.. include:: ../vars.rst .. _chapter-pre-shared-key: *************** |PSKProtection| *************** This chapter describes |PSKProtection|, which expands and unifies |RTI_SP| entry-level protection. This mechanism replaces similar mechanisms (HMAC-only and its derivatives) under a common, more capable interface. |PSKProtection| is a |CryptoPlugin| mechanism that supports basic communication protection. It is based on a |PSK|, distributed out-of-band to |DPs|. The |PSKProtection| does not require authentication and does not support more sophisticated security features such as granular security and topic permissions enforcement. A |PSK| offers metadata and data protection on the wire and restricts communication only to |DPs| holding the pre-shared, user-configurable key seed. |PSKProtection| can be leveraged in two different ways: * As part of the |RTI_SP|: RTPS |PSKProtection| works alongside existing |SP| features and secures the communication happening before and during authentication. Post-authentication communication is protected with other security mechanisms from |SP|. * As part of |RTI_LIGHT_SP|: In this case, all traditional DDS Security mechanisms are disabled and the entire communication is protected with RTPS |PSKProtection|. |LIGHT_SP| is described in detail in :ref:`p3_advanced/lightweight_security:The |LIGHT_SP_HEADING|`. .. attention:: |PSKProtection| is being standardized and in this process the final configuration and functionality may change. |PSKProtection| Motivation and Benefits ======================================= |PSKProtection| 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. |PSKProtection| in |LIGHT_SP_HEADING| vs. |PSKProtection| in |SP_HEADING| ------------------------------------------------------------------------- |PSKProtection| uses the same mechanism in both |LIGHT_SP| and the |SP|, and offers the same level of protection. The difference is in the |PSK| area of responsibility. |PSKProtection| within the |SP| secures all communication that occurs before two |DPs| authenticate each other. Once authentication completes successfully, more sophisticated |SP| features (such as enforcement of permissions at the topic-level) can be used. Authentication itself is also protected with the |PSK|. In this setting, |PSKProtection| 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. |PSKProtection| also provides an additional mitigation for potential vulnerabilities in the participant discovery process. |LIGHT_SP| are provided as a separate library. It supports |PSKProtection| only and the entire communication is protected with it. More sophisticated security mechanisms are unavailable. |LIGHT_SP| 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. |LIGHT_SP| and |SP| can interoperate if configuration allows - see the configuration section below for details. Configuring |PSKProtection| =========================== .. note:: All |SP|- and |LIGHT_SP|-related properties must be prefixed with :property:`com.rti.serv.secure.`, assuming you used :property:`com.rti.serv.secure` as the alias to load the plugin. If not, change the prefix to match the string used with :property:`com.rti.serv.load_plugins`, followed by the :value:`.` character. The following properties are important for successfully configuring the |PSKProtection|: * The required property :property:`cryptography.rtps_protection_preshared_key` sets the value of the pre-shared key seed and enables |PSKProtection|. It must start with the "str:" prefix, continue with a unique key identifier (number between 0 and 254) followed by a colon (":"), and finish with the secret key. Both the key seed and the unique key identifier must be consistent across all |DPs| in the system. The key seed, combined with public information, is used to produce the key which 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 |DPs|. You have to manually update the key for at all |DPs| in the system. Until the key is updated across the system, decryption errors will occur. * An optional property determines the algorithm used to protect RTPS messages. For |SP|, use :property:`cryptography.encryption_algorithm`. For |LIGHT_SP|, use :property:`cryptography.rtps_protection_preshared_key_algorithm`. For more information about these properties, see :numref:`RTI Security Plugins Properties for Configuring Cryptography`. |LIGHT_SP_HEADING| and |SP_HEADING| Interoperability ---------------------------------------------------- |LIGHT_SP| can interoperate with |SP| if all of the following is true: * The |SP| |GovernanceDoc| is configured with :xmltag:`allow_unauthenticated_participants` = :xmlval:`TRUE` and :xmltag:`rtps_protection_kind` = :xmlval:`NONE`. |LIGHT_SP| do not support authentication and their RTPS messages are protected with |PSK|, which is incompatible with RTPS Origin Authentication Protection. See :ref:`p2_core/access_control:Participant-Level Permissions, Endpoint-Level Permissions, and Unsecure DomainParticipants` and :ref:`p2_core/cryptography:Origin Authentication Protection` for details. * The |SP| |GovernanceDoc| is configured with an :xmltag:`rtps_preshared_secret_protection_kind` that is consistent with the |LIGHT_SP|. See the table below for a list of compatible configurations. * The |SP| are configured with a ``cryptography.encryption_algorithm property`` (see :numref:`RTI Security Plugins Properties for Configuring Cryptography`) that is consistent with the |LIGHT_SP|. See the table below for a list of compatible configurations. .. list-table:: |LIGHT_SP| and |SP| compatible configurations :name: |LIGHT_SP| and |SP| compatible configurations :widths: 34 33 33 :header-rows: 1 :class: longtable * - |LIGHT_SP| `cryptography.rtps_protection_preshared_key_algorithm` - |SP| :xmltag:`rtps_preshared_secret_protection_kind` - |SP| `cryptography.encryption_algorithm property` * - `AES128+GMAC` - :xmlval:`SIGN` - `AES128+GCM` * - `AES128+GCM` - :xmlval:`ENCRYPT` - `AES128+GCM` * - `AES256+GMAC` - :xmlval:`SIGN` - `AES256+GCM` * - `AES256+GCM` (default) - :xmlval:`ENCRYPT` - `AES256+GCM` (default) .. note:: When the |SP| and the |LIGHT_SP| interoperate, topics that have metadata or data protection kinds enabled (features specific to the full |SP|) are unavailable to the |LIGHT_SP|. How |PSKProtection| Works ========================= |PSK| Material -------------- |PSKProtection| relies on deriving unique symmetric keys for every |DP|. The keys are based on a user-configurable, pre-shared secret key seed (common for all |DPs|) and publicly available data that uniquely identifies a |DP| in the network. Thanks to this architecture, every |DP| with the right pre-shared key seed can recreate the unique key material (Master Sender Salt and Master Sender Key) of any other |DP| 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: .. code-block:: none HMAC-SHA256( HMAC-SHA256( concatenate("PSK-SALT", sender's domain ID, target's RTPS header), pre-shared key seed), concatenate("master salt derivation", 0x01)) The 256-bit long Master Sender Key is derived according to this algorithm: .. code-block:: none HMAC-SHA256( HMAC-SHA256( concatenate("PSK-SKEY", sender's domain ID, target's RTPS header), pre-shared key seed), concatenate("master sender key derivation", 0x01)) .. note:: The uniqueness of every |DP|'s key material is important to ensure a high level of security. No two |DPs| 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 |SP| portfolio. Key Management -------------- A PSK-enabled |DP|, upon its creation, derives its own key material which is stored and readily available for later use. Whenever it wants to communicate with another |DP|, 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 |DP| 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 |DP| derives the key using the algorithm and puts it in the list. .. note:: The remote |DPs|' 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 |DP| 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 |DPs| discovery is complete, this limitation no longer exists since the keys are no longer stored in the list. |PSKProtection| and the Cloud ----------------------------- |PSKProtection| is the primary security mechanism for |CONNEXT| cloud deployments, and can be employed to protect the discovery data and Binding Ping in |RTI_CDS| and |RTI_RWT|. For a detailed description of these environments and configuration information see :ref:`p4_integrations/real-time_wan_transport:Support for RTI Real-Time WAN Transport`. When |PSKProtection| is enabled, Participant Discovery messages' serialized data is no longer protected using the TrustedState mechanism (see :ref:`p2_core/authentication:Protecting Participant Discovery`). Instead, the |SP| protect the whole Participant Discovery message (including replay attack protection information described in :ref:`p4_integrations/real-time_wan_transport:Protection Against a Cloud Discovery Service Participant Announcement Replay Attack`). TrustedState is disabled when |PSKProtection| is enabled for the following reasons: * One of the main use cases of |PSKProtection| is to secure cloud deployments. * |RTI_CDS|-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). * |PSKProtection| 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 |PSKProtection| 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.