基于上海华虹SHC1124芯片的电子护照芯片操作系统(COS)的设计与实现
上海华虹集成电路有限责任公司 倪以金
摘要
本文描述基于上海华虹SHC1124芯片的电子护照芯片操作系统的设计与实现。
1 简介
电子护照是在传统本式护照中嵌入电子芯片,并在芯片中存储持照人个人基本资料的新型本式证件。ICAO组织的188个缔约国,必须在不迟于2010年4月1日之前开始颁发国际民航组织标准的机读护照。预计到2011年,全球签发电子护照的国家和地区将达到100个。
本文主要介绍基于上海华虹SHC1124芯片的电子护照芯片操作系统(Chip Operation System,COS)的设计与实现。
2 上海华虹SHC1124芯片特点[1]
上海华虹SHC1124芯片是面向智能卡操作系统平台化和多应用层面的安全控制芯片,主要针对身份识别、银行支付、电子证照等目标领域。该芯片是一款非接触式应用智能卡芯片,带有满足ISO14443标准的RF接口,CPU采用ARM公司的SC100,该CPU基于32的ARM7架构设计并采用RISC指令。芯片其内置ROM(160K)、RAM(8K)作为程序和数据的存储,并采用EEPROM(72K)作为数据或程序的断电存储。另外,该芯片集成了定时器和看门狗、时钟生成、随机数生成、中断控制器、系统控制、DES\3DES、RSA、CRC、安全控制等模块。
3 电子护照芯片操作系统(COS)
电子护照芯片操作系统COS从本质上而言其实就是基于智能卡芯片(上海华虹SHC1124安全控制芯片)而实现的满足电子护照应用规范的嵌入式软件。编程语言采用C语言与ARM汇编,开发工具为ARM Developer Suite v1.2和SHC1124仿真开发工具,可以通过JTAG方式对SHC1124芯片内的程序进行开发和调试。本节主要介绍电子护照芯片操作系统COS的设计与实现。
3.1电子护照芯片操作系统软件架构
图1 电子护照芯片操作系统COS软件架构图
如上图所示,电子护照操作芯片操作系统COS软件采用分层架构设计,主要分为两层:
1) 硬件驱动层(HardWare Driver,HWD):上海华虹SHC1124芯片提供了经过安全认证的硬件驱动层HWD,其提供了操作硬件IP的API函数,方便用户在上海华虹SHC124芯片上聚焦于目标应用的功能开发,缩短产品开发周期。
2) 电子护照应用层(Chip Operation System,COS):主要完成电子护照个人化指令与过关认证流程指令,其中分为三个模块:
2 14443协议处理模块:根据14443标准实现RF通讯,主要负责完成从读卡机接收数据和发送数据;
2 应用算法模块:主要负责实现电子护照应用中各种基础算法;
2 电子护照指令模块:主要实现COS文件系统,完成实际应用场景中发证与验证使用到各种应用指令的处理。
3.2硬件驱动软件
硬件驱动软件(HWD)是上海华虹SHC1124芯片提供的操作芯片硬件的API函数,其位于芯片硬件和应用程序之间。应用程序通过API函数接口调用硬件驱动层HWD的驱动函数,控制硬件执行操作,完成预定的功能。硬件驱动HWD有其单独的RAM和ROM空间,且处于特权 别,而应用程序及其RAM、ROM均处于用户 别。对硬件的访问通过提供的API函数接口和SC100内核的软中断机制来实现,用户程序不能直接操作硬件。硬件驱动软件(HWD)提供了如下可以直接访问的功能模块:
2 CRC模块:包含对CRC协处理器的所有操作和检查功能;
2 DES模块:包含对DES协处理器的所有操作和检查功能;
2 RSA模块:包含对RSA协处理器的所有操作和检查功能;
2 ECC模块:包含对ECC协处理器的所有操作和检查功能;
2 RNG模块:包含对随机数的所有操作和检查功能;
2 Timer&WatchDog模块:包含对定时器和看门狗的所有操作和检查功能;
2 Clock&Power模块:包含对时钟频率、功耗控制的操作和检查功能;
2 Reset模块:包含对复位控制的操作和检查功能;
2 Security模块:包含对安全控制的操作和检查功能;
2 Privilege模块:包含对权限控制的操作和检查功能;
2 EEPROM模块:包含对EEPROM的所有操作和检查功能;
2 RF模块:包含对RF通讯模块的所有操作和检查功能;
2 Interrupt模块:包含对中断控制的操作和检查功能;
2 Manage模块:包含对硬件驱动层HWD辅助管理的功能。
3.2电子护照应用
电子护照芯片操作系统COS从本质上而言其实就是基于智能卡芯片(上海华虹SHC1124安全控制芯片)而实现的满足电子护照应用规范的嵌入式软件。芯片自上电之后,就会循环执行下述伪代码描述的程序片段:芯片接收读卡机发送来的命令数据,处理相应的命令,发送命令处理后的响应数据给读卡机。
while( 1 )
{
ReciveData();
DoCommand();
SendData();
}
下文具体描述电子护照应用COS的实现。
3.2.1 14443协议处理模块
ICAO9303标准[2]规定,电子护照采用符合ISO/IEC-14443规范的RF通讯协议[3][4]。在实现时,14443协议处理模块将通过函数接口的方式为外部模块提供服务,模块接口参见下表:
表1 协议处理模块提供的接口说明表
接口名称 | 接口函数原型 | 功能说明 |
RfInit | void RfInit( void ) | 完成RF硬件IP初始化配置 |
Reveive | void ReveiveData( unsigned char* pDataBuf, unsigned int len); | 完成接收APDU指令的功能 |
SendData | void SendData( unsigned char* pDataBuf, unsigned int len) | 完成发送APDU指令响应结果 |
无论RF的协议是Type A或者Type B,在具体实现时都可以提供上述接口来为外部服务。
3.2.2应用算法模块
应用算法模块提供了电子护照国际标准ICAO9303以及扩展访问控制EAC欧标准的中规定的算法应用,具体包括:
(1) DES算法:DES/3DES加解密、3DES计算TMAC,符合FIPS PUB 46-3标准[5];
(2) RSA算法:1024位与2048位RSA加解密,DH密钥交换算法, 符合PKCS标准[6][ 7];
(3) ECC算法:ECIES加解密、ECDSA签名与验签、ECDH密钥交换算法,符合ISO 15946标准[8][9];
(4) HASH算法:SHA-1,SHA-224,SHA-256,SHA-384,SHA-512,符合FIPS 180-2[10]与FIPS 180-3标准[11];
(5) 密钥派生算法;
(6) 安全消息算法等。
3.2.2.1 密钥派生算法
电子护照在过关认证过程中,需要启用基本访问控制(Basic Access Control,BAC)以及扩展访问控制(Extend Access Control,EAC)中的芯片认证(Chip Authentication,CA)时,电子护照COS就需要对证件基本访问密钥(Kenc与Kmac)和安全消息会话密钥进行派生,都是通过对一个密钥种子(Kseed)产生的两个主要的3DES密钥进行计算来建立的,具体算法流程参见下图:
图2密钥派生算法流程示意图
图2中Kseed为一个单一的种子密钥;当32位计数器C=0x 00 00 00 01时,对Kseed与C组成的数据进行密钥派生运算的值的前16字节为Kenc;当C=0x 00 00 00 02时,对Kseed与C组成的数据进行HASH的值的前16字节为Kmac。算法实现描述如下:
int KeyDerivaion( unsigned char Kseed[],unsigned char C[], unsigned char Key[] )
{
把Kseed与C拼凑成原文S;
对原文S生成SHA1摘要结果M;
对摘要结果M进行奇偶校验调整运算 APB(参下文),生成结果R;
取R前16字节作为返回结果;
返回成功;
}
奇偶校验调整运算APB,算法实现描述如下:
int APB( unsigned char APBData[],unsigned char uAPBDataLen )
{
For( i=0;i< uAPBDataLen;i++ )
{
计算APBData[i]的二进制位“1”的总数,记为count;
如果count为偶数时,APBData[i]为APBData[i]加一;
}
返回成功;
}
3.2.2.2 安全消息算法
电子护照在过关认证时需要启用安全消息,防止非法监听。电子护照芯片操作系统COS就需要对安全消息进行解包与打包处理:支持把终端发过来的APDU指令解包为明文;支持把处理的APDU结果打包成密文。电子护照芯片操作系统必须全局维护安全消息使用的全局变量:
unsigned char g_Kenc[16]; //基本访问控制BAC会话密钥Kenc
unsigned char g_Kmac[16]; //基本访问控制BAC会话密钥Kmac
unsigned char g_SSC[8]; //基本访问控制BAC中计算MAC的发送序列计数器SSC
在电子护照芯片上电时,会话密钥(g_Kenc与g_Kmac)是从电子护照的机读信息MRZ中派生而来,g_SSC的初值为0x00。
电子护照芯片必须把终端发过来的APDU指令解包为明文,终端把APDU指令打包成密文的过程具体参见如下示意图:
图3 终端把APDU指令打包成密文的过程示意图
根据图3描述的过程,可以反向得出电子护照芯片把终端发过来的APDU指令解包为明文的过程,具体使用伪代码描述如下:
int UnPackSecuritMessage(unsigned char uSecurityMessage[],
unsigned int uSecurityMessageLen,
unsigned char uPlainData[],
unsigned int nPlainDataLen)
{
从安全APDU指令uSecurityMessage中获取tag为0x8e的值,记为CC(密码校验和);
使用会话密钥中的Kmac以及全局g_SSC,调用TMAC算法计算安全APDU指令uSecurityMessage数据域的MAC值,记为macTemp;
If(macTemp不等于CC )
{
返回MAC错误;
}
If(安全APDU指令uSecurityMessage中存在tag为0x87)
{
从安全APDU指令uSecurityMessage中获取tag为0x87的数据encdata;
使用会话密钥中的Kenc调用TDES对encdata进行解密,
并生成明文APDU指令的Lc和APDUData;
}
If(安全APDU指令uSecurityMessage中存在tag为0x97)
{
从安全APDU指令uSecurityMessage中获取tag为0x97的数据Le,
并生成明文APDU指令的Le;
}
全局g_SSC自动加1;
返回成功;
}
电子护照操作系统COS在收到指令后,完成相应的处理,并生成返回结果,在启用基本访问控制时,必须对返回的结果进行加密打包,具体过程参见下图:
图4 电子护照把APDU返回结果打包成密文的过程示意图
根据图4描述的过程,电子护照芯片把返回的结果打包成密文的过程具体使用伪代码描述如下:
int PackSecuritMessage( unsigned char uPlainData[],,
unsigned int nPlainDataLen,,
unsigned char uSecurityMessage[],,
unsigned int uSecurityMessageLen)
{
If(nPlainDataLen < 2 )
{
返回数据错误;
}
If(nPlainDataLen > 2 )
{
从nPlainDataLen中获取数据域TempData;
在TempData后补0x80 00 的操作,并赋值给Pading80;
使用会话加密密钥g_Kenc对Pading80进行加密生成CrptPading80;
在CrptPading80前添加Tag ( 0x87 )生成DO87;
}
从uPlainData中获取状态码SW1SW2;
在SW1SW2前添加0x9902构造为DO99;
合并DO87与DO99两部分数据为TempData;
对TempData补0x8000操作生成Pading80;
使用会话密钥g_Kmac以及g_SSC对Pading80计算MAC值为CC;
在CC前添加Tag 0x8E生成DO8E;
合并DO87,DO99,DO8E,SW1SW2的数据域为uSecurityMessage;
}
3.2.3电子护照指令模块
从应用角度来看,电子护照应用存在两种应用场景:发证机关的个人化,和机场或者海关的过关认证,这就要求在电子护照必须支持这些应用场景下的使用。根据电子护照国际规范ICAO9303的要求,电子护照在实际应用场景下需支持的指令如下表2所示。
表2 电子护照芯片操作系统COS支持的指令列表
指令 INS | 指令功能 | 函数接口 | 应用场景 |
0xE0 | 创建文件 | void SysCreate(void) | 个人化 |
0xA4 | 选择应用文件 | void SysSelect(void) | 个人化与过关认证 |
0XD6 | 更新二进制文件指令 | Void SysUpdateBinaryD6(void) | 个人化 |
0XD7 | 更新二进制文件指令 | Void SysUpdateBinaryD7(void) | 个人化 |
0x44 | 激活应用 | Void SysActive(void) | 个人化 |
0XE2 | 更新记录文件 | Void SysUpdateRecord | 个人化 |
0x84 | 获取随机数 | void SysGetChallenge(void) | 过关认证 |
0x82 | 外部认证 | void SysExternalAuthenticate(void) | 过关认证 |
0x88 | 内部认证 | void InternalAuthenticate(void) | 过关认证 |
0xB0 | 读取二进制文件 | void SysReadBinaryB0(void) | 过关认证 |
0xB1 | 读取二进制文件 | void SysReadBinaryB1(void) | 过关认证 |
0x22 | 欧盟EAC指令 | void EuEacSecurityEnvir (void) | 过关认证 |
0x2A | 欧盟EAC验证证书 | void VerifyCertificate(void) | 过关认证 |
电子护照操作系统COS软件在运行时需要切换应用场景,以满足产品生命周期管理的需求,采用伪代码描述的流程如下:
Void EPassPortEntry(void)
{
获取生命周期状态标识;
IF( 当前生命周期为个人化状态)
{
While(1)
{
调用RF协议处理模块的ReceiveData接口接收APDU指令;
Switch(INS)
{
Case 0xE0: SysCreate(); //创建文件
Case 0xA4: SysSelect ();//选择文件
Case 0XD6: SysUpdateBinaryD6(void); //更新二进制文件
Case 0XD7: SysUpdateBinaryD7(void); //更新二进制文件
Case 0XE2: SysUpdateRecord(void); //更新记录文件
Case 0x44: SysActive(void); //激活应用
Default:
设置当前状态码为错误的INS;
}
调用14443协议处理模块的SendData接口发送APDU处理结果;
}
}
IF( 当前生命周期为启用基本访问控制BAC状态)
{
调用14443协议处理模块的ReceiveData接口接收加密的APDU指令;
调用算法模块中的UnPackSecuritMessage接口把接收到的加密的
APDU指令
解析成明文;
Switch(INS)
{
Case 0xA4: SysSelect ();//选择文件
Case 0XB0: SysReadBinaryB0 (void); //读二进制文件
Case 0XB1: SysReadBinaryB1 (void); //读大数据量二进制文件
Case 0X84: SysGetChallenge (void); //获取随机数
Case 0x82: SysExternalAuthenticate (void);
Case 0x88: InternalAuthenticate (void);
Case 0x22: EuEacSecurityEnvir (void);
Case 0x2A: VerifyCertificate(void);
Default:
设置当前状态码为错误的INS;
}
调用算法模块中的PackSecuritMessage接口把APDU处理结果加密;
调用14443协议处理模块的SendData接口发送加密的APDU处理结果;
}
}
3.2.3.1 文件系统
电子护照芯片操作系统COS文件系统的设计,遵守ISO/IEC-7816标准[12]所定义文件标准,可以支持专用文件(DF)和基本文件(EF)两种文件。卡内文件的逻辑组织结构如图5所示,在根处的DF 称为主文件(MF),是必备的。电子护照应用对应一 DF目录;在DF目录下,有对应的密钥文件、工作文件和私有文件。当读卡机选择了电子护照DF目录时,则表示进入了该电子护照应用环境。
图 5 电子护照文件结构
每个文件(包括DF和EF)都由文件头和文件体组成。文件头中包含文件的标识、大小、访问权限和其它基本信息。所有EF文件头中也包含属性字段,包括读权限和写权限。在DF文件头中还包含一个生命周期字段,可以通过激活应用指令进行修改,使用该字段来决定是否开启安全消息机制。当DF中的生命周期字段为个人化阶段标识时,卡片内不启用安全消息;当DF中的生命周期字段为应用阶段标识时,卡片内启用安全消息。
3.2.3.1 个人化
发证机关在发行证照时,需要对电子护照进行的操作可能包括:
(1) 在数据区域创建相应的文件结构;
(2) 录入证件持有人的信息并写入到电子护照中;
(3) 根据各个持有国家的要求,选择启用安全认证机制(基本访问控制BAC,或主动鉴别AA,或被动鉴别PA,或扩展访问控制EAC)
电子护照的个人化遵循ISO7816标准,可以根据电子护照应用规范ICAO9303和实际应用需求,建立对应上述图5的文件结构,并根据下表的定义进行内容个人化和应用初始化。
文件名 | 文件标识符 | SFI | Tag | 文件作用 |
EF.COM | 01 1E | 1E | 60 | 用于存放文件(EF.DG1到EF.DG16)的文件Tag,个人化时会根据实际个人化的文件填充对应的文件Tag |
EF.DG1 | 01 01 | 01 | 61 | 用于存放详细资料记录信息即MRZ,具体信息包括:证件类型、证件号码、颁发机构、过期日期、姓名、生日、国籍、性别 |
EF.DG2 | 01 02 | 02 | 75 | 用于存放面部识别特征即面部图像 |
EF.DG3 | 01 03 | 03 | 63 | 用于存指纹识别编码 |
EF.DG4 | 01 04 | 04 | 76 | 用于存放眼睛的虹膜识别编码 |
EF.DG5 | 01 05 | 05 | 65 | 保留 |
EF.DG6 | 01 06 | 06 | 66 | 保留 |
EF.DG7 | 01 07 | 07 | 67 | 用于存放签名或常用标记显示 |
EF.DG8 | 01 08 | 08 | 68 | 保留 |
EF.DG9 | 01 09 | 09 | 69 | 保留 |
EF.DG10 | 01 0A | 0A | 6A | 保留 |
EF.DG11 | 01 0B | 0B | 6B | 用于存放附加个人详细资料信息 |
EF.DG12 | 01 0C | 0C | 6C | 保留 |
EF.DG13 | 01 0D | 0D | 6D | 保留 |
EF.DG14 | 01 0E | 0E | 6E | 用于扩展访问控制 EAC |
EF.DG15 | 01 0F | 0F | 6F | 用于主动鉴别认证AA |
EF.DG16 | 01 10 | 10 | 70 | 保留 |
EF.SOD | 01 1D | 1D | 77 | 用于被动鉴别PA |
EF.CVCA | 01 1C | 1C | N/A | 用于扩展访问控制EAC |
3.2.3.2 过关认证
电子护照在机场或者海关过关时,终端通过发送指令流来申请电子护照访问权限和读取电子护照中存放的个人信息,如下描述了一个典型应用场景下终端发送给电子护照的指令流程:
(1) 发送选择应用文件指令,选择MF;
(2) 发送选择应用文件指令,选择DF;
(3) 通过B0指令读取EF.DGCOM;
(4) 发送取获取随机数指令,获取随机数用于后续的基本访问控制BAC认证;
(5) 发送外部认证指令进行基本访问控制BAC认证;
(6) 发送内部认证指令进行主动鉴别AA认证;
(7) 发送扩展访问控制EAC中的SetKAT指令,进行芯片认证(Chip Authentication,CA);
(8) 发送扩展访问控制EAC中的组合指令(SetDST指令,Verfiy Certificate指令、SetAt指令、获取随机数指令、外部认证指令),进行终端认证(Terminal Authentication,TA);
(9) 通过B0指令获取电子护照中的持有人信息;
下文将结合ICAO9303以及欧盟EAC标准规范,对各个应用指令的实现做一下简单描述。
3.2.3.2.1选择应用文件
电子护照在过关认证过程中,需要先选择MF,再选择DF,再选择指定的应用文件,因此电子护照COS系统必须支持选择应用文件的指令。
1 指令描述
代码 | 值 | 描述 |
CLA | 0x0C | 0C为安全报文保护模式 |
INS | 0xA4 | - |
P1 | 00 | 通过FID选择MF、DF、EF |
02 | 选择当前DF下的EF |
04 | 按文件名方式选择 |
P2 | 00 | 第1个或仅有1个 |
0x0C | 当Le不存在时不返回7816定义模板,或返回用户自定义模板 |
Lc | XX | P1=00时,Lc=00或02 P1=04时,Lc=01~10 P1=02时,Lc=02 |
Data | XX | 文件标识符或文件名 |
Le | - | - |
参数定义:P1P2=0000时,如果数据字段为空或等于3F00,则选择MF。
2 指令伪代码实现
vid SysSelect(void )
{
获取指令中的文件标识符或文件名;
根据文件标识符或文件名,从EEPROM中查找对应的文件;
IF( 文件没有查找到 )
{
返回 文件不存在错误码;
}
设置查找到的文件为当前文件;
返回状态码0x9000;
}
3.2.3.2.2读二进制文件B0
1 指令描述
代码 | 值 | 描述 |
CLA | 00/0x0C | 0x0C表示采用安全报文的模式 |
INS | 0xB0 | - |
P1 | XX | 见参数定义 |
P2 | XX | 见参数定义 |
Lc | - | 不存在 |
Data | XX | 不存在 |
Le | XX | 要读取的数据长度 |
参数定义:
当P1的高3位为“100”,则低5位为短文件标识符(SFI),P2为读的偏移量。
P1 | P2 |
B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
1 | 0 | 0 | 短文件标识符 | 文件的偏移量 |
| | | | | | | | | | | | | | | |
当P1的 位不为1时,则P1、P2为欲读文件的偏移量,所读文件为当前文件。
P1 | P2 |
B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
0 | 文件的偏移量 |
| | | | | | | | | | | | | | | |
当Le等于00时,只要文件的 长度在256字节之内,则其全部字节将被读出。
2 指令伪代码实现
void SysReadBinaryB0(void)
{
If( ( P1 & 0XE0 ) == 0x80 )
{
根据APDU指令中的文件SFI从EEPROM中查找对应的文件;
If( 对应的SFI文件不存在)
{
返回文件不存在错误码;
}
设置对应的SFI文件为当前文件;
获取APDU指令中P1P2对应的文件偏移量;
}
Else
{
If( 电子护照中当前文件不是二进制文件)
{
返回条件不满足错码;
}
获取APDU指令中P1P2对应的文件偏移量;
}
If( 当前文件的权限字段不满足当前电子护照权限状态)
{
返回条件不满足错码;
}
If( 期望读取的长度超过文件的实际长度)
{
返回Le错误码;
}
调用硬件驱动HWD中的读EEPROM接口,从EEPROM中读取对应的文件内容,并添加上回0x9000状态码作为返回结果;
}
3.2.3.2.3读大数据量二进制文件B1
1 指令描述
代码 | 值 | 描述 |
CLA | 00/0x0C | 0x0C表示采用安全报文模式 |
INS | 0xB1 | - |
P1 | 00 | - |
P2 | 00 | - |
Lc | XX | 数据域长度 |
Data | XX | TLV格式的数据对像:
|
Le | XX | 要读取的数据长度 |
参数定义:
Le取值数据视实际情况调整.
指令说明:
这条命令主要是用于处理二进制文件大小超过32K的情况。
2 指令伪代码实现
void SysReadBinaryB1(void)
{
If( ( P1 & 0XE0 ) == 0x80 )
{
根据APDU指令中的文件SFI从EEPROM中查找对应的文件;
If( 对应的SFI文件不存在)
{
返回文件不存在错误码;
}
设置对应的SFI文件为当前文件;
获取APDU指令中TLV数据区域对应的文件偏移量;
}
Else
{
If( 电子护照中当前文件不是二进制文件)
{
返回条件不满足错码;
}
获取APDU指令中TLV数据区域对应的文件偏移量;
}
If( 当前文件的权限字段不满足当前电子护照权限状态)
{
返回条件不满足错码;
}
If( 期望读取的长度超过文件的实际长度)
{
返回LE错误码;
}
调用硬件驱动HWD中的读EEPROM接口从EEPROM中对应的文件读取内容并添加上回0x9000状态码作为返回结果;
}
3.2.3.2.4随机数生成
电子护照在执行基本访问控制BAC、主动鉴别AA时都需要随机数的支持,因此电子护照COS必须支持随机数生成指令。
1 指令描述
代码 | 值 | 描述 |
CLA | 00x0C | 0x0C表示采用安全报文方式 |
INS | 0x84 | - |
P1 | 00 | - |
P2 | 00 | - |
Lc | - | 不存在 |
Data | - | 不存在 |
Le | 08 | 要求卡片返回的随机数长度 |
2 指令伪代码实现
void SysGetChallenge(void)
{
IF( 指令中的LE不为0x08 )
{
返回LE错误;
}
调用硬件HWD中的RNG接口生成8字节随机数R;
保存随机数R到全局RNDicc中;
把随机数R添加状态码0x9000作为命令的返回结果;
}
3.2.3.2.5基本访问控制BAC
1 指令描述
代码 | 值 | 描述 |
CLA | 0x0C | 0C为安全报文保护模式 |
INS | 0x82 | - |
P1 | 00 | - |
P2 | 00 | - |
00 | - |
Lc | XX | 数据长度 |
Data | XX | 数据域 |
Le | XX | 取值: 1、 无 2、 0x00 3、 0x28 |
该指令主要是实现基本访问控制BAC认证。
2 指令伪代码实现
void SysExternalAuthenticate(void)
{
IF( 电子护照状态为需要执行基本访问BAC状态)
{
设置全局g_SSC为0;
从APDU指令中获取终端传递来的电子护照产生的随机数RNDiccex;
从APDU指令中获取终端传递来的终端产生的16字节随机数Kifd;
从APDU指令中获取终端传递过来的终端产生的8字节随机数RNDifd;
IF(RNDiccex不等于全局变量中RNDicc的值)
{
返回不满足条件错误码;
}
调用硬件驱动HWD中产生随机数接口生成16字节随机数Kicc;
让Kifd与Kicc进行异或运算生成Kseed;
调用基本访问控制BAC会话密钥派生算法生成Kenc与Kmac;
//各自取RNDicc和RNDifd的低4个字节,并合并成8个字节,生成g_SSC
g_SSC = RNDifd(lower 4) | RNDicc(lower 4)
组成基本访问控制BAC指令返回数据R: R = RNDicc | RNDifd | Kicc;
把R加上状态码0x9000作为指令返回结果;
}
}
3.2.3.2.6主动鉴别AA
1 指令描述
代码 | 值 | 描述 |
CLA | 0x0C | 0x0C表示采用安全报文的模式 |
INS | 0x88 | - |
P1 | 00 | - |
P2 | 00 | - |
Lc | 08 | - |
Data | RNG_IFD | 读卡机发来的8字节长度随机数 |
Le | 00 | - |
该指令主要是实用主动鉴别AA认证。
2 指令伪代码实现
Void InternalAuthenticate(void)
{
从APDU指令中获取终端的随机数RNDifd;
调用HWD中生成随机数接口生成106字节的随机数M1;
把M1与RNDifd拼凑成M=M1 | RNDifd
调用算法模块中的SHA1算法对M进行运算,生成摘要SHA1Result;
拼凑签名数据SignatureData = 0x6A |M1 | SHA1Result | 0xBC;
从EEPROM中的安全区域读取EF.DG15对应的RSA私钥;
使用私钥对SignatureData进行签名,生成签名结果SignatureResult;
把签名结果SignatureResult加上状态码0x9000作为指令返回结果;
}
3.3.3.2.7芯片认证CA的Set KAT
1 指令描述
代码 | 值 | 描述 |
CLA | 0C | - |
INS | 22 | - |
P1P2 | 0x41A6 | - |
Lc | xx | - |
Data | TLV | 公钥参数(ISO 8859-1)[13] |
Le | - | - |
在芯片认证CA中,使用该指令来交换共享密钥,电子护照芯片重新启用新的安全会话密钥(Kenc和Kmac)。
2 指令伪代码实现
void EuEacSecurityEnvir( void )
{
If( APDU指令中的P1P2的值为0x41A6)
{
从APDU指令中获取出终端发送过来的公钥;
从EEPROM中的安全区域获取EF.DG14对应的公私钥;
从EF.DG14中查找密钥交换算法标识;
IF( 密钥交换算法标识为DH算法标识)
{
使用DH算法计算出共享密钥Kseed;
}
Else if(密钥交换算法标识为ECDH算法标识)
{
使用ECDH算法计算出共享密钥Kseed;
}
Else
{
返回EEPROM数据错误错误码;
}
调用基本访问控制BAC会话密钥派生算法生成Kenc与Kmac;
设置全局g_SSC为0x00;
从EEPROM中安全区域把CVCA证书读取并放入全局内存中;
返回状态码0x9000;
}
}
3.3.3.2.8终端认证TA 的Set DST
代码 | 值 | 描述 |
CLA | 0C | - |
INS | 22 | - |
P1P2 | 81B6 | - |
Lc | XX | - |
Data | TLV 0x83 | 公钥持有者名称 (ISO 8859-1) |
Le | - | - |
在终端认证TA中,验证证书链时,需要使用该指令来设置后续证书的证书持有者名称,便于电子护照COS使用正确的证书持有者的公钥对证书进行验证。
2 指令伪代码实现
void EuEacSecurityEnvir( void )
{
If( APDU指令中的P1P2的值为0x81B6)
{
IF( 电子护照芯片当前状态为芯片认证未通过 )
{
返回不满足条件错误码;
}
从存放在电子护照芯片全局内存中的父证书,获取证书持有者名称HolderName;
IF( APDU指令中获取的持有者名称不等于HolderName)
{
返回不满足条件错误码;
}
设置电子护照芯片当前状态为 已设置了证书持有名称状态;
返回状态码0x9000;
}
}
3.3.3.2.9终端认证TA 的Verify Certificate
1 指令描述
代码 | 值 | 描述 |
CLA | 0C | - |
INS | 2A | - |
P1P2 | 00BE | - |
Lc | XX | - |
Data | T | 7F4E |
L | |
V | 证书体 |
T | 5F37 |
L | |
V | 证书的签名 |
Le | - | - |
在终端认证TA中,验证证书链时,需要使用该指令来设置启用验证证书链。
2 指令伪代码实现
void VerifyCertificate(void)
{
IF( APDU指令数据域不合法)
{
返回APDU指令数据域不合法错误码;
}
IF( 电子护照芯片中全局中存放的父证书的角色为CVCA)
{
If(APDU指令数据域中的证书的角色为IS或CVCA)
{
返回不满足条件错误码;
}
}
IF(存放在电子护照芯片全局内存中的父证书,对应的角色为DV)
{
If(APDU指令数据域中的证书的角色为CVCA)
{
返回不满足条件错误码;
}
}
使用存放在电子护照芯片全局内存中的父证书的公钥对APDU指令数据域中的证书进行验签;
If( 验证失败)
{
返回不满足条件错误码;
}
返回0x9000状态码
}
1 指令描述
代码 | 值 | 描述 |
CLA | 0C | - |
INS | 22 | - |
P1P2 | 81A4 | - |
Lc | 83 | - |
Data | - | 公钥参数(ISO 8859-1) |
Le | - | - |
在终端认证TA中,证书链验证成功后,需要使用该指令来设置启用终端证书作为后续外部认证的证书。
2 指令伪代码实现
void EuEacSecurityEnvir( void )
{
If( APDU指令中的P1P2的值为0x41A6)
{
从存放在电子护照芯片全局内存中的父证书获取证书持有者名称HolderName;
IF( APDU指令中获取持有者名称不等于HolderName)
{
返回不满足条件错误码;
}
设置电子护照芯片当前状态为 验证检查终端状态;
返回状态码0x9000;
}
}
3.3.3.2.11终端认证TA 的外部认证
1 指令描述
代码 | 值 | 描述 |
CLA | 0x0C | 0C为安全报文保护模式 |
INS | 0x82 | - |
P1 | 00 | - |
P2 | 00 | - |
00 | - |
Lc | XX | 数据长度 |
Data | XX | 数据域 |
Le | XX | 无 |
在终端认证TA中,需要结合获取随机数指令使用,终端先使用获取随机数指令从芯片中获取8字节随机数,终端随后使用RSA或ECDSA签名算法对随机数进行签名,终端再使用该条指令把签名的值发送给电子护照芯片进行验证。
2 指令伪代码实现
void SysExternalAuthenticate(void)
{
If(电子护照芯片当前状态为 验证检查终端状态)
{
从存放在电子护照芯片全局内存中的父证书中获取公钥PubKey;
使用公钥PubKey解密APDU指令中的终端的签名数据,并获取RNDiccex;
If(RNDiccex与内存中存放的随机数RNDicc不等)
{
返回不满足条件错码;
}
从存放在电子护照芯片全局内存中的父证书中获取读取EF.DG3、EF.DG4的授权权限,并设置电子护照芯片中当前权限状态信息;
返回状态码0x9000;
}
}
4 小结
本文根据电子护照ICAO9303国际标准以及欧盟扩展访问控制EAC标准,描述了基于上海华虹SHC1124芯片的电子护照芯片操作系统COS的设计,介绍了电子护照应用涉及的通讯处理、基础算法、文件系统、认证流程等方面的实现。通过流片试制的电子护照应用样本,采用Golden Reader Tool进行验证的结果表明(如下图所示),上述设计完全满足国际标准要求。
参考书目
[1] 安全控制芯片SHC1124综述,林秋,《卡技术与安全》2010年4月刊
[2] ICAO Doc 9303. Specifications for electronically enabled passports with biometric identification capabilities. In Machine Readable Travel Documents – Part 1: Machine Readable Passport, volume2. ICAO, 6th edition, 2006.
[3] ISO/IEC 14443-3, Identification cards – Contactless integrated circuit(s) cards – Proximity cards – Part3: Initialization and anticollision.
[4] ISO/IEC 14443-4, Identification cards – Contactless integrated circuit(s) cards – Proximity cards – Part4:Transmission protocol.
[5] FIPS PUB 46-3, DATA ENCRYPTION STANDARD (DES) ,OCT 1999.
[6] RSA Laboratories. PKCS#1 v2.1: RSA cryptography standard. RSA Laboratories Technical Note, 2002.
[7] RSA Laboratories. PKCS#3: Diffie-Hellman key-agreement standard. RSA Laboratories Technical Note, 1993.
[8] ISO 15946-1. Information technology – Security techniques – Cryptographic techniques based on elliptic curves – Part 1 to Part 8: General, 2002.
[9] BSI. Technical Guideline: Elliptic Curve Cryptography (ECC) based on ISO 15946, Version 1.0. TR-03111, 2007. certificate and certificate revocation list (CRL) profile. RFC 3280, 2002.
[10] NIST. Secure hash standard. FIPS PUB 180-2 (+ Change Notice to include SHA-224), 2002.
[11] NIST. Secure hash standard. FIPS PUB 180-3 , Oct 2008
[12] ISO/IEC 7816-4,Identification cards – Integrated circuit cards – Part4: Organization,security commands for interchange., 2005.
[13] ISO/IEC 8859 , 8-bit single-byte coded graphic character sets.
[14] 基于ICAO9303标准的电子护照,倪以金