Ockam logo
Open Source SDKsOckam RegistryOckam HubKafka Add-onInfluxData Add-onAzure HSM Add-onMicrochip Add-ons

Enrollment Key Agreement

This proposal specifies a key agreement protocol for an entity functioning as an enrollment service, another functioning as an enroller, and lastly an enrollee. The enroller's role is to provide information to an enrollee about the enrollment service such that the enrollee can compute an encryption key and communicate with an enrollment service without sending any information in the clear. The enroller also provides information to the enrollment service such that it knows a valid enrollment request from an enrollee and can safely ignore all others.

This protocol makes use of Signal's X3DH to provide mutual authentication, forward secrecy, and deniability.


There are 3 entities in this protocol: an enrollment service, an enroller, and enrollee. The service provides any enrolled entity with some functionality that will be consumed. The enroller is a system or device under control of an onboarder that is used to authorize other devices to the service. The enrollee is any system or device that wants to consume the benefits provided by the service.


The setup assumes a secure channel exists between the enroller and the service established using another method like XX Key agreement.

To become an enroller, the service generates an enrollment bundle which consists of three cryptographic keys:

  1. Service's identity key IKA
  2. Service's signed prekey SPKA
  3. Service's one-time prekey OPKA

The bundle also contains an Ockam address Addr an enrollee uses to indicate a new enrollment.


The process uses the following parameters:

hashA 256 bit hash function (e.g. SHA-256 or SHA3-256)
infoAn ASCII string with the protocol name
KDFHKDF with 32 0xFF bytes prepended to IKM, with info parameter and salt is 32 0x00 bytes
XEdDSAXEdDSA signature
AEADAuthenticated encryption scheme like AES-256-GCM
||Concatenation of byte sequences


The enroller is usually controlled by the same party as the enrollee. For example, a new robot (enrollee) is installed in a factory and the enroller is a computer terminal (enroller).

When a new enrollee comes online, it establishes a secure channel with an enroller. The enroller indicates to the enrollee to use the service by sending an enrollment bundle.


The enrollee then sends a public key EIKB to the enroller. The enroller forwards this key to the service to indicate this enrollee is allowed to enroll and blessed by this enroller.

At this point the enroller ceases to be a part of the communication.

The enrollee calculates the X3DH key agreement as follows:

  • DH1 = DH(EIKB, SPKA)
  • DH2 = DH(EKB, IKA)
  • DH3 = DH(EKB, SPKA)
  • DH4 = DH(EKB, OPKA)
  • SK = KDF(DH1 || DH2 || DH3 || DH4)

DH1 and DH2 provide mutual authentication. DH3 and DH4 provide forward secrecy. After calculating SK, the enrollee deletes the private key for EKB and DH outputs.

The enrollee calculates the state hash h = hash(info || [0xFF; 32] || DH1 || DH2 || DH3 || DH4)

The enrollee then generates a keypair IKB. This key becomes the identity key for the enrollee.

The enrollee sends a message to the service to indicate enrollment that includes the following:


  • An ephemeral public key EKB
  • Hash(EIKB)

Body Body is encrypted with the calculated SK from X3DH, the AAD is the value of Header || info || Addr || state hash h

  • IKB

EKB serves as the nonce (or the first N bytes depending on the encryption IV size) and Hash(EIKB) serves as the message id.

The message is sent to the service.


The service receives the message, derives SK the same way as the enrollee and performs the following checks:

  1. Has it seen EKB? If so, then reject the message.
  2. Does it have an expected enrollee id = Hash(EIKB)? If not, then reject the message.
    1. It can check this quickly by keeping a hash table of received EIK's from pending enrollees.
  3. Computes the same shared secret to decrypt the message. If decryption fails then reject the message.
  4. Verifies XEdDSA(IKB, EIKB). If it fails the reject the message.

If all checks pass, the service deletes EIKB and replaces it with IKB. This serves as the long term identity key of the enrollee.

The service can continue to use SK to communicate with the enrollee until SK is rotated.

Threat Model

The following are the various parts of the threat model:

  • Protecting against external threats by using to standard cryptography to provide confidentiality, integrity, accountability, authentication
  • Protecting against passive attackers that may be listening to network traffic and active attackers tampering with network traffic by using AES-GCM
  • Protecting against replay enrollments by using nonces and ephemeral keys

The following are not parts of the Vault threat model:

  • Protecting against a malicious enroller that changes or alters the service's prekey bundle or the identity key of the enrollee.
  • Protecting keys on the enrollee, enroller, and service more than the guarantees provided by the Vault.
  • Protecting against memory fault attacks
  • Protecting against physical side channel attacks like voltage differential attacks.


  1. Marlinspike, M. and Perrin, T., The X3DH Key Agreement Protocol.

Vault Interface

On this page
  • Enrollment Key Agreement
  • Description
  • Definition
  • Threat Model
  • Reference
Edit this page
Star Ockam repo