Skip to content

feat(adapters/payshield): Thales payShield adapter scaffold (PINTranslator + Macer) + simulator#13

Closed
canaan5 wants to merge 4 commits into
mainfrom
feat/payshield-adapter
Closed

feat(adapters/payshield): Thales payShield adapter scaffold (PINTranslator + Macer) + simulator#13
canaan5 wants to merge 4 commits into
mainfrom
feat/payshield-adapter

Conversation

@canaan5

@canaan5 canaan5 commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Scaffolds adapters/payshield, a reference payment-HSM adapter that exposes a Thales payShield over its host-command protocol as the vault capabilities a switch needs — the counterpart to adapters/pkcs11 (which is Macer-only).

Capability surface (the point of the capability split)

PINTranslator Macer PINEncryptor
adapters/pkcs11 (general HSM) ❌ (no PCI-secure translate on stock PKCS#11)
adapters/payshield (payment HSM) — (out of scope here)
  • vault.PINTranslator — PIN translate re-enciphered atomically inside the device, so the clear PIN never reaches host memory (PCI PIN Security). This is exactly what a general-purpose PKCS#11 HSM cannot do.
  • vault.Macer — ISO 9797-1 MAC (algorithms 1 and 3).

Keys are named by the device's LMK key token; the clear key never leaves the device.

What's verified

Ships an in-repo Simulator — a protocol test double whose cryptography is the Isopace software vault (vault.SoftVault), so it returns real ISO 9564 / ISO 9797-1 values with no hardware. The suite (in-process, race-clean, in the adapters CI matrix) asserts:

  • adapter MAC == vault.GenerateMAC (alg 1 & 3, both paddings, several message lengths);
  • an ISO0 → ISO3 → ISO0 PIN translate round-trips (PIN + PAN preserved through the reformat);
  • unknown key → *payshield.HostError{Code:"10"}, unsupported algorithm → error, unreachable host → error;
  • compile-time PINTranslator + Macer conformance.

Scaffold status (honest scope)

Faithful: capability surface, host-command framing + request/response-code convention, key-token references, format/algorithm selection, error-code handling.

Stand-in (remaining integration work, tracked under B1):

  • on-wire field layout is a simplified length-prefixed encoding standing in for payShield's positional fields — swap for the exact Host Command Reference layout for the targeted firmware;
  • transport is a single mutex-serialised connection (no pooling/reconnect — front with connector);
  • not validated against real LMK schemes / key tokens / certified hardware; independent security review required before production.

Note on stacking

Built on top of #12 (vault capability interfaces), which this depends on for PINTranslator/Macer. Until #12 merges, this PR's diff includes #12's commits; it cleans up once #12 lands. Separate, stdlib-only module — the core graph is unchanged.

canaan5 added 3 commits June 4, 2026 03:04
Make the key-management façade HSM-adapter-ready by splitting it into small
capability interfaces, so an adapter implements exactly what its device supports.

- Add PINEncryptor, PINTranslator, and Macer. Vault is now their composition,
  so it keeps the same method set — source-compatible; SoftVault and SealedVault
  still satisfy Vault unchanged.
- PINTranslator documents the PCI PIN Security contract: a conforming hardware
  implementation must re-encipher the PIN block atomically inside the device so
  the clear PIN never leaves it; an adapter that cannot (e.g. stock PKCS#11) must
  not implement the interface, since callers rely on its presence to mean the
  operation is PIN-secure.
- A general-purpose PKCS#11 HSM provides Macer (and possibly PINEncryptor); a
  payment HSM (Thales payShield, Futurex) additionally provides PINTranslator.
  Callers type-assert for the narrowest capability they need.

Adds capability-detection tests. gofmt/vet clean; ./... builds, vault/flow/gateway
pass under -race.
A reference payment-HSM adapter that exposes a Thales payShield over its
host-command protocol as the vault capabilities a switch needs:

- vault.PINTranslator — PCI-secure PIN translate (re-enciphered atomically in the
  device; the clear PIN never reaches the host). This is the capability a stock
  PKCS#11 HSM cannot provide, so adapters/pkcs11 omits it; here it is the point.
- vault.Macer — ISO 9797-1 message MAC (algorithms 1 and 3).

Keys are named by the device's LMK key token; the clear key never leaves the
device. The host-command transport frames messages with a 2-byte length prefix
and follows the payShield request/response-code convention; command codes and
PIN-block-format codes are configurable to match a firmware's Host Command
Reference Manual.

Ships an in-repo Simulator: a protocol TEST DOUBLE whose cryptography is the
Isopace software vault (vault.SoftVault), so it returns real ISO 9564 / ISO 9797-1
values while requiring no hardware. The test suite (in-process, no external deps,
race-clean) cross-checks the adapter MAC against the software reference, verifies
an ISO0->ISO3->ISO0 PIN translate round-trips, and checks unknown-key and
unsupported-algorithm error handling. Added to the adapters CI matrix.

Scaffold status: the on-wire field layout is a simplified, self-consistent
stand-in for payShield's positional fields, and the transport is a single
mutex-serialised connection (no pooling/reconnect). The command set, key
references, format/algorithm selection, and error handling are modelled on
payShield. Real-device validation (LMK schemes, key tokens, certified hardware)
and independent security review remain — tracked under B1.
@canaan5 canaan5 closed this Jun 9, 2026
@canaan5 canaan5 deleted the feat/payshield-adapter branch June 9, 2026 11:45
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 9, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant