RBC_Test_Sim_Core 0.1.0 build 51fd23e
Shared transport-layer plumbing for the ADR-029 Train/IL/CTC RBC simulators
Loading...
Searching...
No Matches
simcore.saf Namespace Reference

Classes

class  SafError
class  SafSession

Functions

 _permute (value, table, width)
 _des_subkeys (key8)
 _feistel (r, subkey)
 _des_block (block8, subkeys)
 des_encrypt_block (key8, block8)
 des_decrypt_block (key8, block8)
 _algo3 (key24, block8)
 _algo3_reversed (key24, block8)
 derive_ksmac (kmac, ra, rb)
 compute_mac (ksmac, msg)
 _equal_ct (a, b)
 mac_over_da_body (ksmac, da_id, body)
 _pack_id24 (id_)
 _unpack_id24 (buf)
 _pack_header (ety, mti, df)
 _header_mti (header_byte)
 _header_df (header_byte)
 _monotonic_ms ()

Variables

tuple _IP
tuple _FP
tuple _E
tuple _P
tuple _PC1
tuple _PC2
tuple _SHIFTS = (1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1)
tuple _SBOX
int MAC_LEN = 8
int RAND_LEN = 8
int KEY_LEN = 24
 MTI_AU1
 MTI_AU2
 MTI_AU3
 MTI_DT
 MTI_DI
 MTI_AR
int SEQ_WINDOW = 8
int MAX_PDU = 1024

Detailed Description

SaF - Python mirror of the safe-communication Safety Functional layer.

Byte-identical to ``Platform_Protocol_SafeComm`` (``src/mac/mac.c``, ``src/saf/saf.c``), the same way
``simcore.rbc_wire`` mirrors the C wire codec. The construction follows Subset-037-2 v4.0.0
("EuroRadio FIS - Safety Layer") directly:

* DES, pure Python so a sim needs no crypto package.
* CBC-MAC (Subset-037-2 SS6.2.2, "single DES with modified MAC algorithm 3"): every block but the last is
  single-DES under K1; the last block alone gets E(K3, D(K2, E(K1, .))). ISO/IEC 9797-1 Padding Method 1
  (zero bits, no extra block when the message is already a multiple of 64 bits). Verified against the
  official worked example in Subset-037-2 Annex B.
* KSMAC derivation (SS6.2.3.2.3.13-16): RA and RB are each split into 32-bit left/right halves; KS1/KS2 use
  the normal key order over the left/right halves, KS3 reuses the left half with the key order reversed.
* Frames AU1 (13) / AU2 (21) / AU3 (9) / AR (9) / DT (1+n+8) / DI (3, unauthenticated) per Subset-037-2
  SS6.2.5's tables: a packed ETY|MTI|DF header octet and 24-bit ETCS IDs. The MAC input for AU2/AU3/DT/AR
  follows SS6.2.3.2.1 (message origin authentication: length|DA|body) and SS6.2.3.2.2/Figure 6 (peer entity
  authentication) - DA is always the *receiver's own* identity.
* Sa-DISCONNECT carries no MAC or identity field at all (Table 6/13): SS6.2.3.3.3.2 says release-phase
  authentication is not required, since a forged one can only end the connection early, never inject or
  alter safety data. Any well-formed DI is honoured.

One deliberate, non-conformant addition: the official DT SaPDU carries no sequence number (Table 12) - that
defence is the Subset-098 SAI sub-layer's job (sequence numbering / Triple Time Stamping / EC counter,
SS5.4), which this module does not implement. In its place a 4-byte sequence number is carried inside the
MAC-covered user-data area, matching what ``saf.c`` does. This is a project extension, not itself
conformant to any subset - see ``docs/safety/SUBSET_MAPPING.md`` in the SafeComm library.

The session is transport-agnostic: the caller supplies ``send(bytes)`` and ``recv() -> bytes`` (one
frame per call). ``recv`` raises ``TimeoutError`` when nothing arrived in time.

