UICC 之 USIM 详解全系列——UICC中的Apps与Files结构

UICC中的Apps与Files结构

一、UICC应用框架

app structure

上面就是UICC的应用结构,在我的一篇博客中介绍过UICC的结构,他其实就是一个微型的操作系统。在文件系统中可以有多个应用,每个应用下面有不同的文件。我们终端与UICC的交互大多是文件的读写(另外还有一些是鉴权,随机数,SUCI 等)。

上面的结构并不是协议强制要求实现的,只是一种建议实现方案。但是协议规定了,所有的Application Identity都要存储在EFDIR (文件的结构在我的这篇博文中有介绍),也就是说如果我们想激活一个Application,应该首先读取EFDIR获取Application Identity。

EFDIR,EFPL,EFICCID,EFUMPC都是必须要存在的文件且必须是Master File的子文件(Master File是根文件),而EFTELECOM是可选的,也就是可以没有这个文件,但是如果运营商实现了这个文件则必须使用保留的FID ‘7F 10’ 。

二、UICC中的文件类型

UICC将文件分为两大类,如下图:
文件类型
下面我们详细的讲解一下这几个文件的区别

Dedicated files

专用文件运行对文件进行功能性分组,专用文件可以是专用文件或者基础文件的父类。一个ADF(Application DF)是一个特殊的DF,它包含了一个Application中所有的DFs和EFs

基础文件

Transparent EF

这样的文件中包含了一连串的Bytes(类似于C语言的数组),我们在读取或者更新这类文件的时候,可以通过指定offset和length来实现针对某几个连续的Bytes数据进行读取或者更新。offset等于0表示从文件头开始,而文件的总长度length可以通过SELECT命令返回。

Linear fixed EF

包含了一连串的records,每个records的长度相同。第一个record的索引是1 。通过SELECT命令可以获取一个record的长度以及整个文件的长度(number records * a record length)
Linear fixed EF
这里有几种方法来访问Linear fixed EF的records:

  • 使用绝对record number(例如上图中的 record number 1 , record number 2 , …)
  • 如果没有设置record pointer且在读取/更新命令中设置了NEXT,则可能读取到第一个记录;如果没有设置record point且在读取/更新命令中设置了PREVIOUS,则可能读取到最后一个记录
  • 如果设置了record pointer,则我们可以就目前选中的record执行下面的操作,选择前一个record(前提是当前选中的record不是第一个record),选择下一个record(前提是当前选中的record不是最后一个record)
  • 通过类似正则表达式的模式搜索(pattern search)

如果选择record的命令失败了,则record pointer将保留之前的状态,也就是下次操作时不是自动重置,将从上次操作的位置继续执行命令

当前一个Linear fixed EF最多包含254个records,每个record最大长度255Bytes

Cyclic EF

Cyclic EF用来==按照时间顺序(chronological order)==存储records,当所有records都被使用之后,下一个需要存储的数据将会覆盖按照时间顺序最oldest的record中的数据。

Cyclic EF包含了固定数量的records且所有record的长度相同且不变,文件的第一个record和最后一个record之间有link(类似C语言的双向循环队列),当record pointer设置为最后一个record时,则Next record就是第一个record,反之当record pointer设置为第一个record时,则Previous record就是最后一个record。
Cyclic EF
这里需要强调 如果时更新操作则只能使用PREVIOUS参数来更新record,如果是读取操作,则可以使用NEXT,PREVIOUS,CURRENT,Record Number
如果选择record的命令失败了,则record pointer将保留之前的状态,也就是下次操作时不是自动重置,将从上次操作的位置继续执行命令
当前一个Linear fixed EF最多包含254个records,每个record最大长度255Bytes

Cyclic EF其实就是Linear fixed EF的一个变体,增加了按照时间数据排序的功能

BER-TLV structure EF

TLV格式文件就是通过tag, length, value来表示多个数据对象。tag表述数据对象的类型,length表示这个数据对象的长度,value表述这个数据对象的值,如下图:
TLV解释
TLV格式的数据我们会经常用到,例如SELECT命令返回的数据就是TLV编码的,大家可以参考我在GitHub上的Demo Code进一步理解TLV这种编码。

三、文件ID

上一段提到FID这个缩写,这里做一下详细讲解。FID(File Identifier)用来寻址或者标识一个特定文件,FID由2 Bytes的十六进制数组成。在同一个父目录下不会有相同的FID,且父目录的FID与父目录的直接孩子的FID也不能相同。

文件的路径就是一连串的FID,路径的起点可以是MF(根文件)或者Current DF,路径的结尾是需要访问的文件FID,路径只能是"from father to child"。

