Skip to content

Z-bit-Systems-LLC/OSDP-SC2-Benchmark

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OSDP-SC2-Benchmark

Command-line ACU that measures asymmetric pairing and OSDP-SC2 session performance against a peripheral device.

Overview

Bringing a PD onto a secure channel under OSDP-SC2 costs real time, and until it is measured there is no way to tell whether that cost sits in the post-quantum cryptography, the serial link, or the device's own processing. That distinction matters most on embedded hardware, where the wrong assumption leads to optimising the wrong thing.

OSDP-SC2-Benchmark acts as an ACU against a live PD and profiles two operations: the asymmetric pairing exchange (ML-KEM-768 key encapsulation and ML-DSA-44 signatures over osdp_PAIR), and repeated SC2 session establishment. Rather than reporting a single total, it breaks pairing into ten measured spans and attributes each to ACU cryptography, the serial link, or PD processing. Results are written as a Markdown report.

Key features:

  • Per-operation timing profile of the pairing exchange, rolled up by cost centre
  • Repeated SC2 session establishment with latency statistics
  • Reply-interval timing for osdp_ID, osdp_CAP and osdp_KEYSET on each session
  • Pairing fragment size derived from the PD's own reported receive buffer capability
  • Markdown report with the derivation and caveats stated inline
  • Offline self-test of the profiler's arithmetic

The tool targets the OSDP-SC2 Annex to the Open Supervised Device Protocol, adopted by the Security Industry Association to standardise access control hardware communication. SC2 replaces the AES-128 secure channel of OSDP v2.2 with AES-256-GCM and adds asymmetric pairing.

Development note: asymmetric pairing is experimental and not published to NuGet. This project references a local OSDP.Net checkout on the feature/osdp-sc2 branch. See Installation.

Supported Platforms

  • .NET 10.0
  • Windows and Linux (any platform with a serial port System.IO.Ports can open)

Requires a PD reachable over a serial connection. The PD must trust the OSDP.Net demonstration certificate authority for pairing to succeed.

Installation

No NuGet package is published. Build from source.

Prerequisites

  • .NET 10.0 SDK
  • A local clone of OSDP.Net on the feature/osdp-sc2 branch, checked out as a sibling directory. The project file references ..\OSDP.Net\src\OSDP.Net\OSDP.Net.csproj, and the OSDP.Net.Pairing namespace exists only on that branch.

Build

git clone https://github.com/Z-bit-Systems-LLC/OSDP-SC2-Benchmark.git
cd OSDP-SC2-Benchmark
dotnet build -c Release

If the build reports that OSDP.Net.Pairing cannot be found, the dependency is stale or on the wrong branch. Build it explicitly first:

dotnet build ../OSDP.Net/src/OSDP.Net/OSDP.Net.csproj -c Release -f net10.0

Quick Start

Run a full benchmark against a PD on COM3. Only --port is required.

dotnet run -c Release -- --port COM3

This runs three phases in order and writes benchmark-report.md:

  1. Interrogationosdp_ID and osdp_CAP in cleartext, which set the pairing fragment size
  2. Pairing — one asymmetric pairing exchange, profiled per operation
  3. SC2 — five session establishments, each issuing osdp_ID, osdp_CAP and osdp_KEYSET

Verify the profiler's arithmetic without any hardware:

dotnet run -c Release -- --self-test

Common Scenarios

Measuring an unpaired PD

Pairing succeeds only while the PD holds no secure channel. Once paired, the PD rejects the cleartext osdp_PAIR with NAK: CommunicationSecurityNotMet, because a PD with an established SC2 session NAKs every non-secure command. Reset the PD to its unpaired state before each run that measures pairing. This is why --pair-iterations defaults to 1: raising it requires a manual reset between trials, and without one every trial after the first fails.

A failed pairing attempt leaves no session behind, so a run that fails this way can be retried without another reset.

Benchmarking SC2 only, with a known key

If the SCBK is already known, skip pairing entirely. This needs no PD reset and can be repeated freely, which makes it the practical choice for comparing baud rates or PD firmware revisions.

dotnet run -c Release -- --port COM3 --mode sc2 --scbk 0123...ef --sc2-iterations 25

Controlling fragmentation

By default the pairing fragment size is derived from the PD's ReceiveBufferSize capability. That capability describes the whole OSDP packet, not the payload, so 32 bytes are reserved for framing — 5 header, 1 command code, 6 pairing multipart header and 2 CRC for a cleartext fragment, with the remainder covering a security block and GCM tag on a secured channel. A PD that reports no receive buffer size falls back to 1024 bytes.

# Override the derivation, e.g. to compare fragmentation strategies
dotnet run -c Release -- --port COM3 --fragment-size 256

Notes:

  • --fragment-size governs ACU to PD fragments only. The PD chooses its own reply fragment size, so the inbound pairing message is unaffected by this setting.
  • --acu-receive-size sends osdp_ACURXSIZE to advertise how large a packet the ACU can accept, which is the only ACU-side lever over PD-to-ACU fragmentation. A PD that does not implement the command NAKs it with Unknown Command Code; the run continues and the report records the failure.

Interpreting the report

