Skip to content
Snippets Groups Projects

Quant

pipeline status

The quant repository contains a prototypical software stack that allows to emulate a key exchange within a Quantum Key Distribution Network (QKDN).

Currently quant contains the following main parts: goKMS, quantumlayer, akms-simulator, etsi14module

goKMS

A Key Management System (KMS) for QKDN written in go.

goKMS can pull or receive QKD key material from different sources depending on the configured operating mode. This material gets processed into keys and it provides a key store for each registered KMS peer. So called forwarding routes can be set through gnmi, either via assign-forwarding or key-routing-sessions (see temp.yang).

If a route is configured the goKMS that has no prev-hop provided within its route configuration, will initiate the process to exchange a so-called platform-key using keys derived from QKD key material to encrypt and decrypt the platform-key hop-by-hop during the exchange process. Afterwards, the start and end goKMS have a platform-key available to perform a KSA key exchange.

Note well: This is currently not intended to be used in production environments, neither in networks that can be reached by everybody, nor in other uncontrolled settings.

Configuration of a goKMS

A goKMS can be configured through a configuration file, as seen below:

Id: "0ff33c82-7fe1-482b-a0ca-67565806ee4b" # ID of the kms
Name: kms01 # name of the kms
InterComAddr: 0.0.0.0:50910 # IP and port to bind the local gRPC server for inter KMS communication to
QuantumAddr: 0.0.0.0:50911 # IP and port to bind the local gRPC server for QKD modules to reach the KMS to (optional, only used for specific emulated or experimental QKD modules)
AkmsURL: "http://172.100.20.22:4444/api/v1/keys/push_ksa_key" # address of the rest endpoint of a connected AKMS (used for sending KSA key to the AKMS).
AkmsCkmsServerPort: "9696" # Port of connected AKMS
GRPCTimeoutInSeconds: 10 # Time in seconds for timeout of gRPC connections as a client. Defaults to 10 seconds. Should not be set to 0 or negative values.
GnmiTLS: # Settings for TLS for gNMI endpoint. Can be overwritten with cli parameters.
  Active: true # Whether TLS is enabled
  CAFile: "ssl/ca.crt" # Path to ca
  CertFile: "ssl/kms/kms1-selfsigned.crt" # Path to cert
  KeyFile: "ssl/kms/kms1-selfsigned.key" # Path to key
KmsTLS: # Settings for TLS for inter KMS communication
  Active: true # Whether TLS is enabled
  CAFile: "ssl/ca.crt" # Path to ca
  CertFile: "ssl/kms/kms1-selfsigned.crt" # Path to cert
  KeyFile: "ssl/kms/kms1-selfsigned.key" # Path to key
AkmsCkmsTLS: # Settings for TLS for akms ckms interface
  Active: true # Whether TLS is enabled
  CAFile: "ssl/ca.crt" # Path to ca
  CertFile: "ssl/kms/kms1-selfsigned.crt" # Path to cert
  KeyFile: "ssl/kms/kms1-selfsigned.key" # Path to key
Peers: # Peers to other goKMS
    # peer to goKMS02
    - PeerId: "5e41c291-6121-4335-84f6-41e04b8bdaa2" # id of the peer
      PeerInterComAddr: 172.100.20.11:50910 # inter com endpoint of the peer
      Type: danet # type of communication method between KMS (currently only danet supported)
      QuantumModule: # Quantum module used for this peer
          Type: emulated # Type of the quantum module e.g. emulated or etsi
          TLS: # Settings for TLS for quantum module communication
            Active: true # Whether TLS is enabled
            CAFile: "ssl/ca.crt" # Path to ca
            CertFile: "ssl/kms/kms1-selfsigned.crt" # Path to cert
            KeyFile: "ssl/kms/kms1-selfsigned.key" # Path to key
          Address: 172.100.20.14 # Address of the quantum module
          Hostname: quantumlayer_1 # Optional addressing of the quantum module as hostname
    # peer to goKMS03
    - PeerId: "f80db2c0-2480-46b9-b7d1-b63f954e8227"
      PeerInterComAddr: 172.100.20.12:50910
      Type: danet
      QuantumModule:
          Type: emulated
          Address: 172.100.20.18

