SM Hardware Simulation & Bring-Up · 2025-12-11

Audience: crypto operators and CI engineers bringing up or simulating SM2/SM3 hardware for the Chinese (CN) sovereign profile in Stella Ops.

Use this runbook to simulate or attach SM2/SM3 hardware for the CN profile (the sm compliance profile, ComplianceProfiles.Sm, src/__Libraries/StellaOps.Cryptography/ComplianceProfiles.cs). SM hardware is integrated behind the cn.sm.remote.http vendor adapter — the SM Remote service (src/SmRemote/) does not load a PKCS#11 library itself, so any SoftHSM2 or vendor token sits behind that adapter. When hardware is unavailable, use the software provider (cn.sm.soft) or the unified crypto simulator (devops/services/crypto/sim-crypto-service, provider sim.crypto.remote) to keep CI green.

Goals

Simulation path (SoftHSM2)

Status: roadmap. As of this writing the SM crypto stack ships two providers — the software-only cn.sm.soft provider (BouncyCastle SM2/SM3/SM4, src/__Libraries/StellaOps.Cryptography.Plugin.SmSoft/SmSoftCryptoProvider.cs) and the remote-HSM bridge cn.sm.remote.http (src/SmRemote/, src/__Libraries/StellaOps.Cryptography.Plugin.SmRemote/). There is no direct SoftHSM2/PKCS#11 SM provider: the SM Remote service does not load a PKCS#11 library itself. SoftHSM2 can be exercised today only behind a cn.sm.remote.http vendor adapter (with SM_REMOTE_HSM_ADAPTER_KIND=pkcs11), or via the generic HSM plugin (src/Cryptography/StellaOps.Cryptography.Plugin.Hsm/, HsmOptions.LibraryPath/SlotId), which is a separate non-SM provider. Keep the SoftHSM2 commands below as the token-provisioning recipe for that vendor-adapter path; the StellaOps-side wiring is the SmRemote: configuration shown later, not a direct StellaOps:Crypto:Pkcs11 SM binding.

sudo apt-get install softhsm2
softhsm2-util --init-token --slot 0 --label "SM2SIM" --so-pin 1234 --pin 1234
softhsm2-util --import sm2-private-key.pem --token "SM2SIM" --label "sm2key" --id 1 --pin 1234

NOT IMPLEMENTED — the StellaOps:Crypto:Pkcs11 config block below (with Keys[].SlotId/PinEnvVar/Algorithm) is not a recognized SM-provider configuration schema; no SM code binds it. The recognized SM knobs are the cn.sm.soft/cn.sm.remote.http provider selection plus the SmRemote: section and SM_*/SMREMOTE_* environment variables documented below. The generic HSM plugin uses a different shape (HsmOptions.LibraryPath/SlotId) and is not the SM provider. The YAML is retained only as an illustration of the intended future direct-PKCS#11 SM binding.

# Roadmap / illustrative only — NOT consumed by the SM providers today.
StellaOps:
  Crypto:
    Registry:
      ActiveProfile: sm
    Pkcs11:
      LibraryPath: /usr/lib/softhsm/libsofthsm2.so
      Keys:
        - KeyId: sm2-hw
          SlotId: 0
          PinEnvVar: SM_PKCS11_PIN   # export SM_PKCS11_PIN=1234
          Algorithm: sm2

Vendor hardware bring-up

Vendor SM hardware is integrated behind the cn.sm.remote.http vendor adapter, not by loading a PKCS#11 library inside StellaOps. The adapter terminates the vendor PKCS#11/SDF/HSM-SDK call and exposes the SM Remote HTTP contract.

  1. Stand up (or obtain) a vendor adapter that fronts the PKCS#11/SDF/HSM module (e.g., Feitian/Jacarta SM modules) and exposes the SM Remote HTTP contract (/health, /status, /keys, /sign, /verify, /encrypt, /decrypt).
  2. Import the SM2 private key/cert into the module per vendor tooling; record the remote key IDs the adapter advertises on /keys.
  3. Configure the SM Remote service to point at the adapter — see Production SM Remote bridge. Set SM_REMOTE_HSM_ADAPTER_KIND=pkcs11 (or sdf/sm-hsm) and map your local key IDs to the adapter’s remote key IDs via SMREMOTE_KEYS.
  4. Validate the software SM provider’s algorithm correctness with the SmSoft compliance suite (OSCCA GM/T 0003/0004 SM2/SM3 vectors). These are pure in-process unit tests and do not read SM_PKCS11_* or SM_SOFT_ALLOWED (the test sets RequireEnvironmentGate=false directly):
    dotnet test src/__Libraries/StellaOps.Cryptography.Plugin.SmSoft.Tests
    

