Skip to content

feat: HSM production-crypto path (B1) — capability interfaces + PKCS#11 + payShield - #18

Merged
canaan5 merged 1 commit into
mainfrom
feat/hsm
Jun 9, 2026
Merged

canaan5 merged 1 commit into
mainfrom
feat/hsm

Conversation

@canaan5

@canaan5 canaan5 commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Consolidates the in-flight HSM work into one reviewable change toward roadmap B1 (production crypto path). SoftVault remains the default in-process backend; every HSM adapter is an opt-in separate module, so the root module graph stays stdlib-only.

What's here

Merges three branches and completes the gap:

  1. vault capability interfaces (feat/vault-hsm-interfaces). Decomposes vault.Vault into PINEncryptor / PINTranslator / Macer, so an adapter advertises exactly what its device can securely do. Source-compatible — Vault keeps the same method set. PINTranslator documents the PCI PIN-Security contract (atomic in-device translate; adapters that can't must not implement it).

  2. adapters/pkcs11 (feat/pkcs11-foundation). Generic PKCS#11 / SoftHSM2 adapter implementing Macer (ISO 9797-1 alg 1 + alg 3 retail MAC), composed from the token's 3DES primitives; output is byte-for-byte identical to vault.GenerateMAC, cross-checked against a real token under SoftHSM2 in CI. Separate cgo module. Deliberately Macer-only — no PIN translate (no PCI-secure stock-PKCS#11 mechanism) and no clear-PIN encrypt (belongs to a payment/issuer HSM).

  3. adapters/payshield (feat/payshield-adapter + this PR's new work). Thales payShield adapter over the host-command protocol. Now implements the full vault.Vault: this PR adds EncryptPINBlock (PINEncryptor) on top of the existing TranslatePIN + MAC, with the BA/BB encrypt-PIN command, simulator dispatch, and a deterministic ISO0 test that cross-checks against the software vault. Stdlib-only module.

Design note (divergence worth flagging)

I considered adding PINEncryptor to the PKCS#11 adapter too, but kept it Macer-only by design: its package doc makes a deliberate, written choice that clear-PIN handling belongs to a payment/issuer HSM, not a general-purpose token. The "full vault.Vault" goal is met by payShield, where PIN encrypt properly belongs. Happy to revisit if you'd rather pkcs11 also offer issuer-context PIN encrypt.

Scope / honesty

  • Validated against SoftHSM2 (pkcs11) and the in-repo simulator (payshield) — not real certified hardware. Per the roadmap, real-HSM validation needs vendor access and is out of scope here.
  • payShield wire layout (positional Host-Command fields) and pooled/reconnecting transport remain documented TODOs — the simulator uses a simplified self-consistent encoding.
  • Independent security review still required before production use.

Verification

  • Root module: go build/vet/test ./... clean; zero third-party deps in the core graph.
  • All four adapter modules (otel, sql, payshield, pkcs11) build/vet/test green; gofmt clean.
  • CI (.github/workflows/adapters.yml): matrix over otel/sql/payshield + a dedicated SoftHSM2 job for pkcs11.

Does not close B1 (real-hardware validation + security review outstanding); it lands the engineering-completable portion.

…11 + payShield

Consolidates the HSM work toward roadmap B1 (production crypto path). SoftVault
stays the default in-process backend; every HSM adapter is an opt-in separate
module, so the root module graph remains stdlib-only.

- vault capability interfaces: decompose vault.Vault into PINEncryptor /
  PINTranslator / Macer so an adapter advertises exactly what its device can
  securely do. Source-compatible — Vault keeps the same method set. PINTranslator
  documents the PCI PIN-Security contract (atomic in-device translate; adapters
  that cannot must not implement it).

- adapters/pkcs11: generic PKCS#11 / SoftHSM2 adapter implementing Macer
  (ISO 9797-1 alg 1 and alg 3 retail MAC), composed from the token's 3DES
  primitives; output byte-for-byte identical to vault.GenerateMAC, cross-checked
  against a real token under SoftHSM2 in CI. Separate cgo module. Deliberately
  Macer-only: no PIN translate (no PCI-secure stock-PKCS#11 mechanism) and no
  clear-PIN encrypt (belongs to a payment/issuer HSM).

- adapters/payshield: Thales payShield adapter over the host-command protocol,
  implementing the full vault.Vault — EncryptPINBlock (PINEncryptor),
  TranslatePIN (PINTranslator), and GenerateMAC/VerifyMAC (Macer). Ships an
  in-repo protocol simulator whose cryptography is the software vault, so the
  command flow is exercised end to end in CI without hardware. Stdlib-only module.

Validated against SoftHSM2 (pkcs11) and the in-repo simulator (payshield), not
real certified hardware: real-HSM validation, the exact positional wire layout,
pooled transport, and independent security review remain outstanding (does not
close B1). Also fixes the docs changelog link to ROADMAP-to-v1.md (absolute URL)
so the strict site build passes.
@canaan5
canaan5 merged commit a5f790d into main Jun 9, 2026
10 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 9, 2026
@canaan5
canaan5 deleted the feat/hsm branch June 9, 2026 11:45
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