CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
tlv.h File Reference
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

Go to the source code of this file.

Classes

struct  tlv_t
 Parsed TLV: pointers alias into the caller-supplied buffer. More...

Enumerations

enum  tlv_status_t {
  TLV_OK = 0 , TLV_ERR_BUF_TOO_SMALL , TLV_ERR_BAD_LENGTH , TLV_ERR_BAD_TAG ,
  TLV_ERR_NULL
}
 BER-TLV codec for OpenPGP Data Objects. More...

Functions

size_t tlv_tag_size (uint16_t tag)
 Compute the encoded size of a tag.
size_t tlv_len_size (size_t value_len)
 Compute the BER definite-length encoded size for a length value.
tlv_status_t tlv_write_tag (uint8_t *buf, size_t buf_max, uint16_t tag, size_t *written)
 Encode a tag. Writes either one or two bytes depending on the magnitude of tag.
tlv_status_t tlv_write_len (uint8_t *buf, size_t buf_max, size_t value_len, size_t *written)
 Encode a BER definite length field.
tlv_status_t tlv_build (uint8_t *buf, size_t buf_max, uint16_t tag, const uint8_t *value, size_t value_len, size_t *written)
 Build a complete TLV: tag, length, and value (which may be NULL when value_len == 0).
tlv_status_t tlv_read_tag (const uint8_t *buf, size_t buf_len, size_t *pos, uint16_t *tag_out)
 Read a tag from the input buffer at pos.
tlv_status_t tlv_read_len (const uint8_t *buf, size_t buf_len, size_t *pos, size_t *length_out)
 Read a BER definite length field starting at pos.
tlv_status_t tlv_parse (const uint8_t *buf, size_t buf_len, size_t *pos, tlv_t *out)
 Parse a single TLV starting at pos. On success pos advances past the entire field and out is filled.

Enumeration Type Documentation

◆ tlv_status_t

BER-TLV codec for OpenPGP Data Objects.

OpenPGP smart cards use the BER-TLV encoding from ISO 7816-4 Annex D for every Data Object exchanged via GET DATA / PUT DATA:

  • Tag: 1 or 2 bytes. A 1-byte tag is restricted to values whose lower five bits are not all set; a 2-byte tag uses bits 1..5 of the first byte = b11111 to indicate continuation. (See ISO 7816-4, Annex D, 5.4.)
  • Length: BER definite length. Values < 128 use a single byte directly; longer values use the 0x8x prefix where x is the number of subsequent big-endian length bytes. OpenPGP spec 3.4.1 uses at most 3-byte forms (0x82 LH LL → up to 64 KiB).
  • Value: Raw bytes, of length given by the length field.

The helpers in this header cover encoding and parsing for the subset used by OpenPGP (1-/2-byte tags, 1-/2-/3-byte length).

Status of a TLV operation.

Enumerator
TLV_OK 
TLV_ERR_BUF_TOO_SMALL 

Output / input buffer exhausted before the field could be read or written.

TLV_ERR_BAD_LENGTH 

Length field uses a form we do not support (e.g. > 3 bytes total).

TLV_ERR_BAD_TAG 

Tag bytes violate ISO 7816-4 continuation rules.

TLV_ERR_NULL 

NULL argument where forbidden.

Definition at line 32 of file tlv.h.

Function Documentation

◆ tlv_build()

tlv_status_t tlv_build ( uint8_t * buf,
size_t buf_max,
uint16_t tag,
const uint8_t * value,
size_t value_len,
size_t * written )

Build a complete TLV: tag, length, and value (which may be NULL when value_len == 0).

Parameters
bufOutput buffer.
buf_maxBuffer capacity.
tagTag value.
valueOptional value bytes.
value_lenValue length.
writtenReceives the total number of bytes written.

Definition at line 54 of file tlv.cpp.

References TLV_ERR_BUF_TOO_SMALL, TLV_ERR_NULL, TLV_OK, tlv_write_len(), and tlv_write_tag().

◆ tlv_len_size()

size_t tlv_len_size ( size_t value_len)