Other configuration options:

ETSI14Server: # Configuration for ETSI014 server, should not be used together with AKMS configurations
  Address: "0.0.0.0:1414" # IP and port to bind the local ETSI014 HTTP server to, provides the endpoints defined in ETSI014
  RemoteCKMSID: "5e41c291-6121-4335-84f6-41e04b8bdaa2" # UUID of the target CKMS when doing a (ETSI014) GetKey

QkdnManagerServer: # Server on KMS side for monitoring purposes, currently only supports few example endpoints
  Address: "0.0.0.0:8090" # IP and port to bind the local management monitoring HTTP server to

Peers:
  # peer to goKMS02
  - PeerId: "5e41c291-6121-4335-84f6-41e04b8bdaa2"
    PeerInterComAddr: 172.100.20.11:50910
    Type: danet # type of communication method between KMS (currently only danet supported)
    QuantumModule:
      Type: etsi # Type of the quantum module e.g. emulated or etsi
      Address: http://172.100.20.14:1414 # Address of the quantum module
      Mastermode: true # (Type: etsi specific) Sets the QuantumModule in MasterMode. Keys are requested via GetKey and synced with peer KMS.
      LocalSAEID: "localSAEID" # the related ID of the local SAE
      TargetSAEID: "targetSAEID" # the related ID of the target SAE
      KeyFetchInterval: 10 # interval in seconds for how often keys should be requested from a QuantumModule (optional, uses default if not provided)
      KeyFetchAmount: 10 # amount of keys to be requested from a QuantumModule (optional, uses default if not provided)
      MaxKeyFillLevel: 100 # maximum number of keys to be stored in the storage related to one KMS peer (should be the same for the peer on the other side, uses default if not provided)
  # peer to goKMS03
  - PeerId: "f80db2c0-2480-46b9-b7d1-b63f954e8227"
    PeerInterComAddr: 172.100.20.12:50910
    Type: danet
    QuantumModule:
      Type: etsi
      Address: http://172.100.20.14:1414
      Mastermode: false # (Type: etsi specific) Sets QuantumModule to request keys via GetKeyWithId, setting false explicitly is optional
      LocalSAEID: "localSAEID" # the related ID of the local SAE
      TargetSAEID: "targetSAEID" # the related ID of the target SAE

There are many example configuration files available in this repository under config. Note, for some configuration options, there are different operating modes or ways to configure the behaviour. Not all of them can work together, possible working configurations can be found within the provided example configurations.

You can also provide some configuration via command line arguments. Only settings relevant for running goKMS with remote configuration via gNMI are available here. This includes gNMI TLS settings and log level. Furthermore a path to a configuration file can be provided. Keep in mind that cli arguments will be prioritized, so you can overwrite your gNMI settings in the config file with your cli arguments.

Available are the following flags:

Usage of goKMS:
  -caFile string
        location of the gNMI ca file (overwrites settings in config file)
  -certFile string
        location of the gNMI cert file (overwrites settings in config file)
  -gnmiBindAddress string
        address to bind gNMI to (overwrites settings in config file) (default ":7030")
  -gnmiTLS
        If true do use TLS for gNMI, paths to ca, cert and key must be set aswell (overwrites settings in config file)
  -noGRPCPassthrough
        set the default resolve scheme for grpc to not use passthrough, default is false
  -keyFile string
        location of the gNMI key file (overwrites settings in config file)
  -kms_config string
        path to the config file
  -log string
        logrus log level (debug, info, warn, error, fatal, panic) (default "info")

Interfaces

Inter-KMS Communication

This interface is required for the communication between the peering KMS in order to coordinate their actions for key selection and key forwardwing after a path has been established. The definition can be found in: api/kmsintercom/kmsintercom/kmsintercom.proto

Note: In the future, goKMS might support additional, different protocols for the key exchange.

Interface to quantum modules

goKMS provides the possibility to use different kinds of interfaces to communicate with quantum modules. Which one to use, can be defined via the configuration files in the quantum module section under the peer configuration (see).

