Smart cards. Part 3. TLV

    Hi Giktayms!

    In the last part, we saw how communication occurs between the terminal and the card. We looked at the C-APDU and R-APDU formats, but we did not pay attention to what data these APDUs contain. In this part, we will consider the most common formats in which information is transmitted between the terminal and the card (and vice versa). All of them belong to one family - TLV.

    TLV stands for T ag, L ength, V alue and is used to structure information. At a very abstract level, TLVs can be thought of as a binary version of XML. However, what is Tag, Length, Value?

    • Tag : it says what kind of information is in the TLV. A view can be, for example, a simple line or number, an identifier, or even a complex structure. In some embodiments, Tag also contains meta-information about TLV.
    • Length : the length, in bytes, of the Value element.
    • Value : data contained in TLV

    Each TLV variant has its own encoding rules for each element. Next, we will look at the most common TLV options. I want to immediately note that this article will mainly be devoted to BER-TLV, since this is the most widespread, flexible and complex format. Other TLV options will be considered only briefly.

    BER-TLV


    So, we are talking about the main character of this article - BER-TLV. This is part of the ASN.1 standard and is used not only in the field of smart cards.

    Tag

    The first byte of the tag has the following format:
    b8b7b6b5b4b3b2b1
    ClassType ofTag

    The following classes exist:
    b8b7Description
    00Generic - Basic data types, such as string data or numbers. Rarely used in smart cards.
    0oneApplied - types whose meaning varies depending on the application
    one0Context-sensitive - types whose meaning depends on a given composite type
    oneone Private - types whose meaning depends on a specific organization

    Since the specification describes the full value of the tag, remembering the value of classes is completely superfluous. The class does not affect how the tag will be processed.

    The most interesting is bit 6. When it is 1, then this TLV contains other TLVs. If, on the contrary, its value is 0, then the TLV contains simple data or data that is not structured in TLV format.

    The remaining bits (5-1) are usually just the tag number. However, if they are all units, then the tag number continues on the second byte. If bit8 of the second byte is 1, then the number continues on the third byte, etc. In practice, smart cards only use tags written on one or two bytes.

    Length

    Length can be definite and indefinite.

    An indefinite length is written on one byte with a value of 0x80. This method is only valid for composite TLVs (i.e. TLVs containing other TLVs). In this case, the TLV must necessarily contain TLV-NULL as the last element, which is encoded as "00 00". A similar method is often used in more modern standards, but, in general, it is not very common.

    A specific length is written on one or more bytes.
    Data lengthCoding
    0x00 <= x <= 0x7Fthe value is written unchanged on one byte
    0x80 <= x <= 0xFF0x81 and the value on the second byte
    0x100 <= x <= 0xFFFF0x82 and the value on the second and third bytes
    0x10000 <= x <= 0xFFFFFF0x83 and value on the next three bytes
    0x1000000 <= x <= 0xFFFFFFFF0x84 and value on the next four bytes

    In principle, this table could be continued further. However, huge TLVs are not found in the field of smart cards. The length recorded on more than three bytes (including the prefix 0x82), I personally have not seen. Values ​​are always written in Big Endian format.

    Please note that in smart cards this method of recording length is often used even outside of TLV (i.e. only LV), but, as a rule, with the exception that the value 0x80 can also be written as is, on one byte.

    Value

    Value can be either a TLV sequence or just bytes, the meaning of which depends on the context and the application. It is not acceptable to mix both types of data in the same TLV. TLVs contained in a compound TLV can be of any kind - compound or simple. This element is missing when the length of the TLV is 0.

    Examples

    AID (Application Identifier)
    4F 08 A0 00 00 01 51 00 00 00

    Tag 0x4F: a simple application TLV, in this example containing 8 bytes (the value of which is Application Identifier, i.e. the application identifier).

    Life cycle state
    9F70 01 0F

    Tag 0x9F70: a simple context-sensitive TLV, in this example containing 1 byte. Note that in the first byte of the tag (9F), bits 5-1 are all units, so the tag continues on the next byte.

    Load file data block
    C4 82 0x01 0x0c 01 ... another 266 bytes ... 0a

    Tag 0xC4: A simple private TLV, in this example, containing 268 bytes. The length is written in three bytes, the first of which is the prefix 0x82.

    GlobalPlatform Registry related data
    E3 11 4F 08 A0 00 00 01 51 00 00 00 9F70 01 0F C5 01 00

    Tag 0xE3: composite private TLV containing other TLVs. In this example, only it contains simple TLVs. It is also permissible that a compound TLV or a mixture of compound and simple are contained.

    Theoretically, this could also be written as
    E3 80 4F 08 A0 00 00 01 51 00 00 00 9F70 01 0F C5 01 00 00 00

    using indefinite length. In practice, however, the card only accepts (or sends) an indefinite length when permitted by the specification.

    COMPREHENSION-TLV


    COMPREHENSION-TLV is described in the ETSI TS 101 220 standard. The length is encoded in the same way as for the BER-TLV. The tag is encoded according to the following tables:

    On one byte (0x01 - 0x7E)
    b8b7b6b5b4b3b2b1
    CRTag

    On three bytes (0x0001 - 0x7FFF)
    Byte 1Byte 2Byte 3
    b8-b1b8b7b6b5b4b3b2b1b8-b1
    0x7FCRTag


    The acronym CR stands for Comprehension Required. When this bit is 1, then the TLV receiver should return an error if it does not support this TLV. If, on the contrary, it is 0, then the recipient has the right to ignore the TLV if it is not supported.

    The main application of COMPREHENSION-TLV is the transfer of parameters to the SIM-Toolkit (the SIM-Toolkit is used, among other things, for the SIM-Menu in phones). To increase compatibility between cards and phones, optional parameters (i.e., those parameters without which you can at least somehow execute the command) are sent with CR = 0.

    SIMPLE-TLV


    SIMPLE-TLV is described in ISO7816-4. Unlike the BER-TLV in SIMPLE-TLV, a tag is simply a number between 0x01 and 0xFE, which does not contain information about the class and type. The length is written as follows:
    Data lengthCoding
    0x00 <= x <= 0xFEthe value is written unchanged on one byte
    0xFF <= x <= 0xFFFF0xFF and the value on the second and third bytes


    DGI (Data Grouping Identifier)


    DGI is described in the Global Platform Card Specifications and GP Systems Scripting Language Specification. The tag is always encoded on two bytes and does not contain any meta information. The length is recorded in the same way as for SIMPLE-TLV. DGIs often contain BER-TLVs, but can be simple.

    COMPACT-TLV


    COMPACT-TLV is described in ISO7816-4 and is used exclusively in ATR (Answer to Reset). In this format, the tag and length are written in the same byte. The tag is written in the older nibble, and the length is written in the minor.

    So we have come to the end of this part. If anyone has questions, you can write them in the comments. The next part of the article will be about JavaCard, and after that we will talk directly about the Global Platform.

    The rest of the article


    Part 1. Principles of Operation
    Part 2. APDU

    Also popular now: