Introduction

The ISARA Radiate OpenSSL Connector gives you the ability to implement OpenSSL using the algorithms provided in the ISARA Radiate Security Solution Suite. ISARA Radiate gives you the cryptographic building blocks to create applications that will resist attacks by quantum computers.

For more information about ISARA quantum resistant solutions, please visit https://www.isara.com.

This User’s Guide assumes that you are already familiar with OpenSSL and have extensive experience using it.

Version 1.2 of the ISARA Radiate OpenSSL Connector package contains:

  • Documentation about the ISARA Radiate OpenSSL Connector (README.html and this file)

  • a set of patch files to be applied to the appropriate version of the OpenSSL source

  • the ISARA Radiate toolkit library binary

  • the ISARA Radiate Key State Manager library binary

  • the ISARA Radiate OpenSSL Engine built using OpenSSL and the ISARA Radiate Security Solution Suite

  • the source code for several demo applications that demonstrate how to use the ISARA Radiate OpenSSL Connector

  • scripts that run OpenSSL utility applications and ISARA Radiate OpenSSL Connector demonstration applications and their expected output

The patch files and engine have been tested against these versions of OpenSSL:

  • OpenSSL-1.0.2g

  • OpenSSL-1.0.2j

  • OpenSSL-1.0.2k

The resulting source code was built against ISARA Radiate Security Solution Suite 1.2 included in this package.

The User’s Guide covers the following topics:

Packaging

The ISARA Radiate OpenSSL Connector package contains the following files and directories:

  • README.html — Information about the ISARA Radiate OpenSSL Connector package

  • OpenSSL-Connector-Guide.html — This file.

  • <OPENSSL_VERSION>_ISARA.patch — The patch to apply against OpenSSL where <OPENSSL_VERSION> is one of the following:

    • OpenSSL-1.0.2g

    • OpenSSL-1.0.2j

    • OpenSSL-1.0.2k

  • lib/libiqr_toolkit.so — ISARA Radiate toolkit library (for Linux)

  • lib/libiqr_toolkit.dylib — ISARA Radiate toolkit library (For OSX)

  • lib/libikm_manager.so — The ISARA Radiate Key State Manager library (on Linux)

  • lib/libikm_manager.dylib — The ISARA Radiate State Manager library (on OSX)

  • lib/libiqre_engine.so — ISARA Radiate OpenSSL Connector Engine Library

  • demos/ — Demo source code showing some of the new features

  • demo_script.txt — Script used to demonstrate using OpenSSL with ISARA’s algorithms

  • expected_output.txt — Expected output of the demo_script.txt

  • data/ — Configuration files for the script above

Getting Help

The latest version of this User’s Guide and other ISARA Radiate Security Solution Suite documentation is available on https://www.isara.com. The ISARA Radiate Security Solution Suite Developer’s Guide provides more insights into the meaning of the parameters and has references to algorithm specifications.

Introduction to ISARA’s Algorithms

The ISARA Radiate OpenSSL Connector adds the following quantum resistant algorithms to OpenSSL:

  • Leighton-Micali Signature scheme (LMS)

  • McEliece with Quasi-Cyclic Moderate Density Parity-Check code used in shared secret establishment (MCQ)

  • NewHope family of key exchange variants (NHF):

    • Reference NewHope (NH)

    • Lattice-based Unique Key Establishment (LUKE), an ISARA proprietary algorithm

    • NewHope with AES (NHAES)

Note
The abbreviations in parentheses above are not the official algorithm abbreviations. They are the compact names of the algorithms used in the code of the ISARA Radiate OpenSSL Connector.

Many of the algorithm details are abstracted via the EVP PKEY API. For details, see Using libcrypto APIs For Quantum Resistant Public Key Cryptography.

Caveats

  • LMS keys can only produce a specific number of signatures. The total number of signatures available to an LMS private key depends on parameter selection.

  • LMS private keys are generated and managed using ISARA’s proprietary split private key scheme. See the LMS section of this User’s Guide for details about split private keys.

  • All NewHope variants must initiate and finish the key exchange in the same transaction. The operation cannot be restarted from a previously initialized state.

  • All NewHope variants require that the participants know whether they are the initiator or responder, which is different from Diffie-Hellman requirements.

  • The QC-MDPC private-public key pair must only be used once and then discarded.

Applying the ISARA Radiate OpenSSL Connector Patch to OpenSSL

The ISARA Radiate OpenSSL Connector is supplied as a patch to OpenSSL. It is expected that you are maintaining your own version of OpenSSL with your own customizations to fit into your own system.

The source code for OpenSSL can be found on the OpenSSL.org website: https://www.openssl.org/source/old/

  1. Unpack the OpenSSL source.

  2. In the unpacked directory, apply the patch using the following command: patch -p2 < OpenSSL-ISARA.patch

