# CIP-security-poc → IEC 62443-4-2 (SL 2) component-requirement mapping **What this is:** an honest mapping of the *demonstrated* evidence in this repo to the relevant component requirements (CRs) of **IEC 62443-4-2:2019**, at target **Security Level 2 (SL-C 2)**. **What this is NOT:** a conformance assessment of any Rockwell (or other vendor) product. Product conformance to 62443-4-2 is established by the vendor plus an accredited lab (e.g. ISASecure CSA), against the full standard text and the product's real implementation. This document maps *our principle-level PoC* to the CRs so a reviewer can see exactly which requirement each test speaks to, and — just as importantly — which it does **not**. > **Two disciplines carried from the PoC into this doc:** > 1. **Tiers are honest.** "Demonstrated" means a test *could have failed and didn't*. Where the PoC > only motivates or partially addresses a CR, it says so. > 2. **Re-pull the CR text at submission.** The CR *titles* below were cross-checked against public > sources; the **normative requirement text is copyrighted** and must be verified against a > purchased copy of IEC 62443-4-2:2019 before this goes in a PSIRT packet. Do not rely on any > paraphrase here as the requirement of record. ## Why SL 2 is the right target CVE-2021-22681's exploitation profile is **"simple means, low resources, generic skills"**: the verification key was extracted by legitimate research (Claroty/Kaspersky/Soonchunhyang), has been public since 2021, and abusing it needs only the known key + custom code — no Rockwell software, licensed or pirated. That is the textbook definition of the **SL 2** attacker (intentional violation, simple means), not SL 3/4 (sophisticated/ICS-specific/extended resources). The remediation is therefore correctly evaluated against **SL-C 2** capability requirements. ## The mapping | CR | Title (IEC 62443-4-2:2019) | What it requires (paraphrase — verify vs standard) | PoC evidence | Tier | |---|---|---|---|---| | **CR 1.2** | Software process and device identification and authentication | Identify **and authenticate** software processes and **devices** (not only human users), and deny actions to unauthenticated ones | Test 3: per-**device** identity in the cert SAN, authenticated via mutual TLS; strict endpoint checks *which device*, not just cert validity. **Case 4 (control)** proves the device-identity step is load-bearing: without it, any fleet cert authenticates. | **DEMONSTRATED** (principle) | | **CR 1.9** | Strength of public key-based authentication | Where public-key auth is used: validate the certificate (chain of trust, validity period, **revocation status**), **map the credential to a specific entity**, and use adequate key strength | Test 3: chain-validates to a real CA, honours validity dates, **maps cert → entity via SAN**, RSA-2048. **Test 4: revocation-status check** — a revoked-but-otherwise-valid credential is denied against the current CRL. | **DEMONSTRATED** (validation + entity-mapping + strength + revocation-status all shown) | | **CR 1.8** | Public key infrastructure (PKI) certificates | Operate in accordance with an established PKI: issuance, chain validation, and lifecycle incl. **revocation** and rotation | Test 3: real CA, per-device issuance, chain validation. **Test 4: revocation** via signed CRL. **Test 5 (added 2026-08-03): rotation** — a replacement credential is issued for the same identity, and the negative control (case 3) shows the *old* credential stays valid until *explicitly* retired — re-issuance alone does not retire it. | **DEMONSTRATED for issuance / validation / revocation / rotation** — full CR 1.8 lifecycle now shown, not just enabled | | **CR 1.14** | Strength of symmetric key-based authentication | Where symmetric-key auth is used: per-entity **unique** keys of adequate strength — **not** one shared/hardcoded secret | Inverse mapping. Test 2 (+ the CVE itself) **demonstrates the *violation*** in the ORIGINAL design. The remediation **abandons symmetric-key auth entirely** for public-key auth (CR 1.9 / 1.2) — so in the *remediated* component there is no symmetric-key mechanism left for CR 1.14 to have scope over. | **VIOLATED by the original vulnerability; NOT APPLICABLE to the remediated design** — not "not met," which would misstate a design that removed the mechanism as one that failed to secure it | | **CR 3.1** | Communication integrity | Protect transmitted information against **unauthorised modification** | Test 3 / Test 4 run over TLS 1.2, which provides record-layer integrity (AEAD/MAC) alongside authentication. **Test 6 (added 2026-08-03):** a record-level relay flips one bit specifically inside the **ciphertext** — not the nonce, not the tag; the record layout is `nonce(8) ‖ ciphertext ‖ tag(16)` — of a live Application Data record, since CR 3.1 is about modification of the *transmitted information* itself. The receiving TLS stack's AEAD check rejects it (`SSLV3_ALERT_BAD_RECORD_MAC`) rather than delivering corrupted data. A control run (relay forwards every byte unmodified) confirms the relay itself introduces no corruption. | **DEMONSTRATED** (integrity tested directly, not merely relied upon) | ## Per-CR notes (the honest detail) **CR 1.2 — the strongest leg.** This is where the fix lands squarely. CVE-2021-22681 is a *device/ process* authentication failure (a controller trusting anything that presents the one key). Test 3 demonstrates device identification **and** authentication, and case 4 is the negative control that makes the claim empirical rather than asserted: strip the identity check and a valid-but-foreign fleet cert authenticates. Caveat: this is a principle PoC on a self-built CA + Python `ssl`, not a Rockwell implementation, and it covers authentication, not the full credential lifecycle (CR 1.3–1.5). **CR 1.9 — now fully demonstrated.** The PoC does the load-bearing part of CR 1.9 that distinguishes it from "any CA-valid cert": it **maps the credential to a specific entity** (SAN → `device-a`) and rejects a genuinely CA-valid cert bound to a different entity (Test 3, case 3), at RSA-2048 with chain + validity-period validation. **Test 4 adds the revocation-status clause**: a credential that is still CA-signed and unexpired is denied once its serial is on the current CRL. Identity + strength + revocation status are all shown. **CR 1.8 — demonstrated across the full lifecycle: issuance / validation / revocation / rotation.** Test 3 stands up a working PKI trust model (issue → chain-validate); Test 4 adds **revocation** via a CA-signed CRL. **Test 5 (added 2026-08-03) adds rotation**, with its own control: issuing a replacement credential for the same identity does **not** by itself retire the prior one (case 3 — both are valid until the prior credential is *explicitly* revoked, case 4); continuity holds throughout (case 5 — the identity never loses access during the transition). That two-step structure — re-issue, then separately retire — is the actual empirical content of "rotation" as CR 1.8 states it, not merely two features that happen to share a PKI. **CR 1.14 — violated by the original design; not applicable to the remediated one.** This is the subtle one, and worth being exact about rather than defaulting to the more self-critical-sounding label. CVE-2021-22681 *is* a CR 1.14 violation (a shared/hardcoded symmetric-style secret with no per-entity uniqueness) — Test 2 models that violation. But the remediation doesn't strengthen the symmetric scheme, it **abandons** it entirely for per-device public-key auth (CR 1.9 / 1.2). A requirement about the strength of symmetric-key authentication has no subject to apply to once symmetric-key authentication is no longer part of the design. Calling that **"not met"** would overstate our own gap — it reads to a reviewer as a residual hole in the SL 2 posture, when the accurate statement is that the remediated component doesn't use the mechanism CR 1.14 governs at all. Precision here runs in the *conservative* direction on purpose: the honesty discipline this document holds itself to should not cost accuracy by making a clean redesign look like an unmet requirement. **CR 3.1 — now independently tested, not just relied upon.** Using TLS gives communication integrity as a property of the channel — that was always true, but "we used TLS" and "we broke a record on purpose and watched it get rejected" are different tiers. **Test 6 (added 2026-08-03)** does the latter: a record-level relay (parses only the 5-byte TLS record header, never the plaintext) flips one bit inside the **ciphertext** of a live Application Data record — deliberately not the nonce or the tag, so the failure is attributable to modifying the *transmitted information*, which is what CR 3.1 actually asks about. The AEAD authentication check on the receiving end fails with `SSLV3_ALERT_BAD_RECORD_MAC` and the connection is torn down. A control run — the same relay forwarding every byte unmodified — confirms the relay itself introduces no corruption, so the tamper run's failure is attributable to the tamper, not the harness. ## Summary for the packet - **Directly demonstrated (empirically, with a control):** CR 1.2, CR 1.9, and the full lifecycle of CR 1.8 — issuance, validation, revocation, **and rotation** (Test 5, 2026-08-03) — plus CR 3.1 communication integrity, tested directly rather than assumed from the TLS channel (Test 6, 2026-08-03). - **CR 1.14:** violated by the original vulnerability; not applicable to the remediated design, which abandons symmetric-key auth rather than merely failing to secure it (corrected 2026-08-03 — "not met" overstated our own gap in the conservative direction). - **Both items from the 2026-07-31 "remaining" list are now closed** (Tests 5 and 6, 2026-08-03) — no soft cells left in this mapping as of this update. - **Test environment note:** every test here pins TLS 1.2 for deterministic failure timing and cleartext record-type visibility (Test 6's relay needs to identify record types) — a test-harness choice, not a deployment recommendation. Prefer the highest TLS version your devices support; see `README.md` Scope Boundaries. ## Evidence index (all re-runnable) - `test1_baseline_vulnerable.py` — no-auth baseline. - `test2_shared_secret_fails.py` — narrative bridge (the fleet-key *shape*; no evidential weight). - `test3_mutual_tls_fix.py` — per-device identity binding + negative control (case 4) + reverse (case 5), SAN not CN. - `test4_revocation.py` — CRL revocation: still-valid credential granted, then denied after its serial is revoked. - `test5_rotation.py` — rotation: a replacement credential is issued for the same identity; the prior one stays valid until explicitly retired (the control), then is denied; continuity holds throughout. - `test6_tamper_injection.py` — a record-level relay flips one bit in a live encrypted record; TLS's AEAD check rejects it (control: unmodified relay delivers the message intact). ## Sources (titles cross-checked; normative text = purchase the standard) - IEC 62443-4-2:2019, *Security for industrial automation and control systems — Part 4-2: Technical security requirements for IACS components.* Official sample: https://cdn.standards.iteh.ai/samples/21919/fe56b59fa6f04b849d88a2311aa5ec15/IEC-62443-4-2-2019.pdf - CR titles cross-checked against public summaries: https://www.keyfactor.com/blog/iec-62443-4-2-technical-security-requirements-for-iacs-components/ · https://cytal.co.uk/blog/iec-62443-4-2-component-security-requirements-and-how-to-meet-them/ - Rockwell PN1550 (CVE-2021-22681) + CISA ICSA-21-056-03 — see repo README citation block. *l0gic — Patrick Crosby, 2026-07-31. Verify all CR normative text against a purchased copy of IEC 62443-4-2:2019 before submission.*