NOT IMPLEMENTED: STELLAOPS_CRYPTO_ENABLE_SM_PKCS11 is not referenced by any source. SM_PKCS11_LIBRARY/SM_PKCS11_PIN are honored only by the generic HSM and Pkcs11Gost plugins, not by the SM (cn.sm.*) providers, and the SmSoft test project does not consume any of them.

Production SM Remote bridge

src/SmRemote/ (StellaOps.SmRemote.Service) hosts the SM Remote service. It registers the src/__Libraries/StellaOps.Cryptography.Plugin.SmRemote/ SmRemoteHttpProvider (provider id cn.sm.remote.http) when the runtime selects the remote provider, and exposes its own scoped HTTP surface — /health, /status, /hash, /encrypt, /decrypt, /sign, /verify — fronted by the Router. The five mutating endpoints require StellaOps scopes (sm-remote:hash, sm-remote:encrypt, sm-remote:decrypt, sm-remote:sign, sm-remote:verify); /health and /status are anonymous.

Required production configuration (validated at startup via SmRemoteRuntimeOptions.ValidateRuntime, which fails fast / refuses to start outside Development|Testing if any check below is not satisfied):

SMREMOTE_PROVIDER=cn.sm.remote.http
SM_REMOTE_HSM_URL=https://sm-hsm-adapter.local   # must be an absolute http(s) URL
SMREMOTE_KEYS=authority-sm2=vendor-sm2-key,attestor-sm2=vendor-attestor-key
SM_REMOTE_HSM_ADAPTER_KIND=sm-hsm                # one of: sm-hsm | sdf | pkcs11
SM_REMOTE_HSM_CONTRACT_VERSION=sm-remote-vendor-adapter.v1
SM_REMOTE_HSM_REQUIRE_VENDOR_CONTRACT=1          # production requires this true
SMREMOTE_ALLOW_SOFTWARE_PROVIDER=0
SMREMOTE_ALLOW_EPHEMERAL_KEYS=0

Optional / situational settings:

SM_REMOTE_HSM_API_KEY=<secret>                   # bearer token to the adapter
SM_REMOTE_HSM_REQUIRE_API_KEY=1                  # require the bearer token (else startup fails if unset)
SM_REMOTE_HSM_TIMEOUT=30000                      # ms; default 30000, must be > 0 in production

Production validation also rejects cn.sm.soft, requires at least one SMREMOTE_KEYS mapping with non-empty local and remote key IDs, and forbids duplicate local key IDs. SMREMOTE_ALLOW_EPHEMERAL_KEYS=1 is rejected outside local harnesses; when it is enabled on a Development/Testing harness it also requires a positive SMREMOTE_EPHEMERAL_KEY_TTL (ISO-8601 duration, e.g. PT1H).

SMREMOTE_KEYS is an allow-list. Each item is either keyId or localKeyId=remoteKeyId; unmapped production key IDs fail closed instead of being generated locally (AllowImplicitKeyMapping=false in production). The downstream adapter must expose the full SM Remote HTTP contract — the service probes /health, /status, and /keys and rejects simulator-shaped, incomplete, or non-production responses (see SmRemoteVendorContract in src/__Libraries/StellaOps.Cryptography.Plugin.SmRemote/SmRemoteHttpClient.cs) before forwarding /sign, /verify, /encrypt, or /decrypt. The adapter must also advertise, for each configured key, an algorithm and usage matching the requested operation, or the call fails closed. Vendor-specific PKCS#11, SDF, or HSM SDK integrations should live behind that adapter rather than inlining vendor code in Stella Ops. The adapter contract is documented in sm-remote-vendor-adapter-contract.md.

Simulator fallback

Note: the compose overlay also sets STELLAOPS_ALLOW_UNSAFE_CRYPTO_SIM=1, but that variable is a compose-level convention only — no source code enforces it. The actual code-level gate is STELLAOPS_CRYPTO_ENABLE_SIM.

Validation evidence to capture

Determinism

Publishing