Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Full OQS project integration #1

Merged
merged 1 commit into from
Feb 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
version: 2.1

# CircleCI doesn't handle large file sets properly for local builds
# https://github.com/CircleCI-Public/circleci-cli/issues/281#issuecomment-472808051
localCheckout: &localCheckout
run: |-
PROJECT_PATH=$(cd ${CIRCLE_WORKING_DIRECTORY}; pwd)
mkdir -p ${PROJECT_PATH}
cd /tmp/_circleci_local_build_repo
git ls-files -z | xargs -0 -s 2090860 tar -c | tar -x -C ${PROJECT_PATH}
cp -a /tmp/_circleci_local_build_repo/.git ${PROJECT_PATH}
jobs:
ubuntu_bionic:
description: A template for running OQS-OpenSSL tests on x64 Ubuntu Bionic Docker VMs
docker:
- image: openquantumsafe/ci-ubuntu-bionic-x86_64:latest
steps:
- checkout # change this from "checkout" to "*localCheckout" when running CircleCI locally
- run:
name: Clone and build liboqs
command: |
git clone --depth 1 --branch main https://github.com/open-quantum-safe/liboqs.git &&
cd liboqs && mkdir _build && cd _build &&
cmake -GNinja -DCMAKE_INSTALL_PREFIX=$(pwd)/../../.local .. && ninja install &&
cd ..
- run:
name: Clone and build OpenSSL(3)
command: |
git clone --depth 1 --branch master git://git.openssl.org/openssl.git openssl &&
cd openssl && ./config --prefix=$(echo $(pwd)/../.local) && make -j 4 && make install_dev && cd ..
- run:
name: Build OQS-OpenSSL provider
command: |
./scripts/preptests.sh && mkdir _build && cd _build && cmake -GNinja -DOPENSSL_ROOT_DIR=$(pwd)/../.local -DCMAKE_PREFIX_PATH=$(pwd)/../.local .. && ninja
- run:
name: Run provider tests
command: cd _build; ctest

workflows:
version: 2.1
build:
jobs:
- ubuntu_bionic:
name: ubuntu-bionic
context: openquantumsafe
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# checked out OSSL
openssl
# checked out liboqs
liboqs
# installed SW
.local
# obtained from main OQS-OpenSSL repo
oqs-provider/generate.yml
# build directory
_build
# generated from openssl src:
test/ssltestlib.c
test/ssltestlib.h
test/oqs_test_groups
155 changes: 130 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,47 +1,152 @@
oqsprovider - Open Quantum Safe provider for OpenSSL 3.0
========================================================
oqsprovider - Open Quantum Safe provider for OpenSSL (3.0)
==========================================================

This is derived from the OQS-OpenSSL3 branch in
https://github.com/open-quantum-safe/openssl to
make an independent and external provider.
Purpose
-------