Currently there are two interfaces available:

  • First there is our own interface implementation which can be found under: danet/quipsec This is the interface that is used within our implementation of an emulated quantum module (see quantumlayer).

  • Second there is the REST-based implementation of ETSI014 which allows us to handle quantum modules that implemented the ETSI014 API (polling is currently hardcoded to 2 seconds).

gNMI

To manage the goKMS we provide a gNMI endpoint.

By using the gnmi-target package it is possible to manage (GET/SET/subscribe) configuration data of the KMS. Currently we use the temp.yang file for this and only a part of it is implemented yet.

Interfaces to trigger key exchange

Depending on the chosen configuration of the KMS, there are different possibilities of triggering a key exchange.

Via AKMS:

It is possible to simulate a request send by an AKMS (see akms-simulator). The request should look like something this, where receiving_CKMS_ID is the ID of the KMS that should be reached. Check config/configure-and-run-docker-playground.sh for other examples:

curl -X POST -H "Content-Type: application/json" -d '{
  "receiving_CKMS_ID": "968fd594-b0e7-41f0-ba4b-de259047a933",
  "request_ID": "request_ID-1234",
  "key_properties": {
      "number": 1,
      "key_length": 256,
      "timeout": 20,
      "TTL": 24
    }
}' 'http://172.100.20.10:9696/api/v1/keys/ksa_key_req'

After a successful key exchange both AKMS simulators will log the ID and the key value.

Via ETSI014:

The key exchange can also be triggered by sending a GetKey request as defined in ETSI014. After a successful key exchange, the key can then be fetched on the other end using the GetKeyWithIDs call.

Debug setup

For goKMS there is a debug setup available for VS Code. It uses the standard docker-compose.yml setup and simply adds the debugger to it in the docker-compose.override.yaml

  1. Set your breakpoints for the goKMS (akms-simulator and quantumlayer currently not supported)
  2. Go to the debugger tab in vscode and select Debug all kms parallel. The single KMS options may work for certain things, but are not guaranteed to work because of how the debugging setup works.
  3. Wait for it to start. At the end you can follow the instruction printed in your terminal to add the devices to the qkdn-controller.

If you are finished stop the debugger and run make compose-debug-down to stop the environment.

Quantumlayer

An implementation of an emulated quantum module. This QKD module pushes an amount of random numbers (called bulk keys) to the connected KMS, whereas the actual amount will vary over time and depending on the operation mode. It has two possible operation modes:

(Pseudo) Random Numbers

The generation of random numbers is done via the golang's math/rand pseudo random number generator(PRNG). The synchronization is done in an "offline" way, as both quantum modules simply wait to the next full 20 seconds on their clock before sending data. As both modules use the same seed for it's number generation, they will send the same data. After sending, it will sleep a given amount of time.

For this a quantumlayer uses the gRPC interface defined in: danet/quipsec.

Replay Numbers

The generation of random numbers is done with the help of a CSV file. This file should include a timestamp in ms and the number of bits that should be sent at that time. The quantum module always waits the given duration and then sends the given amount of data. For the random numbers, the same method as in the random operation mode is used.

Configuration of a quantumlayer

A quantumlayer can be configured through a configuration file, as seen below:

KMSAddr: "kms_1:50911"              # The address of the connected goKMS.
OperationMode: "normal"             # The operations mode. Can be either "normal" or "replay"
SleepTimerForGenerationInMs: 5000   # How long the module should sleep between each send process. Only relevant if mode is "normal"
Seed: 1337                          # The seed for the random number generation. Must be the same on both matching quantum modules. If empty, the current day is used.
replayFilePath: './data.csv'        # The path to the replay data. Only relevant if mode is "replay"

Also available are the following arguments:

Usage of quantumlayer:
  -config string
        path to the config file
  -noGRPCPassthrough
        set the default resolve scheme for grpc to not use passthrough, default is false (default false)
  -log string
        logrus lof level (debug, info, warn, error, fatal, panic), default: info (default "info")

akms-simulator