SFI(Short File Identifier)由 5 Bits组成,取值范围1到30,同一个父目录下子文件的SFI不能相同。

DF name由1到16个Bytes组成,独一无二的标识了一个AID(application id)(我们在讲解USIM Application时会用到),并且将’7FFF’保留作为当前已经在给定的逻辑信道(逻辑信道下段中讲解)上激活的Application的FID。

我们将电话卡插入手机后,需要激活USIM应用才能正常上网,而这个USIM应用的ID就是上面提到的DF name,一般都是16个Bytes 用起来比较麻烦(比如按照路径读取文件的时候),所以可以使用’7FFF’来代替16 Bytes的DF name

四、选择文件的几种方法

当UICC激活且ATR之后,默认选中的文件是Master File(MF),每个文件都可以使用SELECT命令选择,下面有三种选择方法(参考我的Demo Code):

通过FID选择文件

下面的文件可以通过FID选择:

  • 当前选择的目录下的任何文件
  • 当前DF的父目录下的任何DF孩子
  • 当前目录的父目录
  • 当前的DF
  • 当前激活Application的ADF
  • Master File

Demo code如下

//当前选择的是USIM App,EF IMSI是它的直接孩子
init_usim(&usim ,send_apdu_usim); //初始UICC并激活USIM
uint8_t imsi[2]={
    
    0x6F,0x07}; //IMSI的FID
//0xA4时SELECT命令,设置P1等于0x00表示select by FID
send_command_usim(&usim,0x00,0xA4,0x00,0x04,0x02,imsi,INVALID_LE,&r_apdu); //使用FID选择IMSI文件

获取Demo code

协议中给出的例子:
在这里插入图片描述
在这里插入图片描述

通过Path选择文件

通过设置SELECT命令的P1的值(命令结构在下一篇博文讲解),可以设定路径的起始位置,例如下图:
在这里插入图片描述
但是这里有几个限制条件:

  • 当P1设置为"select by path from MF"时,路径中不需要再添加MF的FID(‘3F00’)
  • 当P1设置为"select by path from current DF"时,路径中不需要再添加激活的Application的默认FID(‘7FFF’)
  • 当P1设置为"select by path from MF"或者"select by path from current DF"时,不需要再添加当前DF的FID
  • 当P1设置为"select by path from MF"或者"select by path from current DF"时,不能使用空数据字段(也就是说文件路径不能是空)

协议中给出的例子:
在这里插入图片描述
在这里插入图片描述
Demo code如下

init_usim(&usim ,send_apdu_usim);
uint8_t imsi[4]={
    
    0x7F,0xFF,0x6F,0x07};
//0xA4时SELECT命令,设置P1等于0x08表示select by path from MF
send_command_usim(&usim,0x00,0xA4,0x08,0x04,0x04,imsi,INVALID_LE,&r_apdu); //P1设置为0x08,表示MF作为起始路径

获取Demo code

通过SFI选择文件

SFI的存在主要是为了简化文件的读取和更新操作,常规操作应该是首先通过SELECT命令选择文件,然后再进行读取或者更新,但是如果文件有了SFI之后,就不需要先SELECT就可以读取或者更新文件了,下面的命令都支持SFI:
• READ BINARY;
• UPDATE BINARY;
• READ RECORD;
• UPDATE RECORD;
• INCREASE;
• SEARCH RECORD;
• RETRIEVE DATA; or
• SET DATA.

文件是否支持SFI可通过文件的FCP(包含了文件属性且TLV编码)获取。如果FCP中包含了tag等于’88’的TLV DO但是length等于0,表示该文件不支持SFI;如果FCP没有包含tag等于’88’的TLV DO,则表示支持SFI且等于FID的低5Bits

在READ RECORD/UPDATE RECORD/INCREASE/SEARCH RECORD中使用SFI,会立即设置当前的文件为Current EF且重置current record pointer,后续对record的操作命令中不再需要添加SFI。RETRIEVE DATA/SET DATA类似只不过重置的是current tag pointer。

init_usim(&usim ,send_apdu_usim);
//0xB0是READ BINARY,设置P1为0x80 | 0x07
//0x80表示使用SFI , 0x07是IMSI文件的SFI
send_command_usim(&usim,0x00,0xB0,0x87,0x00,INVALID_LC,NULL,INVALID_LE,&r_apdu); 

获取Demo code

五、逻辑信道

逻辑信道有点类似于C语言的多进程,也就是我们可以通过不同的逻辑信道ID实现UICC的并发操作。逻辑信道ID 0总是有效(也就是说UICC至少也是个单道程序操作系统)。

