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

Go to the source code of this file.

Classes

struct  t1_block_t
 Decoded block. INF points into the buffer supplied to t1_block_decode. More...

Macros

#define T1_INF_MAX   254
 ISO 7816-3 T=1 block-format encoder / decoder.
#define T1_DEFAULT_IFSC   32
 Default IFSC at protocol start (ISO 7816-3, before negotiation).
#define T1_LEN_RESERVED   0xFF
 Reserved LEN value; must not appear on the wire.

Enumerations

enum  t1_block_kind_t { T1_BLOCK_I , T1_BLOCK_R , T1_BLOCK_S }
 T=1 block taxonomy. More...
enum  t1_r_error_t { T1_R_OK = 0x00 , T1_R_EDC_ERR = 0x01 , T1_R_OTHER_ERR = 0x02 }
 R-block error indicator (PCB bits 1-0). More...
enum  t1_s_subtype_t {
  T1_S_RESYNCH_REQ = 0x00 , T1_S_IFS_REQ = 0x01 , T1_S_ABORT_REQ = 0x02 , T1_S_WTX_REQ = 0x03 ,
  T1_S_RESYNCH_RESP = 0x20 , T1_S_IFS_RESP = 0x21 , T1_S_ABORT_RESP = 0x22 , T1_S_WTX_RESP = 0x23
}
 S-block subtype (PCB bits 5-0). More...
enum  t1_status_t {
  T1_OK = 0 , T1_ERR_SHORT , T1_ERR_LEN , T1_ERR_INF_TOO_BIG ,
  T1_ERR_EDC , T1_ERR_PCB , T1_ERR_OUT_BUF , T1_ERR_NULL
}
 Result of t1_block_decode / t1_block_encode. More...

Functions

uint8_t t1_lrc (const uint8_t *buf, size_t len)
 Compute the longitudinal redundancy check (LRC) of a buffer.
uint16_t t1_crc (const uint8_t *buf, size_t len)
 Compute the ISO/IEC 13239 CRC-16 of a buffer (polynomial 0x1021, initial value 0xFFFF, no final XOR, MSB first). Used as the alternative EDC when CRC is negotiated.
t1_status_t t1_block_encode_i (uint8_t nad, uint8_t ns, bool more, const uint8_t *inf, uint8_t inf_len, bool use_crc, uint8_t *out, size_t out_cap, size_t *out_len)
 Encode an I-block.
t1_status_t t1_block_encode_r (uint8_t nad, uint8_t nr, t1_r_error_t err, bool use_crc, uint8_t *out, size_t out_cap, size_t *out_len)
 Encode an R-block.
t1_status_t t1_block_encode_s (uint8_t nad, t1_s_subtype_t subtype, const uint8_t *inf, uint8_t inf_len, bool use_crc, uint8_t *out, size_t out_cap, size_t *out_len)
 Encode an S-block.
t1_status_t t1_block_decode (const uint8_t *buf, size_t buf_len, bool use_crc, t1_block_t *out)
 Decode a T=1 block.

Macro Definition Documentation

◆ T1_DEFAULT_IFSC

#define T1_DEFAULT_IFSC   32

Default IFSC at protocol start (ISO 7816-3, before negotiation).

Definition at line 37 of file t1_block.h.

Referenced by t1_state_init(), and t1_state_next_outbound().

◆ T1_INF_MAX

#define T1_INF_MAX   254

ISO 7816-3 T=1 block-format encoder / decoder.

A T=1 block has the shape:

+--—+--—+--—+-------------—+--—+ | NAD | PCB | LEN | INF (0..254 B) | EDC | +--—+--—+--—+-------------—+--—+ 1B 1B 1B LEN bytes 1B (LRC) or 2B (CRC)

  • NAD: source/destination address (0x00 in the OpenPGP smartcard role).
  • PCB: protocol control byte; encodes block type, sequence numbers, and more-data flag.
  • LEN: information field length (0..254). 0xFF is reserved.
  • INF: payload bytes.
  • EDC: error-detection code. LRC = XOR of NAD..INF; CRC = CRC-16 over the same bytes (selected via T=1 protocol parameters in ATR).

This header exposes only the syntax layer. The state machine (sequence numbers, IFSC/IFSD negotiation, reassembly of chained APDUs) lives in t1_state.h.

Maximum information-field length per ISO 7816-3 T=1 (LEN byte).

Definition at line 34 of file t1_block.h.

Referenced by t1_block_encode_i(), and t1_block_encode_s().

◆ T1_LEN_RESERVED

#define T1_LEN_RESERVED   0xFF

Reserved LEN value; must not appear on the wire.

Definition at line 40 of file t1_block.h.

Referenced by t1_block_decode().

Enumeration Type Documentation

◆ t1_block_kind_t

T=1 block taxonomy.

Enumerator
T1_BLOCK_I 

Information block (carries APDU bytes).

T1_BLOCK_R 

Receive-ready block (ACK / error).

T1_BLOCK_S 

Supervisory block (IFS, ABORT, WTX, RESYNCH).

Definition at line 43 of file t1_block.h.

◆ t1_r_error_t

R-block error indicator (PCB bits 1-0).

Enumerator
T1_R_OK 

No error, request retransmission of N(R).

T1_R_EDC_ERR 

EDC / parity error detected.

T1_R_OTHER_ERR 

Other error.

Definition at line 50 of file t1_block.h.

◆ t1_s_subtype_t

S-block subtype (PCB bits 5-0).

