Secure Session

Secure Session is a lightweight mechanism for securing any kind of network communication (both private and public networks, including the Internet). It is protocol-agnostic and operates on the 5th layer of the network OSI model.

Some of the features of Secure Session are: secure end-to-end communication; perfect forward secrecy; strong mutual peer authentication; replay protection; low negotiation round-trip; use of strong cryptography (including ECC); simplicity, user-friendliness; ease of integration into existing applications.

Communication over Secure Session consists of 2 stages: negotiation stage (key agreement); actual data exchange.

Negotiation stage

During the negotiation stage, peers exchange their cryptographic material and authenticate each other. After a successful mutual authentication, each peer derives a session-shared secret and other auxiliary info from the session (session ID, initial vectors, etc.).

NOTE: Session ID is random and is derived from the negotiated cryptographic material by each peer independently. There is no way for a specific value to be enforced by one of the peers.

Data exchange stage

During the data exchange stage, peers securely exchange data provided by higher layer protocols. The session parameters (state) can be saved and restored at any time. This means that the lifetime of the Session extends to the underlying environment's power cycle.

WARNING: The Session state contains sensitive information and should be stored and handled in a secure manner. For example, Secure Cell may be used.

Here is how the data is protected within the Session:

Integration scenarios

Secure Session only provides security services and doesn't do actual network communication. In fact, Secure Session is decoupled and independent from any networking implementation. It becomes the caller's responsibility to provide an actual network transport for Secure Session to use. There are two types of APIs available for easy integration and implementation: callback API and buffer-aware API.

Callback API

The easiest way to quickly leverage Secure Session in your solution is to implement a set of simple callback methods and register them within the Secure Session framework. These callbacks are a little more than just simple send/receive methods, but this is the interface that will bind the generic Secure Session communication with your actual networking implementation.

Buffer-aware API

This type of API is useful for integrating Secure Session with an application that has its own sophisticated established network processing path. You only need to add some calls to Secure Session somewhere in this path. These calls will be operating with client-provided buffers rather than using callbacks.

Complex scenarios

It is possible to mix the Callback API and the Buffer-aware API together and use them simultaneously when neither of the above simple cases is applicable for a specific solution. For example, if you:

  • use buffer-aware API for receiving data, but use callback API for sending data;
  • use callback API in negotiation stage, but use buffer-aware API on the data exchange stage;
  • switch from callback API to buffer-aware API and back again in the run-time based on some specific conditions;
  • etc.

WARNING: Invoking any Secure Session API in the same Secure Session context should be synchronised with the respect to that context.

Implementation details

Secure Session's interface is described in src/themis/secure_session.h.

Secure Session depends on the transport object that must be set by the secure_session_create method:

secure_session_t *secure_session_create(const void *id, size_t id_length,
                                        const void *sign_key, size_t sign_key_length,
                                        const secure_session_user_callbacks_t *user_callbacks);

The transport object is represented by the following structure:

struct secure_session_user_callbacks_type
  send_protocol_data_callback send_data;
  receive_protocol_data_callback receive_data;
  protocol_state_changed_callback state_changed;
  get_public_key_for_id_callback get_public_key_for_id;

  void *user_data;

The callbacks' function pointers are:

typedef ssize_t (*send_protocol_data_callback)(const uint8_t *data,
                                               size_t data_length,
                                               void *user_data);

typedef ssize_t (*receive_protocol_data_callback)(uint8_t *data,
                                                  size_t data_length,
                                                  void *user_data);

typedef void (*protocol_state_changed_callback)(int event,
                                                void *user_data);

typedef int (*get_public_key_for_id_callback)(const void *id,
                                              size_t id_length,
                                              void *key_buffer,
                                              size_t key_buffer_length,
                                              void *user_data);

Function get_public_key_for_id_callback is used for getting the public key for client ID, so this callback is mandatory. Without it, Secure Session will have no means for authenticating the key exchange.

The functions send_protocol_data_callback and receive_protocol_data_callback are used for sending and receiving data from the communication channel. When set, send_protocol_data_callback may be triggered by key exchange when the Session is established. The functions send_protocol_data_callback and receive_protocol_data_callback will both be triggered by secure_session_send and secure_session_receive to communicate over an actual communication channel. If these functions are not set, Secure Session object can still be used in wrap/unwrap mode (see below).

The function protocol_state_changed_callback is an optional callback that delivers Secure Session state transitions to client applications.

Usage modes

Secure Session object may be used in three modes.


In this mode, the Secure Session object manages communication channel on its own, with the help of send_protocol_data_callback and receive_protocol_data_callback methods.

ssize_t secure_session_send(secure_session_t *session_ctx,
                            const void *message,
                            size_t message_length);

ssize_t secure_session_receive(secure_session_t *session_ctx,
                               void *message,
                               size_t message_length);


In this mode, send_protocol_data_callback and receive_protocol_data_callback methods are not used. A wrapped message will be returned to the user in a buffer.

themis_status_t secure_session_wrap(secure_session_t *session_ctx,
                                    const void *message,
                                    size_t message_length,
                                    void *wrapped_message,
                                    size_t *wrapped_message_length);

themis_status_t secure_session_unwrap(secure_session_t *session_ctx,
                                      const void *wrapped_message,
                                      size_t wrapped_message_length,
                                      void *message,
                                      size_t *message_length);

Mixed mode

Any combination of the three modes may work, too. For example, send_protocol_data_callback may be set, while secure_session_send is used for sending the data and secure_session_unwrap decrypts the data in the application's "receive" path.