HarpoS7 1.1.0-alpha3

This is a prerelease version of HarpoS7.
There is a newer version of this package available.
See the version list below for details.
dotnet add package HarpoS7 --version 1.1.0-alpha3                
NuGet\Install-Package HarpoS7 -Version 1.1.0-alpha3                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="HarpoS7" Version="1.1.0-alpha3" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add HarpoS7 --version 1.1.0-alpha3                
#r "nuget: HarpoS7, 1.1.0-alpha3"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install HarpoS7 as a Cake Addin
#addin nuget:?package=HarpoS7&version=1.1.0-alpha3&prerelease

// Install HarpoS7 as a Cake Tool
#tool nuget:?package=HarpoS7&version=1.1.0-alpha3&prerelease                

Logo

GitHub License Codecov GitHub top language Nuget

HarpoS7 is a C# library designed to authenticate sessions in the S7 Comm Plus protocol. It supports both legacy challenge authentication (found in projects made using TIA Portal V16 and older) and the more recent TLS authentication introduced in project made using TIA Portal V17 and newer.

HarpoS7 is intended for integration into other libraries and frameworks rather than as a standalone tool for end users.

Features

  • Fully managed
  • Supports challenge-based authentication (pre-V17 TIA portal)
  • Supports TLS authentication (post-V17 TIA portal)
  • Supports legitimation (password authorization) - requires testing

Tested on

  • S7-1200 (1214C DC/DC/DC, 214-1AG40-0XB0)
  • S7-PLCSIM V16 (PLC: S7-1200)
  • S7-PLCSIM V18 (PLC: S7-1500)

Getting started

For a comprehensive example of how to use HarpoS7, explore the HarpoS7.PoC project included in the repository.

This project provides a hands-on demonstration of how to integrate HarpoS7 into a sample application. Follow the example code and comments to fully understand how to use the library.

Public keys

Since 1.1.0 the default public keys are integrated into the library.

If you want to use a custom public key, you can implement your own IPublicKeyStore or pass in a raw public key to the Authenticate function directly.

Legacy auth sample

In order to authenticate a legacy session (challenge-based):

// The "input" buffers - you have to load/fill them yourselves
// The "output" buffers - the library fills them

// Input - challenge received from the PLC (20 bytes long)
var challenge = new byte[20];

// Input - public key used by the PLC (loaded from local storage, 
// can be identified by the fingerprint sent by the PLC)
var publicKey = new byte[64];

// Output - "Encrypted key" which you send back to the PLC (216 bytes long)
var keyBlob = new byte[Constants.FinalBlobDataLength];

// Output - Session key used later on to calculate packet integrity hashes (24 bytes long)
var sessionKey = new byte[Constants.SessionKeyLength];

LegacyAuthenticationScheme.Authenticate(
    keyBlob.AsSpan(),
    sessionKey.AsSpan(),
    challenge.AsSpan(),
    publicKey.AsSpan());

In order to calculate a packet digest (these are used to prevent tampering):

// Input - your packet data (without the S7-Header and S7-Trailer)
var data = new byte[dataLength];

// Input - session key (output from LegacyAuthenticationScheme.Authenticate)
var sessionKey = new byte[Constants.SessionKeyLength];

// Output - the packet data digest, usually placed in the S7-header
var digestBuffer = new byte[HarpoPacketDigest.DigestLength];

HarpoPacketDigest.CalculateDigest(digestBuffer.AsSpan(), data, sessionKey);

TLS auth

It is important to note that although TLS authentication is present in HarpoS7, it should be treated as a proof of concept rather than a ready-to-use solution.

The reason is that the implementation is simply the built-in SslStream wrapped around a primitive CotpStream.

Legitimation

It is possible to authorize with a password against a password-protected PLC. Keep in mind that this feature had even less testing than the authentication part.

In order to authorize with a password you need to firstly obtain a valid session (using TLS or legacy auth scheme). Then you need to get a legitimation challenge using a GetVarSubStreamed request (use Wireshark to know how). Finally you can pass everything down to the SolveLegitimateChallenge function.

Code:

using HarpoS7.Auth;

var blobData = new byte[LegitimateScheme.OutputBlobDataLength];
LegitimateScheme.SolveLegitimateChallenge(
    blobData, // OUT - send this with SetVarSubStreamed
    challenge, // IN - get this with GetVarSubStreamed
    publicKey, // IN - get this from a local storage by matching the fingerprint sent by the PLC
    sessionKey, // IN - generated by LegacyAuthenticationScheme.Authenticate (TODO: check TLS)
    "password"); // IN - password required by the PLC

Credits

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.1.0 116 8/26/2024
1.1.0-alpha3 80 8/15/2024
1.0.1 139 3/31/2024
1.0.0 115 2/11/2024

Real S7-1200/1500 support