A simple simulation of an AKMS endpoint. This provides a REST endpoint to receive KSA keys from a goKMS. The following functionalities are not implemented, the explanation is just there as a means of describing the KMS type. The 'A' stands for access and one of the main purposes of this type of KMS is providing a security barrier protecting the core network of a provider from malicious activity of an end user. Its further purpose is to interact with AAA instances of providers for contractual matters.

etsi14module

A simple implementation of a QKD module providing the REST endpoint as defined in ETSI014. Depending on the desired configuration of the whole QKD network, it can be used as provider of pseudo QKD key material. There is no complex logic behind the endpoint, it just provides randomly genrated keys using the random number generator of Go on a GetKey call. This keys get stored in memory to be able to provide them afterwards on GetKeyWithIDs calls.

Usage

See the makefile for options. To use private repos rename build_env.env.example to build_env.env and add valid credentials. If you have access, simply use your username and a GitLab access token.

Minimal Test Setup

A docker-compose file provides a minimal test setup to play around with quant.

Minimal docker test setup

This minimal setup contains four goKMS, with goKMS01 and goKMS04 as endpoints. Both of those are then connected to a akms-simulator. Quantumlayers are used as quantum modules.

Start and Stop

By running make compose-up and make compose-down the setup can be started or stopped with its default config. Please note that you need access to private QKDN repos to do this. If you don"t have this access, you can use the small examples in /dev_env_data.

The default config is based on the configuration files provided in the config/goKMS and config/quantumlayer folder.

Setting routes

We provide some example .json files to configure forwarding routes. They can be found under config.

It is possible to configure the goKMS through gNMI. This also applies for setting entries within the goKMS internal routing table. Therefore the paths assign-forwarding as well as key-routing-sessions are both suitable.

The following is an example of a gNMI set request sent through gnmic:

gnmic -a "172.100.20.12:7030" -u admin -p admin --insecure -e JSON_IETF set --update-path 'key-routing-sessions/routing-sessions[path-id=38e0588b-6a2d-42c9-85a0-887cc877c299]' --update-file ./config/goKMS02-a.json

The .json provided in this case contains information about previous and next hops, as well as a path id.

{
    "path-id": "38e0588b-6a2d-42c9-85a0-887cc877c299",
    "prev-hop": {
        "node-id": "0ff33c82-7fe1-482b-a0ca-67565806ee4b",
        "ip-address": "172.100.20.10",
        "port": 50910
    },
    "next-hop": {
        "node-id": "968fd594-b0e7-41f0-ba4b-de259047a933",
        "ip-address": "172.100.20.13",
        "port": 50910
    }
}

Instant playground

For an instant playground the bash script configure-and-run-docker-playground.sh can be used (see config/configure-and-run-docker-playground.sh). This adds two key-routing-sessions which results in the exchange of two platform keys.

  • kms01 -> kms02 -> kms04
  • kms01 -> kms03 -> kms04

After that two requests from an AKMS are simulated through two curl requests.

Demo with goSDN-Controller

There is an additional playground where the goSDN-Controller can be used to configure goKMS. Therefore a small lab is provided.

Requirements:

Below is a short demo video of this setup in combination with the goSDN-Controller.

Integration Tests

Everything needed for the integration tests is found in the integration-tests folder. You can run them by simply using make integration-tests in the project root.

If you need to debug the integration tests you can use vscode and provided configurations. Open the integration test file you want to debug and set your breakpoints in the test and the kms code (a breakpoint before the tests add the devices to the controller is nearly always required), then go to VSCodes debug tab and start Debug open integration test and kms. After all images are build and started wait around 25 seconds before starting to progress through the test. You can switch between stepping through the test and each kms. Stepping through the quantum layer, controller, routing app and akms-simulator is currently not supported.

Contributing

Contributions are welcome! Please follow these guidelines:

  1. Fork the repository.
  2. Create a new branch.
  3. Make your changes.
  4. Submit a pull request.

Acknowledgements

Developed in the DemoQuanDT project ("Quantenschlüsselaustausch im deutschen Telekommunikationsnetz für höhere IT-Sicherheit", engl. quantum key exchange in the german telecommunications network for higher IT security).

The DemoQuanDT project is funded by the german ministry of education and research (BMBF).

Logo of the BMBF