Pre-requisits
-------------
This repository contains code to enable quantum-safe cryptography in a
standard OpenSSL (3.0) distribution by way of implementing a single shared
library, the OQS
[provider](https://www.openssl.org/docs/manmaster/man7/provider.html).

To be able to build oqsprovider, you must build and install OpenSSL 3.0 (not
yet release) and liboqs. It's not important where they are installed, just
This code is derived from the OQS-OpenSSL3 branch in
https://github.com/open-quantum-safe/openssl creating
an independent and (OpenSSL-)external provider.

Status
------

Currently this provider fully enables quantum-safe cryptography for KEM
key establishment in TLS1.3 including management of such keys via the
OpenSSL (3.0) provider interface. Also, OQS signatures are available via
the OpenSSL EVP interface. For information about the available OQS algorithms,
[refer to the OQS-OpenSSL documentation](https://github.com/open-quantum-safe/openssl#supported-algorithms).

Open work items are
- fully TLS-integrated quantum-safe signatures
- hybrid quantum-safe cryptography

If any of these functionalities are needed, please refer to the
[OQS-OpenSSL1.1.1](https://github.com/open-quantum-safe/openssl) fork.

Building and testing
--------------------

## Pre-requisites

To be able to build `oqsprovider`, OpenSSL 3.0 (not yet released) and liboqs
need to be installed. It's not important where they are installed, just
that they are.

Example for building and installing OpenSSL 3.0 in `$HOME/.local` (only
development files are installed):
For building, minimum requirements are a C compiler, git access and `cmake`.
For Linux these commands can typically be installed by running for example

sudo apt install build-essential git cmake

### OpenSSL (3.0)

Example for building and installing OpenSSL 3.0 in `.local`:

git clone git://git.openssl.org/openssl.git openssl
git clone git://git.openssl.org/openssl.git
cd openssl
./config --prefix=$(echo $HOME/.local) && make && make install_dev
./config --prefix=$(echo $(pwd)/../.local) && make && make install_sw
cd ..

Example for building and installing liboqs in `$HOME/.local`:
OpenSSL (3.0) is not yet released in a production version. For [limitations
see here](https://wiki.openssl.org/index.php/OpenSSL_3.0#STATUS_of_current_development).

### liboqs

Example for building and installing liboqs in `.local`:

git clone https://github.com/open-quantum-safe/liboqs.git
cd liboqs
cmake -DCMAKE_INSTALL_PREFIX=$HOME/.local -S . -B _build
cmake --build _build
cmake --install _build
cmake -DCMAKE_INSTALL_PREFIX=$(pwd)/../.local -S . -B _build
cmake --build _build && cmake --install _build
cd ..

Quick building and testing instructions
---------------------------------------
Further `liboqs` build options are [documented here](https://github.com/open-quantum-safe/liboqs/wiki/Customizing-liboqs).

To build oqsprovider, do the following
## Building the provider

cmake -DOPENSSL_ROOT_DIR=$HOME/.local -DCMAKE_PREFIX_PATH=$HOME/.local \
-S . -B _build
`oqsprovider` can be build for example via the following:

cmake -DOPENSSL_ROOT_DIR=$(pwd)/.local -DCMAKE_PREFIX_PATH=$(pwd)/.local -S . -B _build
cmake --build _build

To test oqsprovider, do the following:
## Testing

Testing can be run via the following command:

(cd _build; ctest)

To test oqsprovider verbosely, do the following:
Add `-V` to the `ctest` command for verbose output.

*Note*: Some parts of testing depend on OpenSSL components. These can be
activated by executing `./scripts/preptests.sh` before building the provider.

## Build options

### NDEBUG

By adding the standard CMake option `-DCMAKE_BUILD_TYPE=Release` to the
`oqsprovider` build command, debugging output is disabled.

Using
-----

In order to exercise the `oqsprovider`, it needs to be explicitly activated.
One way to do this is to enable it in the OpenSSL config file. Detailed
explanations can be found for example
[here](https://wiki.openssl.org/index.php/OpenSSL_3.0#Providers).

Another alternative is to explicitly request its use on the command line.
The following examples use that option. All examples below assume openssl (3.0)
to be located in a folder `.local` in the local directory as per the
building examples above. Installing openssl(3.0) in a standard location
eliminates the need for specific PATH setting as showcased below.

## Creating (classic) keys and certificates

This can be facilitated for example by running

LD_LIBRARY_PATH=.local/lib .local/bin/openssl req -x509 -new -newkey rsa -keyout rsa_CA.key -out rsa_CA.crt -nodes -subj "/CN=test CA" -days 365 -config openssl/apps/openssl.cnf
LD_LIBRARY_PATH=.local/lib .local/bin/openssl genpkey -algorithm rsa -out rsa_srv.key
LD_LIBRARY_PATH=.local/lib .local/bin/openssl req -new -newkey rsa -keyout rsa_srv.key -out rsa_srv.csr -nodes -subj "/CN=test server" -config openssl/apps/openssl.cnf
LD_LIBRARY_PATH=.local/lib .local/bin/openssl x509 -req -in rsa_srv.csr -out rsa_srv.crt -CA rsa_CA.crt -CAkey rsa_CA.key -CAcreateserial -days 365

## Setting up a (quantum-safe) test server

This can be facilitated for example by running

LD_LIBRARY_PATH=.local/lib .local/bin/openssl s_server -cert rsa_srv.crt -key rsa_srv.key -www -tls1_3 -groups kyber768:frodo640shake -provider-path _build/oqsprov -provider default -provider oqsprovider

## Running a client to interact with (quantum-safe) KEM algorithms

This can be facilitated for example by running

LD_LIBRARY_PATH=.local/lib .local/bin/openssl s_client -groups frodo640shake -provider-path _build/oqsprov -provider default -provider oqsprovider

By issuing the command `GET /` the quantum-safe crypto enabled OpenSSL3
server returns details about the established connection.

Any [available KEM algorithm](https://github.com/open-quantum-safe/openssl/tree/OQS-OpenSSL_1_1_1-stable#key-exchange) can be selected by passing it in the `-groups` option.

Team
----
The Open Quantum Safe project is led by [Douglas Stebila](https://www.douglas.stebila.ca/research/) and [Michele Mosca](http://faculty.iqc.uwaterloo.ca/mmosca/) at the University of Waterloo.

Contributors to the `oqsprovider` include:

- Michael Baentsch
- Christian Paquin
- Richard Levitte

Acknowledgments
---------------

Financial support for the development of Open Quantum Safe has been provided by Amazon Web Services and the Tutte Institute for Mathematics and Computing.

We'd like to make a special acknowledgement to the companies who have dedicated programmer time to contribute source code to OQS, including Amazon Web Services, evolutionQ, Microsoft Research, Cisco Systems, and IBM Research.

(cd _build; ctest -V)
Research projects which developed specific components of OQS have been supported by various research grants, including funding from the Natural Sciences and Engineering Research Council of Canada (NSERC); see [here](https://openquantumsafe.org/papers/SAC-SteMos16.pdf) and [here](https://openquantumsafe.org/papers/NISTPQC-CroPaqSte19.pdf) for funding acknowledgments.
58 changes: 58 additions & 0 deletions oqs-template/generate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/usr/bin/env python3

import copy
import glob
import jinja2
import jinja2.ext
import os
import shutil
import subprocess
import yaml

# For list.append in Jinja templates
Jinja2 = jinja2.Environment(loader=jinja2.FileSystemLoader(searchpath="."),extensions=['jinja2.ext.do'])

def file_get_contents(filename, encoding=None):
with open(filename, mode='r', encoding=encoding) as fh:
return fh.read()

def file_put_contents(filename, s, encoding=None):
with open(filename, mode='w', encoding=encoding) as fh:
fh.write(s)

def populate(filename, config, delimiter, overwrite=False):
fragments = glob.glob(os.path.join('oqs-template', filename, '*.fragment'))
if overwrite == True:
source_file = os.path.join('oqs-template', filename, os.path.basename(filename)+ '.base')
contents = file_get_contents(source_file)
else:
contents = file_get_contents(filename)
for fragment in fragments:
identifier = os.path.splitext(os.path.basename(fragment))[0]
identifier_start = '{} OQS_TEMPLATE_FRAGMENT_{}_START'.format(delimiter, identifier.upper())
identifier_end = '{} OQS_TEMPLATE_FRAGMENT_{}_END'.format(delimiter, identifier.upper())
preamble = contents[:contents.find(identifier_start)]
postamble = contents[contents.find(identifier_end):]
if overwrite == True:
contents = preamble + Jinja2.get_template(fragment).render({'config': config}) + postamble.replace(identifier_end + '\n', '')
else:
contents = preamble + identifier_start + Jinja2.get_template(fragment).render({'config': config}) + postamble
file_put_contents(filename, contents)

def load_config():
config = file_get_contents(os.path.join('oqs-template', 'generate.yml'), encoding='utf-8')
config = yaml.safe_load(config)
for sig in config['sigs']:
sig['variants'] = [variant for variant in sig['variants'] if variant['enable']]
return config

config = load_config()

# For now, only activate providers:
populate('test/oqs_test_signatures.c', config, '/////')
populate('test/oqs_test_groups.c', config, '/////')
populate('oqsprov/oqsprov.c', config, '/////')
populate('oqsprov/oqsprov_groups.c', config, '/////')
populate('oqsprov/oqs_kmgmt.c', config, '/////')
populate('oqsprov/oqs_sig.c', config, '/////')

9 changes: 9 additions & 0 deletions oqs-template/generate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

cd oqs-template

# Step 1: Obtain current generate.yml from main:
wget -c https://raw.githubusercontent.com/open-quantum-safe/openssl/OQS-OpenSSL_1_1_1-stable/oqs-template/generate.yml

# Step 2: Run the generator:
cd .. && python3 oqs-template/generate.py
27 changes: 27 additions & 0 deletions oqs-template/oqsprov/oqs_kmgmt.c/keymgmt_constructors.fragment
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{% for sig in config['sigs'] %}
{%- for variant in sig['variants'] %}
static void *{{variant['name']}}_new_key(void *provctx)
{
return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), {{variant['oqs_meth']}}, "{{variant['name']}}", 0, NULL);
}

static void *{{variant['name']}}_gen_init(void *provctx, int selection)
{
return oqsx_gen_init(provctx, selection, {{variant['oqs_meth']}}, 0);
}

{%- endfor %}
{% endfor %}

{% for kem in config['kems'] %}
static void *{{kem['name_group']}}_new_key(void *provctx)
{
return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), {{kem['oqs_alg']}}, "{{kem['name_group']}}", 1, NULL);
}

static void *{{kem['name_group']}}_gen_init(void *provctx, int selection)
{
return oqsx_gen_init(provctx, selection, {{kem['oqs_alg']}}, 1);
}
{% endfor %}

9 changes: 9 additions & 0 deletions oqs-template/oqsprov/oqs_kmgmt.c/keymgmt_functions.fragment
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{% for sig in config['sigs'] %}
{%- for variant in sig['variants'] %}
MAKE_KEYMGMT_FUNCTIONS({{variant['name']}})
{%- endfor %}
{%- endfor %}
{% for kem in config['kems'] %}
MAKE_KEYMGMT_FUNCTIONS({{kem['name_group']}})
{%- endfor %}

8 changes: 8 additions & 0 deletions oqs-template/oqsprov/oqs_sig.c/sig_oids.fragment
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{% for sig in config['sigs'] %}
{%- for variant in sig['variants'] %}
if (!strcmp({{variant['oqs_meth']}}, oqs_name))
return i2d_ASN1_OBJECT(OBJ_txt2obj("{{variant['oid']}}", 1), &oidbuf);
else
{%- endfor %}
{%- endfor %}

9 changes: 9 additions & 0 deletions oqs-template/oqsprov/oqsprov.c/alg_functions.fragment
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{% for sig in config['sigs'] %}
{%- for variant in sig['variants'] %}
extern const OSSL_DISPATCH oqs_{{ variant['name'] }}_keymgmt_functions[];
{%- endfor %}
{%- endfor %}
{% for kem in config['kems'] %}
extern const OSSL_DISPATCH oqs_{{ kem['name_group'] }}_keymgmt_functions[];
{%- endfor %}

4 changes: 4 additions & 0 deletions oqs-template/oqsprov/oqsprov.c/kem_functions.fragment
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{% for kem in config['kems'] %}
ALG("{{kem['name_group']}}", oqs_generic_kem_functions),
{%- endfor %}

9 changes: 9 additions & 0 deletions oqs-template/oqsprov/oqsprov.c/keymgmt_functions.fragment
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{% for sig in config['sigs'] %}
{%- for variant in sig['variants'] %}
ALG("{{variant['name']}}", oqs_{{ variant['name'] }}_keymgmt_functions),
{%- endfor %}
{%- endfor %}
{% for kem in config['kems'] %}
ALG("{{kem['name_group']}}", oqs_{{ kem['name_group'] }}_keymgmt_functions),
{%- endfor %}

6 changes: 6 additions & 0 deletions oqs-template/oqsprov/oqsprov.c/sig_functions.fragment
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{% for sig in config['sigs'] %}
{%- for variant in sig['variants'] %}
ALG("{{variant['name']}}", oqs_signature_functions),
{%- endfor %}
{%- endfor %}

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{% for kem in config['kems'] %}
{ {{ kem['nid'] }}, {{ kem['bit_security'] }}, TLS1_3_VERSION, 0, -1, 0, 1 },
{%- endfor %}

6 changes: 6 additions & 0 deletions oqs-template/oqsprov/oqsprov_groups.c/group_names.fragment
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{% set cnt = namespace(val=-1) %}
{% for kem in config['kems'] -%}
{%- set cnt.val = cnt.val + 1 %}
OQS_GROUP_ENTRY("{{kem['name_group']}}", "{{kem['name_group']}}", "{{kem['name_group']}}", {{ cnt.val }}),
{%- endfor %}

Loading