Files
aliro-project/harness/tests/test_trust_header.py
Dangerous Things 782074f6ae Initial snapshot: Aliro applet, harness, Nucleo NFC10A1 reader port
Three components, all bench-validated to varying depths:

- applet/: CSA Aliro v1.0 Java Card applet for J3R180. AUTH0 + AUTH1
  expedited-standard flow end-to-end green via PC/SC bench reader
  (aliro-bench-test). Userland AES-256-GCM and HMAC-SHA-256 layered
  on top of J3R180's primitives because the card lacks both natively.
  P-256 curve params seeded explicitly per J3R180's quirk.

- harness/: Python orchestrator (aliro-trustgen, aliro-personalize,
  aliro-bench-test) for trust-bundle generation, card personalization
  via PersonalizationApplet, and PC/SC AUTH0+AUTH1 transactions. 126
  pytest cases passing.

- reader/STM32CubeExpansion_ALIRO_V1_0_0/: ST X-CUBE-ALIRO V1.0.0
  with our NFC10A1 port (NUCLEO-U545RE-Q + X-NUCLEO-NFC10A1, ST25R200
  shared with NFC09A1). nfc10-only/ project, NFC10A1 BSP shim,
  ALIRO_TRUST_OVERRIDE include into vendor's provisioning.c, and an
  ALIRO_APDU_TRACE wrapper around demoTransceiveBlocking. Boots,
  detects the J3R180, completes SELECT + AUTH0; AUTH1 currently fails
  with RFAL ERR_PROTO (0xB) — under investigation, see
  docs/plans/2026-04-20-nucleo-nfc10a1-port.md and bench-notes/.

Excluded: x-cube-aliro.zip vendor archive, harness/.venv, build dirs,
generated aliro_trust.h (contains private reader scalar), all PEMs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 10:17:46 -07:00

88 lines
2.7 KiB
Python

"""Tests for the C header emitted from a TrustBundle."""
from cryptography.hazmat.primitives.asymmetric import ec
from aliro_harness.trustgen.header import TrustBundle, render_trust_header
def _bundle():
return TrustBundle(
issuer_public_key=ec.generate_private_key(ec.SECP256R1()).public_key(),
reader_private_key=ec.generate_private_key(ec.SECP256R1()),
reader_group_id=bytes(range(16)),
reader_group_sub_id=bytes(range(16, 32)),
)
def test_header_has_include_guard():
text = render_trust_header(_bundle())
assert "#ifndef ALIRO_TRUST_H_" in text
assert "#define ALIRO_TRUST_H_" in text
assert "#endif" in text
def test_header_marks_file_as_autogenerated():
text = render_trust_header(_bundle())
assert "AUTO-GENERATED" in text
assert "DO NOT EDIT" in text
def test_header_defines_reader_private_key_as_32_bytes():
text = render_trust_header(_bundle())
assert "#define ALIRO_READER_PRIVATE_KEY" in text
assert text.count("0x", text.index("ALIRO_READER_PRIVATE_KEY")) >= 32
def test_header_defines_reader_public_key_as_x_y_concatenated_64_bytes():
text = render_trust_header(_bundle())
assert "#define ALIRO_READER_PUBLIC_KEY" in text
def test_header_defines_issuer_pub_x_y_and_concatenated():
text = render_trust_header(_bundle())
assert "#define ALIRO_ISSUER_PUB_X" in text
assert "#define ALIRO_ISSUER_PUB_Y" in text
assert "#define ALIRO_ISSUER_PUB" in text
def test_header_defines_issuer_kid():
text = render_trust_header(_bundle())
assert "#define ALIRO_ISSUER_KID" in text
def test_header_defines_reader_group_ids():
text = render_trust_header(_bundle())
assert "#define ALIRO_READER_GROUP_ID" in text
assert "#define ALIRO_READER_GROUP_SUB_ID" in text
def test_reader_private_key_bytes_match_input():
bundle = _bundle()
text = render_trust_header(bundle)
expected = bundle.reader_private_key.private_numbers().private_value.to_bytes(32, "big")
first_byte_hex = f"0x{expected[0]:02x}"
last_byte_hex = f"0x{expected[-1]:02x}"
priv_block_start = text.index("ALIRO_READER_PRIVATE_KEY")
priv_block_end = text.index("#define", priv_block_start + 1)
block = text[priv_block_start:priv_block_end]
assert first_byte_hex in block
assert last_byte_hex in block
def test_issuer_kid_matches_compute_issuer_kid():
from aliro_harness.issuer.kid import compute_issuer_kid
bundle = _bundle()
text = render_trust_header(bundle)
expected_kid = compute_issuer_kid(bundle.issuer_public_key)
kid_start = text.index("ALIRO_ISSUER_KID")
kid_end = text.index("\n", kid_start)
kid_line = text[kid_start:kid_end]
for b in expected_kid:
assert f"0x{b:02x}" in kid_line