This is a test tool. The MAC is cryptographically dated (see the C library's SUBSET_MAPPING.md).

Function Documentation

◆ _algo3()

_algo3 ( key24,
block8 )
protected
Subset-037-2 SS6.2.2.1 "single DES with modified MAC algorithm 3": E(K3, D(K2, E(K1, block))).

Definition at line 143 of file saf.py.

◆ _algo3_reversed()

_algo3_reversed ( key24,
block8 )
protected
The same construction with K1 and K3 swapped: E(K1, D(K2, E(K3, block))). Used only for KS3.

Definition at line 150 of file saf.py.

◆ _des_block()

_des_block ( block8,
subkeys )
protected

Definition at line 125 of file saf.py.

◆ _des_subkeys()

_des_subkeys ( key8)
protected

Definition at line 103 of file saf.py.

◆ _equal_ct()

_equal_ct ( a,
b )
protected

Definition at line 193 of file saf.py.

◆ _feistel()

_feistel ( r,
subkey )
protected

Definition at line 114 of file saf.py.

◆ _header_df()

_header_df ( header_byte)
protected

Definition at line 233 of file saf.py.

◆ _header_mti()

_header_mti ( header_byte)
protected

Definition at line 229 of file saf.py.

◆ _monotonic_ms()

_monotonic_ms ( )
protected

Definition at line 461 of file saf.py.

◆ _pack_header()

_pack_header ( ety,
mti,
df )
protected

Definition at line 225 of file saf.py.

◆ _pack_id24()

_pack_id24 ( id_)
protected

Definition at line 217 of file saf.py.

◆ _permute()

_permute ( value,
table,
width )
protected
Bit permutation: ``table`` lists 1-based source bit positions, MSB first.

Definition at line 95 of file saf.py.

◆ _unpack_id24()

_unpack_id24 ( buf)
protected

Definition at line 221 of file saf.py.

◆ compute_mac()

compute_mac ( ksmac,
msg )
CBC-MAC (SS6.2.2): every block but the last under K1 only; the last block via _algo3. ISO/IEC 9797-1
Padding Method 1 (zero bits), no extra block when len(msg) is already a multiple of 8.

Definition at line 175 of file saf.py.

◆ derive_ksmac()

derive_ksmac ( kmac,
ra,
rb )
Session key (SS6.2.3.2.3.13-16): RA = RA_L|RA_R, RB = RB_L|RB_R (32-bit halves).
KS1 = algo3(RA_L|RB_L), KS2 = algo3(RA_R|RB_R), KS3 = algo3_reversed(RA_L|RB_L).

Definition at line 165 of file saf.py.

◆ des_decrypt_block()

des_decrypt_block ( key8,
block8 )
Single DES decrypt, one 8-byte block.

Definition at line 138 of file saf.py.

◆ des_encrypt_block()

des_encrypt_block ( key8,
block8 )
Single DES, one 8-byte block.

Definition at line 133 of file saf.py.

◆ mac_over_da_body()

mac_over_da_body ( ksmac,
da_id,
body )
[length(2, BE) | DA(3) | body], MACed (SS6.2.3.2.1.1 "Procedure 1"). compute_mac() zero-pads itself.

Definition at line 202 of file saf.py.

Variable Documentation

◆ _E

tuple simcore.saf._E
protected
Initial value:
= (32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1)

Definition at line 46 of file saf.py.

◆ _FP

tuple simcore.saf._FP
protected
Initial value:
= (40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25)

Definition at line 42 of file saf.py.

◆ _IP

tuple simcore.saf._IP
protected
Initial value:
= (58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7)

Definition at line 38 of file saf.py.

◆ _P

tuple simcore.saf._P
protected
Initial value:
= (16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25)

Definition at line 49 of file saf.py.

◆ _PC1

tuple simcore.saf._PC1
protected
Initial value:
= (57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4)

Definition at line 51 of file saf.py.

◆ _PC2

tuple simcore.saf._PC2
protected
Initial value:
= (14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4,
26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40,
51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32)

Definition at line 55 of file saf.py.

◆ _SBOX

tuple simcore.saf._SBOX
protected

Definition at line 59 of file saf.py.

◆ _SHIFTS

tuple simcore.saf._SHIFTS = (1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1)
protected

Definition at line 58 of file saf.py.

◆ KEY_LEN

int simcore.saf.KEY_LEN = 24

Definition at line 162 of file saf.py.

◆ MAC_LEN

int simcore.saf.MAC_LEN = 8

Definition at line 160 of file saf.py.

◆ MAX_PDU

int simcore.saf.MAX_PDU = 1024

Definition at line 214 of file saf.py.

◆ MTI_AR

simcore.saf.MTI_AR

Definition at line 212 of file saf.py.

◆ MTI_AU1

simcore.saf.MTI_AU1

Definition at line 212 of file saf.py.

◆ MTI_AU2

simcore.saf.MTI_AU2

Definition at line 212 of file saf.py.

◆ MTI_AU3

simcore.saf.MTI_AU3

Definition at line 212 of file saf.py.

◆ MTI_DI

simcore.saf.MTI_DI

Definition at line 212 of file saf.py.

◆ MTI_DT

simcore.saf.MTI_DT

Definition at line 212 of file saf.py.

◆ RAND_LEN

int simcore.saf.RAND_LEN = 8

Definition at line 161 of file saf.py.

◆ SEQ_WINDOW

int simcore.saf.SEQ_WINDOW = 8

Definition at line 213 of file saf.py.