什么是逻辑信道

UICC是否支持逻辑信道可以通过ATR获取,并且还可以在ATR中获得逻辑信道的分配方式以及最大支持的逻辑信道数。不同逻辑信道之间的命令交互都是独立的,就是说同一时间只能有一个逻辑信道激活来完成命令的接收和应答工作。UICC为了实现多个逻辑信道同时工作,设计了一种共享式文件,通过文件描述符"shareable"指明其为共享文件(包含在SELECT命令所返回的FCP中),如下图:
shareable

但是需要注意的是,UICC只是给我们提供了可以多逻辑信道同时操作的机制,UICC不会保证数据在智能卡和终端中的一致性,这需要Application来保证,尤其需要注意 读写并发对cyclic file的影响。

如何开启逻辑信道

我们可以通过MANAGE CHANNEL command打开一个逻辑信道,智能卡会帮我们分配逻辑信道ID并做为命令的应答返回给我们。逻辑信道一旦打开之后,要么明确的调用MANAGE CHANNEL command来关闭,要么将UICC去激活来关闭逻辑信道。

如果我们是从 basic channel(上电后默认激活的逻辑信道) 中打开新的逻辑信道,则新打开的逻辑信道会将MF作为其当前选中的DF(激活后的默认起始路径)。
如果我们不是从basic channel中打开新的逻辑信道,则新打开的逻辑信道选中的DF(激活后的默认起始路径)将与发送激活命令的逻辑信道当前选中的DF一样被选中。如果发送激活命令的逻辑信道当前选中的DF不是共享DF或者ADF,则不会有新的逻辑信道激活,并且返回一个error code通知命令不允许执行。

保留的文件ID

• ADF:

  • Operational use (implicit FID for the current ADF):
    ‘7FFF’

• Dedicated Files:

  • Administrative use:
    ‘7F4X’, ‘5F1X’, ‘5F2X’.

  • Operational use:
    ‘7F10’ (DFTELECOM);
    ‘7F20’ (DFGSM);
    ‘7F21’ (DFDCS1800); and
    ‘7F23’ (DFFP-CTS) are reserved for 3GPP, 3rd Generation Partnership Project;
    ‘7F11’ (DFCD) is reserved for assignment in the present document;
    ‘7F22’ (DFIS-41) is reserved for ANSI, American National Standards Institute, USA;
    ‘7F24’ (DFTIA/EIA-136’) is reserved for TIA, Telecommunications Industry Association, USA;
    ‘7F25’ (DFTIA/EIA-95’) is reserved for 3GPP2, 3rd Generation Partnership Project 2;
    ‘7F26’ (DFGSMA) is reserved for GSMA, GSM Association;
    ‘7F2X’, where X ranges from ‘6’ to ‘F’ are reserved for future assignments.

  • For information:
    ‘7F31’ (DFIDEN) is used in the iDEN specification by Motorola, Inc, USA;
    ‘7F80’ (DFPDC) is used in the PDC specification by ARIB, Association of Radio Industries and
    Businesses, Japan;
    ‘7F90’ (DFTETRA) is used by TETRA Association, Terrestrial Trunked Radio.

• Elementary files:

  • Administrative use:
    ‘6F XX’ in the DFs ‘7F 4X’; ‘4F XX’ in the DFs ‘5F 1X’, ‘5F2X’;
    ‘6F 1X’ in the DFs ‘7F 10’, ‘7F 20’, ‘7F 21’;
    ‘4F 1X’ in all 2nd level DFs;
    ‘2F EX’ in the MF ‘3F 00’; ‘2F07’ EFENV-CLASSES (specified in ETSI TS 102 671 [27]).
  • Operational use:
    ‘6F 2X’, ‘6F 3X’, ‘6F 4X’ in ‘7F 10’ and ‘7F 2X’;
    ‘4F YX’, where Y ranges from ‘2’ to ‘F’ in all 2nd level DFs;
    ‘2F05’, ‘2F06’ and ‘2F 1X’ in the MF ‘3F 00’.
  • Operational use ISO/IEC 7816-4 [12]:
    ‘2F00’ EFDIR, ‘2F01’ EFATR in the MF ‘3F00’.

上述的’ X '没有特殊强调就是0x0到0xF之间的数

当然还有一些文件是由某些组织维护的,这些文件我们不再这里介绍

关于每个文件的FID可以下载UICC和USIM协议自行查询

返回系列目录

猜你喜欢

转载自blog.csdn.net/qq_31985307/article/details/113826360