If the patch doesn’t apply cleanly, start over and make sure you’re running the patch command from inside the OpenSSL directory. (For example, the directory for OpenSSL 1.0.2g is named openssl-1.0.2g.) Also ensure that you are using the appropriate patch for your version of OpenSSL.

Build Instructions

After patching the source for OpenSSL, build it:

  1. Configure OpenSSL. See the relevant INSTALL file in the OpenSSL directory for more information. For example: ./Configure shared OPENSSL_CONFIGURATION NOTE: You must use shared for dynamic engine support.

  2. Execute make depend

  3. Execute make all

  4. Build the demo applications. Each source file in the demos directory is its own self-contained application. The ISARA Radiate OpenSSL Connector uses the following compiler and linker flags to build these applications: -O3 -DNDEBUG -rdynamic -lcrypto. Your system might require different parameters.

  5. Run the ISARA Radiate OpenSSL Connector demos and the OpenSSL standard utilities as shown in demo_script.txt to see if you get similar output to what is shown in expected_output.txt.

Note
You will not get an exact match in output as there is some randomness associated with these algorithms and potential differences across run- time environments.

Using OpenSSL Utilities For Quantum Resistant Public Key Cryptography

The functionality of the standard utilities from the OpenSSL package has not changed. These utilities are documented on the OpenSSL.org website: https://www.openssl.org/docs/man1.0.2/apps/

Since ISARA’s algorithms are implemented in an engine, use the -engine parameter to specify the path and file name of the ISARA Radiate engine. This engine can print debug and status information to stderr by defining the following environment variable at runtime:

ISARA_VERBOSE=1

See the demo.sh script for an example of how to do this.

The following standard OpenSSL utilities can be used with the indicated algorithms:

Table 1. Supported Algorithms By Application
Application LMS MCQ NHF

req

x509

verify

cms

smime

genpkey

pkey

pkeyutl

ciphers

s_server

s_client

Leighton-Micali Signature Scheme

If the application has an -algorithm parameter, you can specify LMS with -algorithm LMS.

Of particular note, the ISARA Radiate OpenSSL Connector does not fully support using x509, req and genpkey. You cannot embed the public key in the private key.

If you use req and then x509 to generate a self-signed certificate, OpenSSL will embed an empty public key in the certificate. Alternatively, you can use req with the -x509 parameter to create a self-signed certificate.

If you use genpkey you lose the public key. ISARA has developed a proprietary split private key scheme. This lets you generate an entire LMS private key split into multiple independent files. However, such a scheme is not compatible with the way the genpkey utility works. Therefore, the ISARA Radiate OpenSSL Connector includes a new demo application called openssl_genlms that allows you to create split LMS private keys.

You can use the following options to specify the Winternitz value, tree height, number of split keys and prefix of the private key files:

  • -pkeyopt winternitz_value:w

  • -pkeyopt tree_height:h

  • -pkeyopt split:n

  • -pkeyopt private_key_prefix:path_prefix

Use one of these values for w:

Table 2. LMS Winternitz Values
w Winternitz Value

0

1

1

2

2

4

3

8

Use one of these values for h:

Table 3. LMS Tree Height Values
h Tree Height

0

5

1

10

2

15

3

20

See the IETF specification referenced in the ISARA Radiate Security Solution Suite documentation for more details about these values.

n can be any value from 1 to 2 to the power of the tree height. n=1 is the canonical case of a single tree.

private_key_prefix can be something like /home/user/keys/lms_priv_key. An identifier and extension will be appended to the prefix to create many split keys. For example, with the prefix above and the case of n=4 then the following files would be created:

  • /home/user/keys/lms_priv_key_0.pem

  • /home/user/keys/lms_priv_key_1.pem

  • /home/user/keys/lms_priv_key_2.pem

  • /home/user/keys/lms_priv_key_3.pem

Note
The engine expects that you not edit the file names. You can move these files to different places in the file system and even onto different computers, but you should not rename the files.

For the req utility, you must ignore the key that would be output to stdout or the file specified by -keyout command line parameters. Instead, you should use the key as specified by private_key_prefix.

The engine manages the private key. All operations that require an LMS private key must use the engine key form, specified as -keyform ENGINE -key /path/to/key_n.pem where n is an integer.

McEliece with Quasi-Cyclic Moderate Density Parity-Check Code

If the application has an -algorithm parameter, you can specify QC-MDPC with -algorithm MCQ. genpkey can create keys of different security levels by setting the keysize with -pkeyopt pubkeysize:n. Use one of these values for n:

Table 4. QC-MDPC Key Sizes
n Public Key Size in Bits Description

0

9857

128 bits of classical security.

