Message format: BER-TLV
This protocol uses what is called a Basic Encoding Rules Tag Length Value format also known as BER TLV. BER TLV is a particular implementation of the generic TLV. Let’s start with what the TLV format is.
A TLV construction is a byte array that has a tag indicating what the data is (also known as identification), a length specifying its length (in bytes/octets), and the value itself.
- TLV example
08 04 72 26 9A 33
^ ^ ^ ^
| | |---------|
| | value
| ----- length
-------- tag
The BER TLV follows the same format, but it increases the information that can be sent with one single TLV.
Tag
The tag is the identification of the information sent. Each tag is unique and has a unique purpose within the protocol. Each tag can be made up of one, two or three bytes. To know how many bytes are used each byte is divided in subfields that inform the reader about its composition
First byte
This byte is always present and has the following format.
| Tag class | P/C | Tag type | |
|---|---|---|---|
| Bits | 8 7 | 6 | 5 4 3 2 1 |
First byte
The 8 bits are divided into 3 subfield
- Tag class: Formed by the first two bits starting from the left (bit 7th and bit 8th).
| Class | Value | Description |
|---|---|---|
| Universal | 0 (b00) | The type is native to ASN.1 |
| Application | 1 (b01) | The type is only valid for one specific application |
| Context-specific | 2 (b10) | Meaning of this type depends on the context (such as within a sequence, set or choice) |
| Private | 3 (b11) | Defined in private specifications |
First byte subfields
- P/C: Formed by the third bit starting from the left (bit 6th). It encodes whether the tag is primitive or constructed, in other words, if the value has more TLV in it, or it is just the value.
| P/C | Value | Description |
|---|---|---|
| Primitive ( P ) | 0 | The contents octets directly encode the value. |
| Constructed ( C ) | 1 | The contents octets contain 0, 1, or more encodings. |
P/C specifications
- In the specifications of protocol messages, the constructed tags are depicted in the following way:
| Tag Name | Tag |
|---|---|
| Tag | XXXX |
| > Child Tag | XXXX |
| >> GrandChild Tag | XXXX |
| >> GrandChild Tag | XXXX |
Constructed tags
- Tag type: formed by the rest of the bits. It contains the tag identification. All 5 bits are available to be used to identify a tag. But in case those 5 bits are not enough, another byte can be used. For that all 5 bits should be set to 1 (0x1F)
If the tag uses one byte is known as Short Form and if it uses more than one byte it is known as Long Form
Short form tags
- EMV tag Application Identifier
Tag: 0x50
0x50 -> 0 1 0 1 0 0 0 0
Tag class: 0 1 -> Application (The type is only valid for one specific application)
P/C: 0 -> Primitive
Tag type: 1 0 0 0 0 -> Identifier
- EMV Issuer script template 1
Tag 0x71
0x71 -> 0 1 1 1 0 0 0 1
Tag class: 0 1 -> Application (The type is only valid for one specific application)
P/C: 1 -> Constructed
Tag type: 1 0 0 0 1 -> Identifier
Following bytes
The rest of the bytes have the same structure:
| More bytes indicator | Tag type | |
|---|---|---|
| Bits | 8 | 7 6 5 4 3 2 1 |
Following bytes
-
More bytes indicator. The 8th bit will have value 1 if there is at least another byte following this one. Value 0 if not.
-
Tag type: The same as the first byte, this will identify the tag.
Long form tags
- EMV Application cryptogram
Tag: 0x9F26
0x9F -> 1 0 0 1 1 1 1 1
Tag class: 1 0 -> Context-specific (Meaning of this type depends on the context (such as within a sequence, set or choice))
P/C: 0 -> Primitive
Tag type: 1 1 1 1 1 -> Long Form
0x26 -> 0 0 1 0 0 1 1 0
More bytes: 0 -> No more, last byte
Tag type: 0 1 0 0 1 1 0 -> Identifier
- AID Entry
Tag 0x7FE306
0x7F -> 0 1 1 1 1 1 1 1
Tag class: 0 1 -> Application (The type is only valid for one specific application)
P/C: 1 -> Constructed
Tag type: 1 1 1 1 1 -> Long Form
0xE3 -> 1 1 1 0 0 0 1 1
More bytes: 1 -> At least one byte more
Tag type: 1 1 0 0 0 1 1 -> Identifier
0x06 -> 0 0 0 0 0 1 1 0
More bytes: 0 -> No more, last byte
Tag type: 0 0 0 0 1 1 0 -> Identifier
Length
This is the hexadecimal representation of the length of the data contained in a single TLV. The length field normally uses one byte, as with one byte the length that can be represented is 127 bytes. If the length only uses one byte it is called Short Form and if it uses more than one byte it is called Long form.
To determine which form it is, please check the first bit. If its value is 0, it means it is a short form and the following 7 bits are the length of the data. If the value is 1, then the following 7 bits indicate how many bytes are going to be used as length indicator, which will follow immediately after this first byte.
Short form length
- Example: Data length is 10 bytes:
Length: 0x0A
0x0A -> 0 0 0 0 1 0 1 0
Long form: 0 -> Short form, one byte
Length: 0 0 0 1 0 1 0 -> Length 0x0A -> 10
- Example: Data length is 120 bytes:
Length: 0x78
0x78 -> 0 1 1 1 1 0 0 0
Long form: 0 -> Short form, one byte
Length: 1 1 1 1 0 0 0 -> Length 0x78 -> 120
Long form length
- Example: Data length is 200 bytes:
Length: 0x81C8
0x81 -> 1 0 0 0 0 0 0 1
Long form: 1 -> Long form
Length: 0 0 0 0 0 0 1 -> Number of length bytes 1
0xC8 -> 1 1 0 0 1 0 0 0
Length: 1 1 0 0 1 0 0 0 -> Length 0xC8 -> 200
- Example: Data length is 400 bytes:
Length: 0x820190
0x82 -> 1 0 0 0 0 0 1 0
Long form: 1 -> Long form
Length: 0 0 0 0 0 1 0 -> Number of length bytes 2
0x0190 -> 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0
Length: 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 -> Length 0x190 -> 400
Value
This contains the information to be communicated. This field can also be a list of TLVs. Each tag has a unique way of coding the information
Data
- Numeric
Currency Code: 5F2A020978
Tag: 5F2A
Length: 02
Data: 0978 -> 978 EUR
- Text
Amount display string: 5FE321084575726F20353030
Tag: 5FE321
Length: 08
Data: 4575726F20353030 -> ASCII 'Euro 500'
- Boolean
Receipt duplicate: 5FE5020100
Tag: 5FE502
Length: 01
Data: 00 -> false
- Time/Date
EMV Transaction Date 9A03220217
Tag: 9A
Length: 03
Data: 220217 -> 17/02/2022
For more information BER-TLV