Documentation

OSDP Secure Channel

OSDP uses AES with a key size of 128 bits (16 bytes). The Secure Channel (SC) session is initiated by the CP, and either side can invalidate an established session (PD by sending a NAK, CP by starting a new SC handshake). This document explains the secure channel workflow to help application developers understand failure logs emitted by LibOSDP.

LibOSDP has a working implementation of the secure channel. Any CP/PD using this library will advertise this as an implicit capability. To disable secure communication (e.g. for debugging), call osdp_pd_set_capabilities() after osdp_setup() and set the compliance level of OSDP_PD_CAP_COMMUNICATION_SECURITY to 0.

Secure Channel Session

A SC session is initiated with a handshake involving 2 command-reply transactions between the CP and PD. Once established, a session can be kept active indefinitely until either party discards it or a timeout (400 ms) occurs.

The CP starts by sending CMD_CHLNG, to which the PD replies with REPLY_CCRYPT. With this response the CP authenticates the PD and computes its session keys. Next, the CP sends CMD_SCRYPT, which the PD uses to authenticate the CP and compute its session keys. If all goes well, both CP and PD will have a working set of session keys (s-enc, s-mac1, and s-mac2). The final message of the handshake is the REPLY_RMAC_I response from the PD, which carries the initial reply MAC the CP will use as the IV for encrypting its next command (MAC chaining).

This process works if both the CP and PD have the same SCBK. If there is a mismatch, the CP will fail to verify the PD's authenticity when it receives REPLY_CCRYPT. At that point, LibOSDP will try a new SC handshake with SCBK-default to check if the PD is in install-mode. If that also fails, the CP goes online without a secure session and retries every 10 minutes.

Note: This is the default behavior. With ENFORCE_SECURE enabled, the behavior changes (see below).

SCBK (Secure Channel Base Key)

This is the primary key used to derive the secure channel session keys. When setting up a CP or PD, pass the SCBK in osdp_pd_info_t::scbk.

If osdp_pd_info_t::scbk is NULL:

  • In PD mode: the PD is forced into install mode.
  • In CP mode: the PD is set up with secure channel disabled (plaintext).

Note: LibOSDP no longer supports master-key based SCBK derivation. Each PD must be configured with its own SCBK directly; the CP is responsible for maintaining the per-PD SCBKs, as recommended by the OSDP specification.

Install Mode

Install mode is a provisioning-time, insecure mode that instructs the PD to use SCBK-Default (a hardcoded key defined by OSDP) and allows the CP to set a new SCBK. Once the PD receives a new SCBK, it automatically exits install mode, preventing another SCBK key set.

Enable install mode by passing OSDP_FLAG_INSTALL_MODE in osdp_pd_info_t::flags. Do not pass this flag during normal operation.

Entering Install Mode

If you are building a PD as a product, you'll need a method to force the PD into install mode during provisioning to allow the CP to set a new SCBK.

A simple approach is a pin-hole tactile switch that, when pressed during reboot, causes your application to pass the OSDP_FLAG_INSTALL_MODE flag.

This is not very secure since an attacker with physical access can do the same. More secure alternatives include special configuration cards presented to an RFID reader soon after boot to trigger install mode (as some HID devices implement).

On the CP side, keying the SCBK while a PD is in install mode is what Osprio Provisioner automates — it sets the new SCBK over a controlled point-to-point link and verifies it with a fresh secure-channel handshake before the PD is handed to the production bus.

The ENFORCE_SECURE Flag

Enforce Secure is a LibOSDP flag introduced due to the insecure nature of install mode. A CP/PD instructed to use this flag operates with stricter security, disallowing certain OSDP features such as install mode.

When ENFORCE_SECURE is enabled:

  • Secure Channel cannot be disabled
  • The CP/PD will not operate without a secure channel if setup fails
  • SCBK-Default (install mode) is not allowed

When you see a "... due to ENFORCE_SECURE" failure message in the logs, the CP/PD attempted an action that LibOSDP deemed a protected operation requiring supervision.

Persistence of Keys

LibOSDP does not retain the SCBK across power cycles. The application is responsible for storing and providing the correct SCBK on each call to osdp_cp/pd_setup().

In CP mode, the CP owns the SCBK, so the CP app already has the key. In PD mode, when the PD receives a new SCBK from the CP, the PD app gets a copy in the OSDP_CMD_KEYSET callback.

Random Number Generation

The secure channel handshake mixes a random nonce from each side into the session keys, so the strength of the secure channel depends on the quality of that randomness. You are responsible for ensuring your hardware has a cryptographically strong random source.

Where the randomness comes from depends on the crypto backend:

  • OpenSSL / MbedTLS: nonces are drawn from the crypto library's CSPRNG, which is seeded from the operating system's entropy source. No extra work is needed on hosted platforms.
  • TinyAES (bundled fallback): nonces come from the platform's rand_u32(). This is only as strong as the underlying source — on hosted builds it falls back to the C library's rand(), and on some microcontrollers it is a boot-seeded PRNG. Neither is suitable for production secure channel use.

On any target without a hardware TRNG wired in, override rand_u32() with a real entropy source before deploying secure channel. See Porting to a New Platform for how the platform hooks are provided.