1

14866

128 bits of classical security.

2

20409

128 bits of classical security.

3

32771

256 bits of classical security.

4

45062

256 bits of classical security.

5

61449

256 bits of classical security.

NewHope, LUKE and NewHope with AES

As NewHope, LUKE, and NewHope with AES are specifically for key exchange, they are only used in the s_server and s_client applications that run the TLS protocols.

These are exposed by the Derive/SetPeer EVP PKEY APIs, but pkeyutl cannot be used with these algorithms. A peer key file cannot be properly supplied for the initiator because construction depends on the responder’s data. The responder must have the initiator’s peer key first. The initiator’s peer key does not exist yet; that is why you are running pkeyutl in the first place. The ISARA Radiate OpenSSL Connector package includes a simple demo of how to use these algorithms. See openssl_nh_with_asn1.c.

Note
The ciphers application lists all supported ciphersuites. To try one of the ISARA Radiate ciphersuites, run the ciphers command to get a list of all supported ciphersuites and pick the one you want. When you execute s_client, pass in that ciphersuite with the -cipher command line option.

Using libcrypto APIs For Quantum Resistant Public Key Cryptography

All of ISARA’s algorithms are abstracted by the EVP PKEY API layer. Here are the relevant APIs for each of the algorithms:

Table 5. EVP APIs per Algorithm
Algorithm CTX_new_id Keygen SetParam Sign Verify Encrypt Decrypt SetPeer Derive

LMS

MCQ

NewHope Variants

Note
These API names have been shortened and simplified. For example, Derive refers to EVP_PKEY_derive_init() and EVP_PKEY_derive().

Because LMS private keys are saved in a proprietary format, the engine is used to save and load the private key. LMS private keys must be loaded via ENGINE_load_private_key(). The key_id should be the path of the private key file.

Loading the Engine

You must load the ISARA Radiate engine before using the ISARA Radiate algorithms. The following sample code shows how to load the engine, where the engine parameter is a string that specifies the path to the engine’s file:

ENGINE *setup_engine(const char *engine) {
    ENGINE *e = NULL;
    if ((e = ENGINE_by_id(engine)) == NULL) {
        fprintf(stderr, "Invalid engine \"%s\".\n", engine);
        return NULL;
    }

    if (!ENGINE_init(e)) {
        fprintf(stderr, "The engine did not initialize correctly.\n");
        ENGINE_free(e);
        return NULL;
    }

    if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
        fprintf(stderr, "Unable to use this engine.\n");
        ENGINE_free(e);
        return NULL;
    }

    fprintf(stdout, "Engine \"%s\" set.\n", ENGINE_get_id(e));
    return e;
}

