Running without openssl

Picoquic was originally built to use the OpenSSL functions made available through “pictotls”. There are however environments for which OpenSSL is not available, or in which loading OpenSSL is not desirable. In these environments, we want to use alternatives. Here is a list of the functions that we want, and potential alternatives.

Function Usage Alternatives
SHA256 Key derivation minicrypto. Could also use mbed or bcrypt on some platforms.
aes128gcm local secrets Minicrypto, but it is painfully slow. On x86/64, ptls_fusion works great. Bcrypt on Windows. MbedTLS on ARM.
aes128gcmsha256 Cipher suite used in initial packets, required for interop Same issue as AES_GCM_128
aes256gcmsha384 Used for higher security Pretty much same issue as AES_GCM_128. Not clear whether there is support in MbedTLS
chacha20poly1305sha256 Better performance than aes128gcm if hardware support is not available. Minicrypto, but the performance is limited. Maybe MbedTLS.
init_sign_certificate Certificate signature Minicrypto only supports some types of certificates.
set_tls_key_openssl Set the root key used to sign CERT Minicrypto, but only some types of keys.
set_tls_root_certificates Set the root certificates used for verification Maybe load some PEM file?
set_random_provider Set a random number provider Investigate. Bcrypt comes with cryptogenrandom

Software structure

The original code directly linked into openssl, while using some of the abstractions proposed by picotls. PR #1539 introduces a more structured solution, loading algorithms and function in tables, and then using function pointers or other indirection. The code:

1- Upon init, performs a series of calls to the load the functions defines by each provider, 2- Before exiting the process, performs a series of calls to unload the resources allocated when defining the functions that the provider loaded.

The call to a provider will be:

void picoquic_ptls_<example>_load(int unload)

in which the parameter unload is set to 0 for an initialization call, and 1 for the release call.

When called, the provider uses on or all of the following registration functions:

void picoquic_register_ciphersuite(ptls_cipher_suite_t* suite, int is_low_memory);
void picoquic_register_key_exchange_algorithm(ptls_key_exchange_algorithm_t* key_exchange);
void picoquic_register_tls_key_provider_fn(
    picoquic_set_private_key_from_file_t set_private_key_from_file_fn,
    picoquic_dispose_sign_certificate_t dispose_sign_certificate_fn,
    picoquic_get_certs_from_file_t get_certs_from_file_fn);

void picoquic_register_verify_certificate_fn(picoquic_get_certificate_verifier_t certificate_verifier_fn,
    picoquic_dispose_certificate_verifier_t dispose_certificate_verifier_fn,
    picoquic_set_tls_root_certificates_t set_tls_root_certificates_fn);

void picoquic_register_explain_crypto_error_fn(picoquic_explain_crypto_error_t explain_crypto_error_fn,
    picoquic_clear_crypto_errors_t clear_crypto_errors_fn);

void picoquic_register_crypto_random_provider_fn(picoquic_crypto_random_provider_t random_provider);

These functions and their arguments are defined in picoquic_crypto_provider_api.h. The code includes examples of using these functions in picoquic_ptls_minicrypto.c, picoquic_ptls_openssl.c and picoquic_ptls_fusion.c.

Compiling without OpenSSL

To create a version of picoquic that does not require OpenSSL, call cmake with the argument -DWITH_OPENSSL=OFF. This will update the list of include files and linked libraries used by picoquic. The picoquic modules will be compiled with the flag PTLS_WITHOUT_OPENSSL.

Progressive development

This is still work in progress. The current code has options for three cryptographic providers defined in picotls: minicrypto, OpenSSL and Fusion. When operating without OpenSSL, it falls back to minicrypto, which is inferior in many respects:

The AES-GCM issue is alleviated if the system supports the AES “Fusion” module, such as 64 bits x86 systems running Linux (but not Windows, because of compiler issues.) The issues could be alleviated on Windows by using the bcrypt functions, but this requires changes in the declaration of dependencies in the Visual Studio project.

We could in theory develop a Certificate Verifier that would be independent of OpenSSL, and that would only rely on cryptographic functions supported in picotls. The two big missing pieces are ASN1 parsing of certificates, and support for RSA.

The next step is to develop a wrapper for (Mbed TLS)[https://github.com/Mbed-TLS/mbedtls]. This might take some time.