1. Overview: The Change-Detection Problem in Fielded PLCs
Once a SIMATIC S7-1200 or S7-1500 controller leaves engineering and enters the field, the program on the CPU is exposed to several change vectors: integrator modifications, plant electrician tuning, OEM retrofits, post-warranty changes, and rollback-to-original after a fault. When a downstream machine fails, the first engineering question is almost always the same: what does the loaded program look like compared to the released baseline? TIA Portal does not store a full native version-control graph inside the CPU, so the protection and detection strategy must be engineered explicitly across four layers: block-level encryption, CPU access control, physical media protection, and runtime telemetry (checksum + datalog).
This reference consolidates the field-proven mechanisms documented in the SIMATIC S7-1200 programmable controller system manual and the TIA Portal programming and operating manual. The goal is a layered model that (a) prevents casual modification, (b) detects modification when it occurs, (c) records who/when/which block was touched, and (d) survives a rollback where the same program is re-downloaded in an attempt to erase evidence.
2. Layered Protection Model
Use all four layers in combination. A single layer is bypassed in minutes; the combination is the practical deterrent.
| Layer | Mechanism | What It Stops | Residual Risk |
|---|---|---|---|
| L1 – Block | Know-how protection with password | Reading block logic, partial copy | Block can still be overwritten online with correct CPU password |
| L2 – CPU | Access level 1–4, HMI/Read/Write/No-access passwords | Online edits, firmware download, card read/write | Lost password requires MMC wipe (S7-1500) or SMC wipe (S7-1200) |
| L3 – Physical | Sealed SMC slot, locked cabinet, tamper-evident labels | Card swap, secret-card download, offline attack | Does not stop online edits over Ethernet/PROFINET |
| L4 – Runtime | GET_CHECKSUM, DataLog, file on SMC, HMI audit | Silent modification, rollback, unrecorded edits | Can be deleted by attacker with full CPU write access |
3. L1 – Know-How Protection (Block-Level Encryption)
Know-how protection encrypts the compiled block on the CPU and in the offline project. The S7-1200 system manual (article ID 109751634) and the TIA Portal help describe the procedure:
- Right-click the block (FB, FC, OB, DB) in the project tree.
- Select Properties → Protection.
- Check Know-how protection, enter a password (≥ 1 char, recommended ≥ 12 with mixed case + symbol).
- Compile the project. The block is encrypted on download; the CPU will not return the compiled code on upload without the password.
For an S7-1500 (T-CPU), a second tick box enables Block Privacy, which additionally prevents the CPU from displaying the block interface to other engineering tools over the network. This is documented in the S7-1500 system manual at SIMATIC S7-1500 / ET 200MP system manual.
| Property | S7-1200 | S7-1500 |
|---|---|---|
| Block encryption (know-how) | Yes | Yes |
| Block privacy (anti-probe) | No | Yes (firmware ≥ V2.0) |
| Anti-debug / anti-trace | No | Yes (firmware ≥ V2.6 with T-CPU option) |
| Copy protection tied to serial | No (block tied to project serial only) | Yes (CPU serial binding optional) |
Know-how protection does not prevent an authorised user with the CPU write password from overwriting the block. Its role is to make reverse engineering harder, not to block modification. This is why it is layer 1, not the only layer.
4. L2 – CPU Access Levels and Passwords
Configure the protection levels in Devices & Networks → PLC → Properties → Protection & Security in TIA Portal. The CPU ships with the full access level and no password; you assign at least one password and reduce the access level to the lowest the operator's role requires.
| Level | Name | Online Capabilities (S7-1200/1500) |
|---|---|---|
| 1 | No access (Complete protection) | HMI access only, no read or write from engineering |
| 2 | Read access | Read diagnostics, identify, compare; no write |
| 3 | HMI access | Read + HMI tags; no firmware download, no program write |
| 4 | Full access (no password) | Read, write, format SMC, download firmware |
For warranty and rollback scenarios, the practical configuration is:
- Level 1 with one password held only by the OEM/integrator.
- Level 3 with a separate password for the end-user HMI and tag read/write.
- Level 4 left empty (no password) only for the brief commissioning window, then disabled.
Password rules: minimum 4 characters per TIA Portal, but a strong password follows the project password policy: ≥ 12 characters, mixed case, digit, symbol. Store the password in a sealed envelope inside the cabinet and in the OEM's password vault. The S7-1200 stores the password hash in non-volatile memory; a forgotten password for S7-1500 requires a manufacturer reset with a SIMATIC memory card created in TIA Portal, which wipes the program. For S7-1200 the procedure is similar (SMC reset to factory).
5. L3 – Physical SMC and Cabinet Protection
The SIMATIC Memory Card (SMC) on the S7-1200 and the SIMATIC Memory Card on the S7-1500 contain the project when the CPU is in card operation mode. An attacker with physical access to the card can:
- Pull the card.
- Insert it in a card reader.
- Browse, copy, or modify the files (the S7-1200 stores blocks in
SIMATIC.S7S/FWUPDATE.S7Sformat that is partly documented). - Reinsert the modified card; the CPU boots from the card.
Mitigations:
- Apply a tamper-evident serialized security seal across the SMC slot cover and the housing seam. Photograph the seal at commissioning; store the photo in the project archive.
- Lock the cabinet. Use a key that is keyed-alike to other plant cabinets only if cross-access is acceptable; otherwise use an OEM-only key.
- For S7-1500, enable Know-how protect with copy protection (CPU serial binding): the block is encrypted with the serial number of the target CPU and will not run on any other CPU. This is set in the block's Protection properties.
- Disable the card reader on the CPU if the model supports it (S7-1500 CPUs above a certain FW revision disable card write while RUN is active).
6. L4 – Runtime Change Detection
This is the layer that answers the original question: how do I know if anything changed, and when, even if the original program was reloaded?
6.1 GET_CHECKSUM Instruction
The GET_CHECKSUM (or GetChecksum) instruction returns a 32-bit CRC of a block's runtime image. It is available in the S7-1200/1500 instruction set. Place the call in OB1 (or a cyclic OB) inside a know-how protected FB so the attacker cannot see what is being measured.
// FB "AuditCrc" (know-how protected)
// Inputs : i_blockNo : INT // block number to check
// Outputs: o_crc : DWORD // returned CRC
// o_chgFlag : BOOL // edge-detected change
#instGetChecksum (REQ := TRUE,
BlockNo := #i_blockNo,
RET_VAL := #status,
CHECKSUM := #o_crc);
IF #firstRun THEN
#storedCrc := #o_crc;
#firstRun := FALSE;
END_IF;
IF #o_crc <> #storedCrc THEN
#o_chgFlag := TRUE; // edge – latch on change
#storedCrc := #o_crc; // update for next scan
END_IF;
Parameters:
| Parameter | Type | Meaning |
|---|---|---|
| REQ | BOOL | Trigger – use TRUE for cyclic, FALSE for one-shot via edge |
| BlockNo | INT | Block number (e.g. 1 for OB1, 100 for DB100). 0 returns the checksum of the OB currently being executed. |
| RET_VAL | INT | Status: 0 = OK, 1 = block does not exist, 8090 = block in EPROM, 8091 = know-how protected |
| CHECKSUM | DWORD | Returned 32-bit CRC. Changes whenever the block is recompiled, replaced, or modified online. |
Cycle the call across all critical blocks (FBs, FCs, DBs, OBs that contain safety or control logic). Store the captured CRC in a retentive DB so a power cycle does not reset the baseline. The detection survives a rollback only if the stored CRC is on a media the attacker cannot easily modify — see §6.3.
6.2 Change Log via DataLog
Use the DataLogCreate, DataLogWrite, and DataLogClose instructions to append a record every time the CRC differs from the previous value. The S7-1200 system manual describes DataLog as a way to write CSV-formatted records to the SMC.
// On rising edge of #o_chgFlag
"dlgCreate"(REQ := FALSE); // create once at first run
"dlgOpen" (MODE := APPEND);
"dlgWrite" (REQ := TRUE,
ID := "dlgId",
DATA := [#i_blockNo, #o_crc, #storedCrc, RTC()); // block, new, old, timestamp
DONE => #writeDone,
ERROR => #writeErr);
"dlgClose" ;
Fields recorded:
-
BlockNo– which block changed -
NewCrc– new CRC -
OldCrc– the CRC that was stored before -
Timestamp– read from the CPU real-time clock (DTL fromRD_SYS_T)
The DataLog file resides on the SMC and is therefore subject to the same physical protection as the program (L3). An attacker with cabinet access and the card reader can delete the log; that is why L4 is layered with L3, not a replacement.
6.3 External Storage of the Baseline
To survive a rollback attack where the attacker re-downloads the original program, the baseline CRC must be stored where the attacker cannot write to it. Options, in order of robustness:
-
External server (push). On every CRC mismatch, push the change record to a plant historian (WinCC, OPC UA server, MQTT broker) over the CPU's integrated PROFINET interface. The CPU web server can be configured to issue an HTTP POST; alternatively, use a
TSEND_Cinstruction to send a UDP frame to a syslog daemon. Configure in Devices & Networks → PLC → Properties → Web server or in theTSEND_Cconfiguration. - Operator panel recipe. A WinCC Comfort/Advanced recipe slot can hold the baseline CRC and a comment. Recipes are user-editable; this is appropriate for warranty documentation but not tamper-proof.
- Sealed paper printout. Print the CRC of every block at commissioning, sign, seal, and file in the OEM archive. Not searchable but legally robust.
- SIMATIC Automation Tool audit. The SIMATIC Automation Tool can read block CRCs over the network and compare against a stored manifest. Run it on a schedule from a separate engineering workstation.
6.4 Email Notification on Change
Use the S7-1200/1500 web server's "User-defined pages" and the EMAIL function block in the TIA Portal library to send an SMTP message when the change flag is set. Configure in CPU Properties → Web server → User-defined pages and use a TIA Portal Email FB from the "Communication" palette. Required parameters:
| Field | Value |
|---|---|
| SMTP server | Plant mail relay (e.g. 10.0.0.25) |
| Sender | [email protected] |
| Recipient | [email protected] |
| Subject | Program change detected on %CPU_NAME% |
| Body | Block, old CRC, new CRC, timestamp, plant tag |
7. Detecting a Rollback to the Original Program
Rollback detection is the hardest case: the program bytes on the CPU are now identical to the released baseline, yet the change history is still real. Use out-of-band evidence:
-
Modification counter. A retentive counter (
CTUinstance in a protected FB) is incremented on every detected change. A subsequent re-download of the original program does not decrement it. The counter value, read at the next warranty service, reveals the total number of change events. - Last-event timestamp. Store the RTC value of the last detected change in a retentive DB and additionally in the HMI recipe (see §6.3.2). Even after a rollback, this timestamp persists.
- External push of change events. If every change event was pushed to the historian (§6.3.1), a rollback cannot erase it.
-
File system signature. On the SMC, write a marker file (e.g.
OEM_BOOT.S7S) at commissioning that contains the signed CRC list. A subsequent card swap leaves the file system modification date of the SMC folder intact, which is visible in TIA Portal Online & Diagnostics → Memory.
8. Standard Program vs. Safety Program
Safety programs (F-CPU, F-blocks) have a separate compilation that is signed by the safety administrator's password. The F-signature is stored in the safety program and can be read with the GetFCheckSum instruction on S7-1200F / S7-1500F CPUs. The procedure for change detection on F-blocks is:
- Read the F-signature with
GetFCheckSum(see S7-1200F/1500F system manuals). - Compare to the value stored in a protected DB at the safety acceptance test.
- Any change to an F-block invalidates the F-signature and forces a re-acceptance test by the safety administrator.
For safety blocks, the F-signature provides a built-in mechanism that the standard program lacks. Use the same L4 telemetry (GET_CHECKSUM, DataLog) for non-safety blocks; rely on the F-signature plus the safety password for F-blocks.
9. Commissioning Procedure
- Compile the final program. Record the SHA-256 (or any hash) of the
.ap15/.ap17project file in the project archive. - For every critical block, record the CRC returned by
GET_CHECKSUM. Store in a CSV that is the project's CRC manifest. - Take a photograph of the SMC slot and cabinet seal. File the photo in the project archive.
- Set all CPU access levels except the operator (HMI) level. Document which level is assigned to which role.
- Apply know-how protection to the audit FB, the audit DB, and any block containing calibration constants.
- Test the change detection: modify a non-critical DB online, verify the change flag rises, verify the DataLog appends a row, verify the email is sent (if configured).
- Restore the DB to its released value, verify that the stored CRC is updated and no further email is sent, and verify the modification counter and last-event timestamp persist.
- Sign and date the CRC manifest. File in the project archive and the OEM warranty system.
10. Verification Checklist
| # | Check | Pass Criteria |
|---|---|---|
| 1 | Online edit to a non-critical DB | Change flag rises; DataLog row appended; email sent within 60 s |
| 2 | Reload of original program | Modification counter does not decrement; last-event timestamp persists |
| 3 | Removal of SMC | Visible breakage of tamper seal recorded in service log |
| 4 | Try to upload know-how protected block without password | CPU returns error; block contents not visible in TIA Portal |
| 5 | Try online edit with operator-level password | TIA Portal returns access denied |
| 6 | Audit FB deleted online | Subsequent re-download of program resets the block; the modification counter reverts to zero — document this as a known gap and re-seal |
| 7 | CPU clock drift | DataLog timestamps are within ±1 s of NTP (configure time sync via NTP in CPU properties) |
11. Troubleshooting Matrix
| Symptom | Likely Cause | Resolution |
|---|---|---|
| GET_CHECKSUM returns 8091 | Block is know-how protected, runtime cannot hash it | Exclude that block from the audit list or accept that its CRC is opaque |
| GET_CHECKSUM returns 8090 | Block is loaded from EPROM / card without RAM copy | Force the block to be resident in work memory (S7-1500: block property "MC7+ code in work memory") |
| DataLog write fails with status 80A1 | SMC full or write-protected | Check SMC capacity; remove write protection tab on the card |
| Email not sent | SMTP authentication, port 25 blocked, DNS not configured | Verify with TCON/TSEND_C test; check IT firewall |
| CRC differs every cycle | Block is being edited live; expected during commissioning | Accept as noise during commissioning; do not alarm |
| Modification counter always 0 | Retain attribute not set on the audit DB | In DB properties, set Retain = Set in IDB for the counter tag |
| Time stamp stuck at 1990-01-01 | CPU battery low or RTC not set | Replace battery; configure NTP or set time at every startup via WR_SYS_T
|
12. Notes for the Warranty Rollback Scenario
The original post asked specifically: a company makes a change, something breaks, they reload the original program, how do we detect that a change was made and what it was? The honest answer is that you cannot fully recover the content of the change once the original is reloaded — the program bytes are now the released baseline. What you can recover, with the architecture above, is:
- The fact that a change occurred (modification counter).
- The block that was changed (logged in the DataLog or historian).
- The timestamp of the change.
- The user account that downloaded the program, if the change was made via TIA Portal (the CPU's Diagnostic buffer records the download with the engineering station's identifier).
Forensic recovery of the actual code change requires a third-party source: the integrator's version-control system (if they used one), the engineering station's TIA Portal project history, or the original change request. The PLC itself is the wrong place to look after a successful rollback. Therefore, in addition to the runtime audit, the OEM should require that the integrator commit each change to a source-control system (e.g. TIA Portal multiuser, or external Git) and link it to the CRC manifest. The combination of runtime audit (catches the change) and source-control (catches the content) is what closes the loop.
13. FAQ
Does know-how protection stop online modification of a block?
No. Know-how protection prevents the compiled block from being read on the CPU, but a user with the correct CPU write password can still overwrite the block online. Use CPU access levels (L2) to stop the modification itself, and know-how protection (L1) only to stop reverse engineering.
How do I detect that the program was changed even if the original was reloaded?
Use a retentive modification counter in a know-how protected FB and push change events to an external historian or email server. The counter and the event log persist across a rollback because the CPU is not aware they should be reset; only an attacker who knows about them and has full CPU write access can erase them.
Can I read the CRC of a know-how protected block with GET_CHECKSUM?
No. GET_CHECKSUM returns the error code 8091 (block is know-how protected) on the S7-1200/1500. Exclude such blocks from the audit or treat their CRC as opaque. The safety signature on F-CPUs (GetFCheckSum) is the equivalent mechanism for F-blocks.
Where should the audit FB live so that an attacker cannot delete it?
On an F-CPU, embed the counter in the safety program — deleting the FB invalidates the F-signature and forces a re-acceptance test. On a standard CPU, store the counter and timestamp on an external HMI or push to a server, because any FB on a standard CPU can be deleted by a user with full access.
What is the difference between the CPU access levels and the know-how protection password?
The CPU access-level password gates what an engineering tool can do over the network (read, write, download firmware). The know-how protection password gates what the engineering tool can see inside a block. Both are required: access level without know-how still allows uploading and reading the logic; know-how without access level still allows online modification.