int main(int argc, char **argv) {
    if (argc != 2) {
        fprintf(stderr, "Failure to specify the correct parameters.\n");
        usage(argv[0]);
        return EXIT_FAILURE;
    }

    CRYPTO_malloc_debug_init();
    CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

    ERR_load_crypto_strings();
    ENGINE_load_dynamic();

    ENGINE *e = setup_engine(argv[1]);
    if (e == NULL) {
        usage(argv[0]);
        return EXIT_FAILURE;
    }

Much of the code has been omitted in this example. See the full code in openssl_engine_load.c.

For security reasons, the ISARA Radiate engine overrides the default RNG implementation in OpenSSL with ISARA’s HMAC-DRBG. You can check to see if this override has taken effect with the following code:

    const RAND_METHOD *rm = RAND_get_rand_method();
    if(rm == RAND_SSLeay()) {
        fprintf(stderr, "After engine load, using default generator\n");
        return EXIT_FAILURE;
    } else {
        fprintf(stderr, "After engine load, NOT using default generator\n");
    }

Identifying the Algorithms

Primitives encoded as .pem or .der files have OIDs (Object Identifiers) that define which algorithms they work with. The only place where you would have to identify the desired algorithm is during creation. You can either do that with EVP_PKEY_asn1_find_str() or with EVP_PKEY_CTX_new_id().

EVP_PKEY_asn1_find_str() takes the algorithm name as a string and EVP_PKEY_CTX_new_id() takes an integer constant associated with the algorithm. Here is a table of the algorithms and their associated strings and constants.

Table 6. Algorithm Identifiers
Algorithm EVP_PKEY_asn1_find_str() EVP_PKEY_CTX_new_id()

LMS

"LMS"

EVP_PKEY_LMS

QC-MDPC

"MCQ"

EVP_PKEY_MCQ

NewHope

"NH"

EVP_PKEY_NH

LUKE

"LUKE"

EVP_PKEY_LUKE

NewHope with AES

"NHAES"

EVP_PKEY_NHAES

Setting Parameters

Each algorithm requires different parameters.

For LMS, there are winternitz_value, tree_height, split, and private_key_prefix.

For QC-MDPC (MCQ), the public key size parameter is specified.

For NewHope (NH), LUKE and NewHope with AES (NHAES) the parameter specifies whether the participant is the initiator or responder.

These parameters can be set using EVP_PKEY_CTX_ctrl() or EVP_PKEY_CTX_ctrl_str().

Table 7. Parameter Names
Parameter EVP_PKEY_CTX_ctrl() EVP_PKEY_CTX_ctrl_str()

LMS Tree Height

N/A

"tree_height"

LMS Winternitz Value

N/A

"winternitz_value"

LMS Private Key Path Prefix

N/A

"private_key_prefix"

LMS Private Key split

N/A

"split"

MCQ Public Key Size

EVP_PKEY_CTRL_MCQ_SET_PUBKEYSIZE

"pubkeysize"

NH Initiator

EVP_PKEY_CTRL_NHF_PARAMSET

N/A

LUKE Initiator

EVP_PKEY_CTRL_NHF_PARAMSET

N/A

NHAES Initiator

EVP_PKEY_CTRL_NHF_PARAMSET

N/A

For LMS tree height, the EVP_PKEY_CTX_ctrl_str() will accept the ASCII encoding of a value from 0 to 4.

Table 8. LMS Values for Tree Height
Value Tree Height

"0"

5

"1"

10

"2"

15

"3"

20

For LMS Winternitz value, the EVP_PKEY_CTX_ctrl_str() will accept the ASCII encoding of a value from 0 to 4.

Table 9. LMS Values for Winternitz Value
Value Winternitz Value

"0"

1

"1"

2

"2"

4

"3"

8

For LMS split private key, the EVP_PKEY_CTX_ctrl_str() will accept the ASCII encoding of a value from 1 to 2 to the power of tree height, which will result in a private key split into parts.

For LMS private key path prefix, the EVP_PKEY_CTX_ctrl_str() will accept a string. This will be combined with an identification string generated by the engine to create a unique file path. Verify that directories indicated in the path already exist.

For QC-MDPC public key size, the EVP_PKEY_CTX_ctrl() value must be from 0 to 5 and EVP_PKEY_CTX_ctrl_str() will accept the ASCII encoding of a value from 0 to 5.

Table 10. QC-MDPC Values for Public Key Size
Value Size in Bits Description

0

9857

128 bits of classical security.

1

14866

128 bits of classical security.

2

20409

128 bits of classical security.

3

32771

256 bits of classical security.

4

45062

256 bits of classical security.

5

61449

256 bits of classical security.

For the NewHope Family, EVP_PKEY_CTX_ctrl() accepts an integer with the following values:

Table 11. NewHope Family Values
Value Description

0

I am the Responder.

1

I am the Initiator.

Using libssl APIs For Quantum Resistant TLS Protocol Messaging

The libssl library maintains its own list of ciphersuites in priority order. The client and server negotiate a common ciphersuite based on their priorities. You can see that list by using the ciphers command.

To programmatically get a list of available cipher suites you can use SSL_get_ciphers() or SSL_get_cipher_list() which are documented on the OpenSSL.org website at https://www.openssl.org/docs/man1.0.2/ssl/SSL_get_ciphers.html

To use a specific ciphersuite:

  • Use SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value) with cmd set to "cipher" and value set to one of the strings from the ciphers command.

  • Use SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) with str set to one of the strings from the ciphers command.

  • Use SSL_set_cipher_list(SSL *ssl, const char *str) with str set to one of the strings from the ciphers command.

SSL_CONF_cmd() is documented on the OpenSSL.org website at https://www.openssl.org/docs/man1.0.2/ssl/SSL_CONF_cmd.html. SSL_CTX_set_cipher_list() and SSL_set_cipher_list() are documented at https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_set_cipher_list.html .

The ISARA Radiate OpenSSL Connector Binaries are licensed for use:

Copyright © 2017, ISARA Corporation, All Rights Reserved.

The code and other content set out herein is not in the public domain, is considered a trade secret and is confidential to ISARA Corporation. Use, reproduction or distribution, in whole or in part, of such code or other content is strictly prohibited except by express written permission of ISARA Corporation. Please contact ISARA Corporation at info@isara.com for more information.

Demonstration code and the OpenSSL patch are covered by the Apache 2.0 license:

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

  • ISARA Radiate OpenSSL Connector (ID 2039582b360d00111502b9361dbeb2c6c2a5c1d0)

  • ISARA Radiate Security Solution Suite (ID e372abc6c2f27eee2c208eaee05109067396357b)

  • ISARA Radiate Key State Manager (ID 0cc79fc3baf3963dab245f224c1b5f017b392ab0)