16. Pre-Shared Key Protection
This chapter describes Pre-Shared Key Protection, which expands and unifies Security Plugins entry-level protection. Pre-Shared Key Protection is a Cryptography Plugin mechanism that supports basic communication protection. It is based on a PSK (a pre-shared, user-configurable key seed) distributed out-of-band to DomainParticipants. Pre-Shared Key Protection does not require (but can be used in combination with) authentication and does not provide (but can be used in combination with) sophisticated security features such as granular security and topic permissions enforcement. Pre-Shared Key Protection offers metadata and data protection on the wire and restricts communication only to DomainParticipants holding the correct PSK.
Pre-Shared Key Protection can be leveraged in two different ways:
As part of the Builtin Security Plugins: Pre-Shared Key Protection works alongside existing Builtin Security Plugins features and secures the communication happening before and during authentication (known as bootstrapping, see Protecting Bootstrapping). Note: While RTPS Bootstrapping messages can only be protected through Pre-Shared Key Protection, non-bootstrapping messages can be protected either with a combination of Pre-Shared Key Protection with other security mechanisms from Builtin Security Plugins, or using non-Pre-Shared Key Protection mechanisms exclusively.
As part of Lightweight Builtin Security Plugins: In this case, all traditional DDS Security mechanisms are disabled and the entire communication is protected with Pre-Shared Key Protection. Lightweight Builtin Security Plugins is described in detail in The Lightweight Builtin Security Plugins. Note: since Pre-Shared Key Protection by itself does not support granular security or topic permissions, Lightweight Builtin Security Plugins can only be used to provide domain-Level protection from outsider adversaries (see Domain-Level Protection From Outsider Adversaries).
16.1. Pre-Shared Key Protection Motivation and Benefits
Pre-Shared Key Protection expands the Connext security offering and enables basic-level protection wherever traditional DDS Security mechanisms are unavailable or infeasible due to limited resources, paramount performance requirements, or other reasons. The PSK secures all the traffic from the start-up of a DDS Entity and restricts the communication only to Entities holding the correct pre-shared key seed.
16.1.1. Pre-Shared Key Protection in Lightweight Builtin Security Plugins vs. Pre-Shared Key Protection in Builtin Security Plugins
Pre-Shared Key Protection uses the same mechanism in both Lightweight Builtin Security Plugins and the Builtin Security Plugins, and offers the same level of protection. The difference is in the PSK area of responsibility.
Pre-Shared Key Protection within the Builtin Security Plugins secures all communication that occurs before two DomainParticipants authenticate each other. Once authentication completes successfully, more sophisticated Builtin Security Plugins features (such as enforcement of permissions at the topic-level) can be used. Authentication itself is also protected with the PSK. In this setting, Pre-Shared Key Protection complements more advanced mechanisms and secures potentially sensitive information exchanged to bootstrap the DDS system (such as topic names in the Permission Document, locators in SPDP messages, or Participant User QoS propagated information), which would otherwise be vulnerable to tampering and visible to unauthorized parties. Pre-Shared Key Protection also provides an additional mitigation for potential vulnerabilities in the participant discovery process.
Lightweight Builtin Security Plugins are provided as a separate library. It supports Pre-Shared Key Protection only and the entire communication is protected with it. More sophisticated security mechanisms are unavailable. Lightweight Builtin Security Plugins are recommended in systems that do not require granular security, sophisticated authentication and permission management, but are resource-limited or demand high performance and low latency.
Lightweight Builtin Security Plugins and Builtin Security Plugins can interoperate if configuration allows - see the configuration section below for details.
16.2. Configuring Pre-Shared Key Protection
Note
All Builtin Security Plugins- and Lightweight Builtin Security Plugins-related properties must be prefixed with
com.rti.serv.secure., assuming you used com.rti.serv.secure
as the alias to load the plugin. If not, change the prefix to match the string
used with com.rti.serv.load_plugins, followed by the .
character.
The following properties are important for successfully configuring the Pre-Shared Key Protection:
The required property
dds.sec.crypto.rtps_psk_secret_passphrasesets the value of the pre-shared key passphrase and enables Pre-Shared Key Protection. See Table 6.8 for the formats for this property.Both the key passphrase and the unique key identifier must be consistent across all DomainParticipants in the system. The key passphrase, combined with public information, is used to produce the key that is used to encrypt and decrypt RTPS messages. You can change this property at runtime, and the unique key identifier is used to determine if the correct key revision is used by different DomainParticipants. You have to manually update the key for all DomainParticipants in the system. Until the key is updated across the system, decryption errors will occur if
dds.sec.crypto.rtps_psk_secret_passphrase_extrais not used.The
dds.sec.crypto.rtps_psk_symmetric_cipher_algorithmoptional property determines the algorithm used to protect RTPS messages and the key bit-length. The available options areAES256+GCM(default),AES128+GCMandSM4+GCM(exclusively in Lightweight Builtin Security Plugins).The Pre-Shared Key Protection can be configured to protect RTPS message integrity (GMAC variant) or both integrity and confidentiality (GCM variant). In the Builtin Security Plugins, to specify the variant, set
rtps_psk_protection_kind(see rtps_psk_protection_kind (domain_rule)) in the Governance Document to eitherENCRYPT(GCM) orSIGN(GMAC). In the Lightweight Builtin Security Plugins, configuration can be done analogously through thedds.sec.access.rtps_psk_protection_kindproperty.The optional
dds.sec.crypto.rtps_psk_secret_passphrase_extraproperty configures an additional passphrase that can be used for decoding incoming RTPS messages only. It can be used, in addition todds.sec.crypto.rtps_psk_secret_passphrase, if there is a requirement for a seamless transition to a new passphrase. See section Updating the PSK Passphrase Without Message Loss for more information.
For more information about these properties, see Table 6.8.
16.2.1. Lightweight Builtin Security Plugins and Builtin Security Plugins Interoperability
Lightweight Builtin Security Plugins can interoperate with Builtin Security Plugins if all of the following is true:
The Builtin Security Plugins Governance Document is configured with
allow_unauthenticated_participants=TRUE,rtps_protection_kind=NONEandenable_key_revision=FALSE. Lightweight Builtin Security Plugins do not support authentication and their RTPS messages are protected with PSK, which is incompatible with RTPS Origin Authentication Protection. See Participant-Level Permissions, Endpoint-Level Permissions, and Unsecure DomainParticipants and Origin Authentication Protection for details.The Builtin Security Plugins and the Lightweight Builtin Security Plugins are configured with the same value of the
dds.sec.crypto.rtps_psk_symmetric_cipher_algorithmproperty.The value of the
dds.sec.access.rtps_psk_protection_kindproperty in the Lightweight Builtin Security Plugins is the same as the value of thertps_psk_protection_kindGovernance Rule in the Builtin Security Plugins’s Governance Document.
Note
When the Builtin Security Plugins and the Lightweight Builtin Security Plugins interoperate, topics that have metadata or data protection kinds enabled (features specific to the Builtin Security Plugins) are unavailable to the Lightweight Builtin Security Plugins.
16.3. How Pre-Shared Key Protection Works
16.3.1. PSK Material
Pre-Shared Key Protection relies on deriving unique symmetric keys for every DomainParticipant. The keys are based on a user-configurable, pre-shared secret passphrase (common for all DomainParticipants) and publicly available data that uniquely identifies a DomainParticipant in the network. Thanks to this architecture, every DomainParticipant with the right pre-shared passphrase can recreate the unique key material (Master Sender Salt and Master Sender Key) of any other DomainParticipant in the network without the need for costly key material exchange. The key material is used as an input parameter for a cryptographic algorithm to encrypt or MAC RTPS messages.
The 256-bit long Master Sender Salt is derived according to this algorithm:
HMAC-<HASH>(
HMAC-<HASH>(
concatenate("PSK-SALT", sender's key identifier, target's RTPS header),
pre-shared secret passphrase),
concatenate("master salt derivation", 0x01))
The 256-bit long Master Sender Key is derived according to this algorithm:
HMAC-<HASH>(
HMAC-<HASH>(
concatenate("PSK-SKEY", sender's key identifier, target's RTPS header),
pre-shared secret passphrase),
concatenate("master sender key derivation", 0x01))
In both cases, the sender’s key identifier consists of four bytes calculated according to this algorithm:
First three bytes:
HASH-<HASH>(concatenate("DomainId=", DomainId, ";DomainTag=", DomainTag))
Last byte:
Least-significant byte of the passphrase identifier (<passphrase_id>).
where:
The domain identifier is given as a string containing the Domain’s decimal representation.
The domain tag is the string that the encoding DomainParticipant propagates during Participant Discovery, and matches the value of its
dds.domain_participant.domain_tagproperty.The pre-shared secret identifier is an index that selects a single key from a configuration that specifies multiple pre-shared keys. In particular, the pre-shared secret id matches the <passphrase_id> value specified as part of the
dds.sec.crypto.rtps_psk_secret_passphraseproperty.There is no NULL terminator at the end of the concatenated strings that we use as input for the hashing algorithm. There is also no NULL terminator at the end of the DomainId and DomainTag strings.
<HASH> denotes the hashing algorithm used by the HMAC algorithm. The Security Plugins use two different hashing algorithms:
SHA256(Builtin Security Plugins and Lightweight Builtin Security Plugins) andSM3(Lightweight Builtin Security Plugins only). The hashing algorithm is selected with the symmetric cipher algorithm through thedds.sec.crypto.rtps_psk_symmetric_cipher_algorithmproperty.SHA256is coupled with any AES algorithm, andSM3is tied toSM4+GCMalgorithm. Both algorithms produce a 256-bit long digest.
Note
The uniqueness of every DomainParticipant’s key material is important to ensure a high level of security. No two DomainParticipants can have the same key. The algorithm’s goal is to ensure reliable and fast protection against external threats, and that no external party can forge the key material without knowledge of the pre-shared key seed. It is not the intent of this mechanism to protect against insider spoofing. If insiders are not fully trustworthy, use a different mechanism from the Builtin Security Plugins portfolio.
16.3.2. Key Management
A PSK-enabled DomainParticipant, upon its creation, derives its own key material which is stored and readily available for later use. Whenever it wants to communicate with another DomainParticipant, it applies the chosen protection (encryption or MAC) to the outgoing message, using its pre-calculated key material. The recipient of the PSK-protected message can quickly determine that the message is PSK-protected by checking the submessage flags in the RTPS Crypto Header. If the message is determined to be PSK-protected, the receiving DomainParticipant checks if its internal storage has the key corresponding to the RTPS Header received in the message. If so, it uses that key to decode or verify the message. If the key is not found in the list, the receiving DomainParticipant derives the key using the algorithm and puts it in the list.
Note
The remote DomainParticipants’ keys are stored in a list of a fixed size (10 slots) during their initial discovery. Whenever all available key slots are used and a “new” remote DomainParticipant is encountered, the oldest entry in the list is replaced with the newly derived one. This mechanism may have a considerable performance impact whenever we discover a number of nodes exceeding the number of slots in the list within a short time - the recipient would end up recalculating the keys frequently. After remote DomainParticipants discovery is complete, this limitation no longer exists since the keys are no longer stored in the list.
16.3.3. Passphrase Identifier
The dds.sec.crypto.rtps_psk_secret_passphrase property that the user
sets consists of a passphrase identifier and a passphrase. Both the passphrase
identifier and the passphrase are used to derive the key material. As seen in
PSK Material, only the least-significant
byte of the passphrase identifier is used in the key derivation process (and the
0xFF value is not allowed). We will refer to this byte as the passphrase key
identifier:
PassphraseKeyId = PassphraseId & 0xFF
The first three bytes are called the passphrase key revision:
PassphraseRevision = (PassphraseId 0xFFFFFF00) >> 8
They are used to increase the range of passphrases, and help preventing id collisions. A DomainParticipant will attempt to decode an RTPS message only if it has both the key identifier and the key revision identical to the locally stored ones.
The passphrase key identifier and the passphrase key revision are propagated in the transformation_id part of the Crypto Header (see Cryptographic Information Added to RTPS Messages). In particular, the passphrase key identifier is sent as the last byte of the transformation_key_id. The passphrase key revision is sent as the first three bytes of the transformation_kind.
16.3.4. Pre-Shared Key Protection and the Cloud
Pre-Shared Key Protection is the primary security mechanism for Connext cloud deployments, and can be employed to protect the discovery data and Binding Ping in RTI Cloud Discovery Service and RTI Real-Time WAN Transport. For a detailed description of these environments and configuration information see Support for RTI Real-Time WAN Transport.
When Pre-Shared Key Protection is enabled, Participant Discovery messages’ serialized data is no longer protected using the TrustedState mechanism (see Protecting Participant Discovery). Instead, the Builtin Security Plugins protect the whole Participant Discovery message (including replay attack protection information described in Protection Against a Cloud Discovery Service Participant Announcement Replay Attack). TrustedState is disabled when Pre-Shared Key Protection is enabled for the following reasons:
One of the main use cases of Pre-Shared Key Protection is to secure cloud deployments.
RTI Cloud Discovery Service-based deployments are not compatible with enforcing TrustedState or protecting Participant Discovery messages’ serialized data with the original Participant Private Key Signature (used to sign the TrustedState).
Pre-Shared Key Protection provides better protection against attacks from DDS domain outsiders (i.e. malicious agents with no access to the PSK seed); it protects the whole RTPS message, as opposed to just the serialized data, and protects against confidentiality threats.
While Pre-Shared Key Protection does not protect against domain insiders (i.e., malicious agents that have gained access to the PSK seed) flooding the network with malicious Participant Discovery messages, the eventual consistency of the Participant Discovery information is still enforced through the Authentication process and the Secure Reliable Participant Discovery topic.
16.3.5. Updating the PSK Passphrase Without Message Loss
The dds.sec.crypto.rtps_psk_secret_passphrase mutable property sets
the value of the PSK passphrase and enables Pre-Shared Key Protection. This property
can be updated at runtime.
However, if you directly modify the
dds.sec.crypto.rtps_psk_secret_passphrase property, you
should expect to lose some RTPS messages until all DomainParticipants in your system have the
updated passphrase. During the transition period, some DomainParticipants have the new
passphrase while others still have the old one. To address this issue, you can
use the dds.sec.crypto.rtps_psk_secret_passphrase_extra property.
To update the PSK passphrase without message loss, follow these recommended steps:
Set the
dds.sec.crypto.rtps_psk_secret_passphrase_extraproperty for all the DomainParticipants in your system. This property should include the values of the old and the new passphrases separated by a new line character.After setting the
dds.sec.crypto.rtps_psk_secret_passphrase_extraproperty value for all DomainParticipants, update thedds.sec.crypto.rtps_psk_secret_passphraseproperty (from the old passphrase to the new passphrase) for all DomainParticipants.You should now remove the value of the
dds.sec.crypto.rtps_psk_secret_passphrase_extraproperty from all DomainParticipants.
As a precautionary measure, you can periodically use the above steps to update
the PSK passphrase. However, you can also update the
dds.sec.crypto.rtps_psk_secret_passphrase directly, ignore
dds.sec.crypto.rtps_psk_secret_passphrase_extra, and accept the
loss of some RTPS messages. For example, it may be better to update the
passphrase as soon as possible if you suspect that it has been compromised.
Until all your DomainParticipants have transitioned to the new passphrase, you may see
warning messages saying that the pre-shared key used to encode the received
message has a different id than the one currently configured.
Figure 16.1 Updating the PSK passphrase without message loss
Warning
The dds.sec.crypto.rtps_psk_secret_passphrase and
dds.sec.crypto.rtps_psk_secret_passphrase_extra properties can
change when you call DomainParticipant::set_qos() with new values, or
due to a modification of the passphrase files when file tracking is enabled
(file tracking is enabled by default, because the
files_poll_interval property has a default value different than
0).
DomainParticipant::set_qos() updates the two passphrase properties at
the same time. However, the change in the passphrase files is not guaranteed
to be detected simultaneously. Therefore, the Security Plugins don’t allow
updates of the primary and extra passphrases through the file tracker as
illustrated in Table 16.1.
Passphrase |
Time 0 |
Time 1 |
Time 2 |
Time 3 |
|---|---|---|---|---|
Primary Passphrase |
<old> |
<old> |
<new> |
<new> |
Extra Passphrase |
<new> |
<old> |
This update pattern is not allowed because it attempts to configure the DomainParticipant
with the same primary and extra passphrase (both the old or both the new
passphrase) in the transition between “Time 1” and “Time 2”. Instead, set
the value of the dds.sec.crypto.rtps_psk_secret_passphrase_extra
property with the old and the new passphrases, as described earlier in this
section.