Enumerator
T1_S_RESYNCH_REQ 
T1_S_IFS_REQ 
T1_S_ABORT_REQ 
T1_S_WTX_REQ 
T1_S_RESYNCH_RESP 
T1_S_IFS_RESP 
T1_S_ABORT_RESP 
T1_S_WTX_RESP 

Definition at line 57 of file t1_block.h.

◆ t1_status_t

Result of t1_block_decode / t1_block_encode.

Enumerator
T1_OK 
T1_ERR_SHORT 

Buffer too small for header.

T1_ERR_LEN 

LEN byte is reserved (0xFF) or buffer mismatch.

T1_ERR_INF_TOO_BIG 

INF length > T1_INF_MAX.

T1_ERR_EDC 

EDC mismatch.

T1_ERR_PCB 

PCB encoding invalid (e.g. R-block with non-zero reserved bits).

T1_ERR_OUT_BUF 

Output buffer too small.

T1_ERR_NULL 

NULL argument where forbidden.

Definition at line 90 of file t1_block.h.

Function Documentation

◆ t1_block_decode()

t1_status_t t1_block_decode ( const uint8_t * buf,
size_t buf_len,
bool use_crc,
t1_block_t * out )

Decode a T=1 block.

The decoder validates LEN, EDC, and PCB encoding rules. Reserved bits in I- and R-blocks must be zero; otherwise T1_ERR_PCB is returned.

Parameters
bufInput bytes.
buf_lenNumber of bytes available.
use_crcIf true, expect 2-byte CRC; otherwise LRC.
outDecoded block (INF pointer aliases into buf).

Definition at line 147 of file t1_block.cpp.

References t1_block_t::edc_ok, t1_block_t::i_more, t1_block_t::i_ns, t1_block_t::inf, t1_block_t::inf_len, t1_block_t::kind, t1_block_t::nad, t1_block_t::pcb, t1_block_t::r_err, t1_block_t::r_nr, t1_block_t::s_subtype, T1_BLOCK_I, T1_BLOCK_R, T1_BLOCK_S, t1_crc(), T1_ERR_LEN, T1_ERR_NULL, T1_ERR_PCB, T1_ERR_SHORT, T1_LEN_RESERVED, t1_lrc(), T1_OK, and t1_block_t::use_crc.

◆ t1_block_encode_i()

t1_status_t t1_block_encode_i ( uint8_t nad,
uint8_t ns,
bool more,
const uint8_t * inf,
uint8_t inf_len,
bool use_crc,
uint8_t * out,
size_t out_cap,
size_t * out_len )

Encode an I-block.

Parameters
nadNode address.
nsSequence number (0 or 1).
moreMore-data flag (chaining).
infInformation field payload (may be NULL when inf_len == 0).
inf_lenPayload length (<= T1_INF_MAX).
use_crcUse 2-byte CRC instead of LRC.
outOutput buffer (caller-allocated, at least 4 + inf_len + (use_crc ? 1 : 0) bytes).
out_capOutput capacity in bytes.
out_lenReceives total bytes written.

Definition at line 75 of file t1_block.cpp.

References append_edc(), T1_ERR_INF_TOO_BIG, T1_ERR_NULL, T1_ERR_OUT_BUF, T1_ERR_PCB, and T1_INF_MAX.

Referenced by t1_state_next_outbound().

◆ t1_block_encode_r()

t1_status_t t1_block_encode_r ( uint8_t nad,
uint8_t nr,
t1_r_error_t err,
bool use_crc,
uint8_t * out,
size_t out_cap,
size_t * out_len )

Encode an R-block.

Parameters
nadNode address.
nrExpected sequence number (0 or 1).
errError indicator.
use_crcEDC algorithm select.
outOutput buffer.
out_capOutput buffer capacity.
out_lenReceives bytes written.

Definition at line 103 of file t1_block.cpp.

References append_edc(), T1_ERR_NULL, T1_ERR_OUT_BUF, and T1_ERR_PCB.

Referenced by encode_rblock().

◆ t1_block_encode_s()

t1_status_t t1_block_encode_s ( uint8_t nad,
t1_s_subtype_t subtype,
const uint8_t * inf,
uint8_t inf_len,
bool use_crc,
uint8_t * out,
size_t out_cap,
size_t * out_len )

Encode an S-block.

Parameters
nadNode address.
subtypeS-block subtype (request or response).
infOptional info payload (e.g. IFS new value).
inf_lenLength of the info payload (0..254).
use_crcEDC algorithm select.
outOutput buffer.
out_capOutput buffer capacity.
out_lenReceives bytes written.

Definition at line 123 of file t1_block.cpp.

References append_edc(), T1_ERR_INF_TOO_BIG, T1_ERR_NULL, T1_ERR_OUT_BUF, T1_ERR_PCB, and T1_INF_MAX.

Referenced by encode_sblock_response().

◆ t1_crc()

uint16_t t1_crc ( const uint8_t * buf,
size_t len )

Compute the ISO/IEC 13239 CRC-16 of a buffer (polynomial 0x1021, initial value 0xFFFF, no final XOR, MSB first). Used as the alternative EDC when CRC is negotiated.

Definition at line 41 of file t1_block.cpp.

Referenced by append_edc(), and t1_block_decode().

◆ t1_lrc()

uint8_t t1_lrc ( const uint8_t * buf,
size_t len )

Compute the longitudinal redundancy check (LRC) of a buffer.

LRC is the bytewise XOR of all bytes in buf. Used as the default EDC byte when the T=1 protocol parameters do not select CRC.

Parameters
bufBuffer pointer.
lenNumber of bytes to fold into the LRC.
Returns
XOR of all bytes.

Definition at line 33 of file t1_block.cpp.

Referenced by append_edc(), and t1_block_decode().