Compute the BER definite-length encoded size for a length value.

Parameters
value_lenValue length.
Returns
Encoded length-field width (1, 2 or 3 bytes).

Definition at line 13 of file tlv.cpp.

Referenced by tlv_write_len().

◆ tlv_parse()

tlv_status_t tlv_parse ( const uint8_t * buf,
size_t buf_len,
size_t * pos,
tlv_t * out )

Parse a single TLV starting at pos. On success pos advances past the entire field and out is filled.

The function rejects truncated values (length field claims more bytes than the buffer holds). It is safe to chain calls in a loop to walk a sequence of TLVs.

Definition at line 122 of file tlv.cpp.

References tlv_t::length, tlv_t::tag, TLV_ERR_BUF_TOO_SMALL, TLV_ERR_NULL, TLV_OK, tlv_read_len(), tlv_read_tag(), tlv_t::total_size, and tlv_t::value.

◆ tlv_read_len()

tlv_status_t tlv_read_len ( const uint8_t * buf,
size_t buf_len,
size_t * pos,
size_t * length_out )

Read a BER definite length field starting at pos.

Accepts the short form (first_byte < 128) and the 0x81 / 0x82 long forms.

Parameters
bufInput buffer.
buf_lenAvailable bytes in the buffer.
posIn/out byte index.
length_outReceives the parsed length value.

Definition at line 98 of file tlv.cpp.

References TLV_ERR_BAD_LENGTH, TLV_ERR_BUF_TOO_SMALL, TLV_ERR_NULL, and TLV_OK.

Referenced by tlv_parse().

◆ tlv_read_tag()

tlv_status_t tlv_read_tag ( const uint8_t * buf,
size_t buf_len,
size_t * pos,
uint16_t * tag_out )

Read a tag from the input buffer at pos.

Advances pos past the tag. Two-byte tags are required to follow the ISO 7816-4 continuation rule (low five bits of the first byte = 0x1F).

Parameters
bufInput buffer.
buf_lenAvailable bytes in the buffer.
posIn/out byte index.
tag_outReceives the parsed tag value.

Definition at line 76 of file tlv.cpp.

References TLV_ERR_BAD_TAG, TLV_ERR_BUF_TOO_SMALL, TLV_ERR_NULL, and TLV_OK.

Referenced by tlv_parse().

◆ tlv_tag_size()

size_t tlv_tag_size ( uint16_t tag)

Compute the encoded size of a tag.

Parameters
tagTag value.
Returns
1 if the tag fits in a single byte, otherwise 2.

Compute the encoded size of a tag.

Definition at line 9 of file tlv.cpp.

Referenced by tlv_write_tag().

◆ tlv_write_len()

tlv_status_t tlv_write_len ( uint8_t * buf,
size_t buf_max,
size_t value_len,
size_t * written )

Encode a BER definite length field.

Supports value lengths 0..65535 (≤ 64 KiB minus 1). Lengths beyond that are rejected with TLV_ERR_BAD_LENGTH because OpenPGP 3.4.1 never asks for more, and ESP32 buffers are far below that.

Parameters
bufOutput buffer.
buf_maxBuffer capacity.
value_lenValue length to encode.
writtenReceives the number of bytes written.

Definition at line 34 of file tlv.cpp.

References TLV_ERR_BAD_LENGTH, TLV_ERR_BUF_TOO_SMALL, TLV_ERR_NULL, tlv_len_size(), and TLV_OK.

Referenced by tlv_build().

◆ tlv_write_tag()

tlv_status_t tlv_write_tag ( uint8_t * buf,
size_t buf_max,
uint16_t tag,
size_t * written )

Encode a tag. Writes either one or two bytes depending on the magnitude of tag.

Parameters
bufOutput buffer.
buf_maxBuffer capacity.
tagTag value.
writtenReceives the number of bytes written.

Definition at line 19 of file tlv.cpp.

References TLV_ERR_BUF_TOO_SMALL, TLV_ERR_NULL, TLV_OK, and tlv_tag_size().

Referenced by tlv_build().