Cartões inteligentes. Parte 3. TLV

Olá Giktayms!

Na última parte, vimos como ocorre a comunicação entre o terminal e o cartão. Analisamos os formatos C-APDU e R-APDU, mas não prestamos atenção aos dados que esses APDU contêm. Nesta parte, consideraremos os formatos mais comuns em que as informações são transmitidas entre o terminal e o cartão (e vice-versa). Todos eles pertencem a uma família - TLV.

TLV significa T ag, L ength, V alue e é usado para estruturar informações. Em um nível muito abstrato, os TLVs podem ser vistos como uma versão binária do XML. No entanto, o que é Tag, Comprimento, Valor?

  • Tag : diz que tipo de informação está no TLV. Uma visualização pode ser, por exemplo, uma simples linha ou número, um identificador ou até uma estrutura complexa. Em algumas modalidades, o Tag também contém meta-informações sobre TLV.
  • Length : o comprimento, em bytes, do elemento Value.
  • Valor : dados contidos no TLV

Cada variante TLV possui suas próprias regras de codificação para cada elemento. A seguir, veremos as opções mais comuns de TLV. Quero observar imediatamente que este artigo será dedicado principalmente ao BER-TLV, já que este é o formato mais difundido, flexível e complexo. Outras opções de TLV serão consideradas apenas brevemente.

BER-TLV


Então, estamos falando sobre o personagem principal deste artigo - BER-TLV. Isso faz parte do padrão ASN.1 e é usado não apenas no campo de cartões inteligentes.

Tag

O primeiro byte da tag tem o seguinte formato:
b8b7b6b5b4b3b2b1
ClasseUm tipoTag

Existem as seguintes classes:
b8b7Descrição
0 00 0Genérico - tipos de dados básicos, como dados ou números de cadeias. Raramente usado em cartões inteligentes.
0 01 1Aplicado - tipos cujo significado varia dependendo da aplicação
1 10 0Sensível ao contexto - tipos cujo significado depende de um determinado tipo composto
1 11 1Privado - tipos cujo significado depende de uma organização específica

Como a especificação descreve o valor total da tag, lembrar o valor das classes é completamente supérfluo. A classe não afeta como a tag será processada.

O mais interessante é o bit 6. Quando é 1, esse TLV contém outros TLVs. Se, pelo contrário, seu valor for 0, o TLV conterá dados simples ou dados que não estão estruturados no formato TLV.

Os bits restantes (5-1) geralmente são apenas o número da etiqueta. No entanto, se forem todas as unidades, o número da tag continuará no segundo byte. Se o bit8 do segundo byte for 1, o número continuará no terceiro byte, etc. Na prática, os cartões inteligentes usam apenas tags escritas em um ou dois bytes.

comprimento

O comprimento pode ser definido e indefinido.

Um comprimento indefinido é gravado em um byte com um valor de 0x80. Este método é válido apenas para TLVs compostos (ou seja, TLVs contendo outros TLVs). Nesse caso, o TLV deve necessariamente conter TLV-NULL como o último elemento, que é codificado como "00 00". Um método semelhante é frequentemente usado em padrões mais modernos, mas, em geral, não é muito comum.

Um comprimento específico é gravado em um ou mais bytes.
Comprimento dos dadosCodificação
0x00 <= x <= 0x7Fo valor é gravado inalterado em um byte
0x80 <= x <= 0xFF0x81 e o valor no segundo byte
0x100 <= x <= 0xFFFF0x82 e o valor no segundo e terceiro bytes
0x10000 <= x <= 0xFFFFFF0x83 e valor nos próximos três bytes
0x1000000 <= x <= 0xFFFFFFFF0x84 e valor nos próximos quatro bytes

Em princípio, esta tabela poderia ser continuada. No entanto, TLVs enormes não são encontrados no campo de cartões inteligentes. O comprimento registrado em mais de três bytes (incluindo o prefixo 0x82), eu pessoalmente não vi. Os valores são sempre escritos no formato Big Endian.

Observe que, nos cartões inteligentes, esse método de duração da gravação geralmente é usado mesmo fora do TLV (ou seja, apenas LV), mas, como regra, com a exceção de que o valor 0x80 também pode ser gravado como está, em um byte.

Valor

O valor pode ser uma sequência TLV ou apenas bytes, cujo significado depende do contexto e do aplicativo. Não é aceitável misturar os dois tipos de dados no mesmo TLV. Os TLVs contidos em um TLV composto podem ser de qualquer tipo - composto ou simples. Este elemento está ausente quando o comprimento do TLV é 0.

Exemplos

AID (identificador de aplicativo)
4F 08 A0 00 00 01 51 00 00 00

Tag 0x4F: um TLV de aplicativo simples, neste exemplo contendo 8 bytes (cujo valor é Identificador de aplicativo, ou seja, o identificador de aplicativo).

Estado do ciclo de vida
9F70 01 0F

Tag 0x9F70: um TLV sensível ao contexto simples, neste exemplo contendo 1 byte. Observe que, no primeiro byte da tag (9F), os bits 5-1 são todas unidades, portanto a tag continua no próximo byte.

Carregar bloco de dados do arquivo
C4 82 0x01 0x0c 01 ... outros 266 bytes ... 0a

Tag 0xC4: um TLV privado simples, neste exemplo, contendo 268 bytes. O comprimento é escrito em três bytes, o primeiro dos quais é o prefixo 0x82.

Dados relacionados ao GlobalPlatform Registry
E3 11 4F 08 A0 00 00 01 51 00 00 00 9F70 01 0F C5 01 00

Tag 0xE3: TLV privado composto contendo outros TLVs. Neste exemplo, somente ele contém TLVs simples. Também é permitido que um composto TLV ou uma mistura de composto e simples esteja contida.

Teoricamente, isso também poderia ser escrito como
E3 80 4F 08 A0 00 00 01 51 00 00 00 9F70 01 0F C5 01 00 00 00

usando comprimento indefinido. Na prática, no entanto, o cartão só aceita (ou envia) um comprimento indefinido quando permitido pela especificação.

COMPREENSÃO-TLV


O COMPREHENSION-TLV é descrito na norma ETSI TS 101 220. O comprimento é codificado da mesma maneira que para o BER-TLV. A tag é codificada de acordo com as seguintes tabelas:

Em um byte (0x01 - 0x7E)
b8b7b6b5b4b3b2b1
CRTag

Em três bytes (0x0001 - 0x7FFF)
Byte 1Byte 2Byte 3
b8-b1b8b7b6b5b4b3b2b1b8-b1
0x7FCRTag


O acrônimo CR significa Compreensão necessária. Quando esse bit é 1, o receptor TLV deve retornar um erro se não suportar este TLV. Se, pelo contrário, for 0, o destinatário terá o direito de ignorar o TLV, caso não seja suportado.

A principal aplicação do COMPREHENSION-TLV é a transferência de parâmetros para o SIM-Toolkit (o SIM-Toolkit é usado, entre outras coisas, para o SIM-Menu em telefones). Para aumentar a compatibilidade entre cartões e telefones, parâmetros opcionais (ou seja, aqueles sem os quais você pode pelo menos executar o comando) são enviados com CR = 0.

SIMPLE-TLV


SIMPLE-TLV está descrito na ISO7816-4. Ao contrário do BER-TLV no SIMPLE-TLV, uma tag é simplesmente um número entre 0x01 e 0xFE, que não contém informações sobre a classe e o tipo. O comprimento é escrito da seguinte maneira:
Comprimento dos dadosCodificação
0x00 <= x <= 0xFEo valor é gravado inalterado em um byte
0xFF <= x <= 0xFFFF0xFF e o valor no segundo e terceiro bytes


DGI (identificador de agrupamento de dados)


O DGI é descrito nas Especificações da placa de plataforma global e na Especificação da linguagem de script dos sistemas GP. A tag é sempre codificada em dois bytes e não contém nenhuma informação meta. O comprimento é gravado da mesma maneira que no SIMPLE-TLV. Os DGIs geralmente contêm BER-TLVs, mas podem ser simples.

COMPACT-TLV


O COMPACT-TLV é descrito na ISO7816-4 e é usado exclusivamente no ATR (resposta para redefinir). Nesse formato, a tag e o comprimento são gravados no mesmo byte. A tag está escrita no petisco mais antigo e o comprimento está escrito no menor.

Então, chegamos ao final desta parte. Se alguém tiver dúvidas, escreva-as nos comentários. A próxima parte do artigo será sobre JavaCard e, depois disso, falaremos diretamente sobre a Plataforma Global.

O restante do artigo


Parte 1. Princípios de Operação
Parte 2. APDU

All Articles