The pairing profile attributes each span to a cost centre. Two of them need care:

  • ACU crypto is measured on the machine running the benchmark. It is a floor for the ACU side and says nothing about the PD.
  • PD turnaround is the gap between the ACU finishing a request and the first reply fragment arriving. It contains the PD's own work plus the bus polling interval, so it is an upper bound on PD processing rather than a measurement of it.

When the PD is a software simulator, every PD-side figure is a best case. Embedded hardware will be slower on those spans, while the serial-link spans carry over largely unchanged.

Core Concepts

Term Meaning
ACU Access Control Unit — the controller. This tool acts as one.
PD Peripheral Device — reader or controller being measured.
Pairing Asymmetric exchange (osdp_PAIR) that authenticates ACU and PD and derives an SCBK. Uses ML-KEM-768 and ML-DSA-44.
SCBK Secure Channel Base Key. 32 bytes under SC2.
SC2 OSDP-SC2 secure channel: AES-256-GCM with KMAC key derivation.
Fragment One chunk of a multipart message. Large pairing messages are split across many, each a separate command and reply.
Cost centre Attribution of a measured span to ACU crypto, serial link, PD processing, or bus overhead.

Advanced Usage

Options

Option Default Description
--port <name> required Serial port, e.g. COM3 or /dev/ttyUSB0
--baud <rate> 38400 Baud rate; must match the PD
--address <0-127> 0 PD address
--mode <both|pairing|sc2> both Which phases to run
--pair-iterations <n> 1 Pairing trials; >1 needs a manual PD reset per trial
--sc2-iterations <n> 5 SC2 session establishments
--fragment-size <n> derived Pairing fragment payload bytes, ACU to PD only
--acu-receive-size <n> 1440 Packet size advertised via osdp_ACURXSIZE; 0 skips
--pair-timeout <sec> 30 Per-pairing timeout
--sc2-timeout <sec> 15 Per-handshake timeout
--scbk <hex> Pre-shared 32-byte SCBK as 64 hex characters
--output <path> benchmark-report.md Report path
--self-test Verify profiler arithmetic and exit; no hardware needed
--help Show usage

Exit codes

Code Meaning
0 Run completed and the report was written
1 Usage error, or --help
2 Unhandled failure; the message and stack trace go to stderr

A run exits 0 even when trials fail. Failures are data, and the report records the success rate and a failure breakdown. Check the report rather than the exit code to judge a run.

How timings are captured

Pairing spans are derived from the IProgress<PairingProgress> reports that ControlPanel.PairDevice emits. The benchmark implements IProgress<T> directly rather than using System.Progress<T>, which marshals callbacks through the synchronization context or thread pool and would fold scheduling delay into millisecond-scale spans.

Those callbacks fire after a fragment's round trip completes, so a naive span boundary charges the first fragment to the preceding compute step. The profiler corrects this by moving the measured per-fragment mean back to the wire. Where a message produced only one callback there is no gap to measure, its wire time cannot be separated from the adjacent turnaround, and the report says so explicitly instead of reporting zero.

Error handling

Command failures during a session are recorded and the run continues, so one unsupported command does not discard an entire measurement:

try
{
    var identity = await controlPanel.IdReport(connectionId, address);
    timings.Add(new CommandTiming("osdp_ID", stopwatch.Elapsed.TotalMilliseconds, true, identity));
}
catch (Exception ex)
{
    // Record the failure as a data point rather than aborting the run
    timings.Add(new CommandTiming("osdp_ID", stopwatch.Elapsed.TotalMilliseconds, false,
        $"{ex.GetType().Name}: {ex.Message}"));
}

Testing and Development

The profiler's span arithmetic is verified against a synthetic exchange with hand-computed expectations, checking each span, the total, and that the spans reconcile with no gap or double-count:

dotnet run -c Release -- --self-test

Run this after changing the profiler. A real pairing measurement costs a manual PD reset to repeat, so the arithmetic is worth validating before spending one — the self-test has already caught a span origin error that a hardware run would have wasted a reset to discover.

Documentation

Roadmap

  • Baud rate sweep, the remaining ACU-side lever over inbound message time
  • Measurement against embedded PD hardware rather than a software simulator
  • Per-operation profiling of the SC2 handshake, currently measured end-to-end only
  • Optional true key rotation on osdp_KEYSET, which currently re-installs the same SCBK so the session stays usable for the next cycle

Contributing

We welcome contributions! Please:

  1. Submit pull requests against the main branch
  2. Follow existing code style and conventions
  3. Include tests for new features
  4. Update documentation as needed

For collaboration inquiries or questions, contact us through Z-bit Systems, LLC.

Hardware Vendor Collaboration

We encourage OSDP hardware vendors to use this project to characterise SC2 and pairing performance on their devices. Core functionality is under an open source license to help increase adoption rates of OSDP-SC2. Contact Z-bit Systems, LLC for inquiries regarding commercial integration or custom development.

License

This project is licensed under the Apache 2.0 License - see the LICENSE file for details.

Acknowledgments

Support

For questions, issues, or feature requests:


About Z-bit Systems, LLC

Z-bit Systems specializes in access control systems, physical security integration, and enterprise security software solutions. We provide commercial support, custom development, and consulting services. Learn more at z-bitco.com.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages