From 58a2c116de9d25fbb6a53e673be5b7238b092eec Mon Sep 17 00:00:00 2001 From: Basil Hess Date: Mon, 20 Mar 2023 11:01:03 +0100 Subject: [PATCH] - Add key encoding options to README.md - Allow to pass options to runtests_encodings.sh - Add qsc_encoder version strings --- CMakeLists.txt | 6 +++--- README.md | 28 ++++++++++++++++++++++++++++ oqsprov/CMakeLists.txt | 6 +++--- oqsprov/oqs_encode_key2any.c | 8 ++++---- oqsprov/oqs_prov.h | 19 ++++++++++++++----- oqsprov/oqsprov.c | 9 ++++++++- oqsprov/oqsprov_keys.c | 12 ++++++------ scripts/runtests_encodings.sh | 2 +- 8 files changed, 67 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 85ca21a3..d8a648d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,10 +17,10 @@ if(${NOPUBKEY_IN_PRIVKEY}) else() message(STATUS "Build will store public keys in PKCS#8 structures") endif() -option(BUILD_ENCODING_LIB "Build with external encoding library for SPKI/PKCS#8 " ON) -if(${BUILD_ENCODING_LIB}) +option(USE_ENCODING_LIB "Build with external encoding library for SPKI/PKCS#8 " ON) +if(${USE_ENCODING_LIB}) message(STATUS "Build will include external encoding library for SPKI/PKCS#8") - add_compile_definitions( BUILD_ENCODING_LIB ) + add_compile_definitions( USE_ENCODING_LIB ) else() message(STATUS "Build will not include external encoding library for SPKI/PKCS#8") endif() diff --git a/README.md b/README.md index e1813f5a..99b7d97f 100644 --- a/README.md +++ b/README.md @@ -178,6 +178,34 @@ excludes all algorithms of the "Sphincs" family. *Note*: By default, interoperability testing with oqs-openssl111 is no longer performed by default but can be manually enabled in the script `scripts/runtests.sh`. +### Key Encoding + +By setting environment variables, oqs-provider can be configured to encode keys (subjectPublicKey and and privateKey ASN.1 structures) according to IETF drafts: + +| Environment Variable | Permissible values | +| --- | --- | +| `OQS_ENCODING_DILITHIUM2` | `draft-uni-qsckeys-dilithium-00/sk-pk` | +| `OQS_ENCODING_DILITHIUM3` | `draft-uni-qsckeys-dilithium-00/sk-pk` | +| `OQS_ENCODING_DILITHIUM5` | `draft-uni-qsckeys-dilithium-00/sk-pk` | +| `OQS_ENCODING_DILITHIUM2_AES` | `draft-uni-qsckeys-dilithium-00/sk-pk` | +| `OQS_ENCODING_DILITHIUM3_AES` | `draft-uni-qsckeys-dilithium-00/sk-pk` | +| `OQS_ENCODING_DILITHIUM5_AES` | `draft-uni-qsckeys-dilithium-00/sk-pk` | +| `OQS_ENCODING_FALCON512` | `draft-uni-qsckeys-falcon-00/sk-pk` | +| `OQS_ENCODING_FALCON1024` | `draft-uni-qsckeys-falcon-00/sk-pk` | +| `OQS_ENCODING_SPHINCSHARAKA128FROBUST` | `draft-uni-qsckeys-sphincsplus-00/sk-pk` | +| `OQS_ENCODING_SPHINCSHARAKA128FSIMPLE` | `draft-uni-qsckeys-sphincsplus-00/sk-pk` | +| `OQS_ENCODING_SPHINCSSHA256128FROBUST` | `draft-uni-qsckeys-sphincsplus-00/sk-pk` | +| `OQS_ENCODING_SPHINCSSHA256128SSIMPLE` | `draft-uni-qsckeys-sphincsplus-00/sk-pk` | +| `OQS_ENCODING_SPHINCSSHAKE256128FSIMPLE` | `draft-uni-qsckeys-sphincsplus-00/sk-pk` | + +If no environment variable is set, or if an unknown value is set, the default is 'no' encoding, meaning that key serialization uses the 'raw' keys of the crypto implementations. + +The test script `scripts/runtests_encodings.sh` (instead of `scripts/runtests.sh`) can be used for a test run with all supported encodings activated. + +By setting `-DUSE_ENCODING_LIB=OFF` at compile-time, oqs-provider can be optionally compiled without support for the IETF drafts for key encodings. The default value is `ON`. + +By setting `-DNOPUBKEY_IN_PRIVKEY` at compile-time, it can be further specified to omit explicitly serializing the public key in a `privateKey` structure. The default value is `OFF`. + Building on Windows -------------------- The following steps have been tested on Windows 10 and 11 using MSYS2 MINGW64 and were successful. However, building with Visual Studio 2019 was unsuccessful (see [#47](https://github.com/open-quantum-safe/oqs-provider/issues/47)). Note that the process of building on Windows is considered experimental and may need further adjustments. Please report further issues to [#47](https://github.com/open-quantum-safe/oqs-provider/issues/47). Despite skipping the testing process, setting up a test server and client with post-quantum cryptography algorithms can still be accomplished. diff --git a/oqsprov/CMakeLists.txt b/oqsprov/CMakeLists.txt index 8797ecaa..021c52c5 100644 --- a/oqsprov/CMakeLists.txt +++ b/oqsprov/CMakeLists.txt @@ -5,7 +5,7 @@ execute_process( OUTPUT_VARIABLE GIT_COMMIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE ) -if (BUILD_ENCODING_LIB) +if (USE_ENCODING_LIB) include(ExternalProject) set(encoder_LIBRARY ${CMAKE_BINARY_DIR}/install/lib/${CMAKE_STATIC_LIBRARY_PREFIX}qsc_key_encoder${CMAKE_STATIC_LIBRARY_SUFFIX}) set(encoder_LIBRARY_INCLUDE ${CMAKE_BINARY_DIR}/install/include) @@ -33,7 +33,7 @@ set(PROVIDER_HEADER_FILES oqs_prov.h oqs_endecoder_local.h ) add_library(oqsprovider SHARED ${PROVIDER_SOURCE_FILES}) -if (BUILD_ENCODING_LIB) +if (USE_ENCODING_LIB) add_dependencies(oqsprovider encoder) endif() set_target_properties(oqsprovider @@ -47,7 +47,7 @@ set_target_properties(oqsprovider # For Windows DLLs RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") target_link_libraries(oqsprovider OQS::oqs ${OPENSSL_CRYPTO_LIBRARY}) -if (BUILD_ENCODING_LIB) +if (USE_ENCODING_LIB) target_link_libraries(oqsprovider qsc_key_encoder) target_include_directories(oqsprovider PRIVATE ${encoder_LIBRARY_INCLUDE}) endif() diff --git a/oqsprov/oqs_encode_key2any.c b/oqsprov/oqs_encode_key2any.c index 731cef8b..4dfb2a24 100644 --- a/oqsprov/oqs_encode_key2any.c +++ b/oqsprov/oqs_encode_key2any.c @@ -512,7 +512,7 @@ static int oqsx_spki_pub_to_der(const void *vxkey, unsigned char **pder) ERR_raise(ERR_LIB_USER, ERR_R_PASSED_NULL_PARAMETER); return 0; } -#ifdef BUILD_ENCODING_LIB +#ifdef USE_ENCODING_LIB if (oqsxkey->oqsx_encoding_ctx.encoding_ctx != NULL && oqsxkey->oqsx_encoding_ctx.encoding_impl != NULL) { unsigned char *buf; int buflen; @@ -535,7 +535,7 @@ static int oqsx_spki_pub_to_der(const void *vxkey, unsigned char **pder) } *pder = keyblob; return oqsxkey->pubkeylen; -#ifdef BUILD_ENCODING_LIB +#ifdef USE_ENCODING_LIB } #endif } @@ -575,7 +575,7 @@ static int oqsx_pki_priv_to_der(const void *vxkey, unsigned char **pder) } privkeylen -= (oqsxkey->evp_info->length_private_key - actualprivkeylen); } -#ifdef BUILD_ENCODING_LIB +#ifdef USE_ENCODING_LIB if (oqsxkey->oqsx_encoding_ctx.encoding_ctx != NULL && oqsxkey->oqsx_encoding_ctx.encoding_impl != NULL) { const OQSX_ENCODING_CTX* encoding_ctx = &oqsxkey->oqsx_encoding_ctx; int ret = 0; @@ -606,7 +606,7 @@ static int oqsx_pki_priv_to_der(const void *vxkey, unsigned char **pder) memcpy(buf, oqsxkey->privkey, privkeylen); memcpy(buf+privkeylen, oqsxkey->comp_pubkey[oqsxkey->numkeys-1], oqsx_key_get_oqs_public_key_len(oqsxkey)); #endif -#ifdef BUILD_ENCODING_LIB +#ifdef USE_ENCODING_LIB } #endif diff --git a/oqsprov/oqs_prov.h b/oqsprov/oqs_prov.h index d8d55d43..89abde00 100644 --- a/oqsprov/oqs_prov.h +++ b/oqsprov/oqs_prov.h @@ -25,11 +25,20 @@ #define OQS_PROVIDER_BASE_VERSION_STR OQSPROVIDER_VERSION_TEXT #ifdef NOPUBKEY_IN_PRIVKEY -#define OQS_PROVIDER_VERSION_STR OQS_PROVIDER_BASE_VERSION_STR "-nopub" +#define NOPUBKEY_IN_PRIVKEY_STR "-nopub" #else -#define OQS_PROVIDER_VERSION_STR OQS_PROVIDER_BASE_VERSION_STR +#define NOPUBKEY_IN_PRIVKEY_STR "" #endif +#ifdef USE_ENCODING_LIB +#define ENCODING_LIB_STR "-encoding_support" +#else +#define ENCODING_LIB_STR "" +#endif + +#define OQS_PROVIDER_VERSION_STR OQS_PROVIDER_BASE_VERSION_STR NOPUBKEY_IN_PRIVKEY_STR ENCODING_LIB_STR + + /* internal, but useful OSSL define */ # define OSSL_NELEM(x) (sizeof(x)/sizeof((x)[0])) @@ -101,7 +110,7 @@ void oqsx_freeprovctx(PROV_OQS_CTX *ctx); # define PROV_OQS_LIBCTX_OF(provctx) (((PROV_OQS_CTX *)provctx)->libctx) #include "oqs/oqs.h" -#ifdef BUILD_ENCODING_LIB +#ifdef USE_ENCODING_LIB #include #endif @@ -140,7 +149,7 @@ struct oqsx_provider_ctx_st { typedef struct oqsx_provider_ctx_st OQSX_PROVIDER_CTX; -#ifdef BUILD_ENCODING_LIB +#ifdef USE_ENCODING_LIB struct oqsx_provider_encoding_ctx_st { const qsc_encoding_t* encoding_ctx; const qsc_encoding_impl_t* encoding_impl; @@ -160,7 +169,7 @@ struct oqsx_key_st { char *propq; OQSX_KEY_TYPE keytype; OQSX_PROVIDER_CTX oqsx_provider_ctx; -#ifdef BUILD_ENCODING_LIB +#ifdef USE_ENCODING_LIB OQSX_ENCODING_CTX oqsx_encoding_ctx; #endif EVP_PKEY *classical_pkey; // for hybrid sigs diff --git a/oqsprov/oqsprov.c b/oqsprov/oqsprov.c index 77042d85..f9ee580a 100644 --- a/oqsprov/oqsprov.c +++ b/oqsprov/oqsprov.c @@ -463,7 +463,14 @@ static const OSSL_PARAM *oqsprovider_gettable_params(void *provctx) return oqsprovider_param_types; } -#define OQS_PROVIDER_BUILD_INFO_STR "OQS Provider v." OQS_PROVIDER_VERSION_STR OQS_PROVIDER_COMMIT " based on liboqs v." OQS_VERSION_TEXT +#define OQS_PROVIDER_BASE_BUILD_INFO_STR "OQS Provider v." OQS_PROVIDER_VERSION_STR OQS_PROVIDER_COMMIT " based on liboqs v." OQS_VERSION_TEXT + +#ifdef QSC_ENCODING_VERSION_STRING +#define OQS_PROVIDER_BUILD_INFO_STR OQS_PROVIDER_BASE_BUILD_INFO_STR " using qsc-key-encoder v." QSC_ENCODING_VERSION_STRING +#else +#define OQS_PROVIDER_BUILD_INFO_STR OQS_PROVIDER_BASE_BUILD_INFO_STR +#endif + static int oqsprovider_get_params(void *provctx, OSSL_PARAM params[]) { diff --git a/oqsprov/oqsprov_keys.c b/oqsprov/oqsprov_keys.c index 3be8c791..a9e506ab 100644 --- a/oqsprov/oqsprov_keys.c +++ b/oqsprov/oqsprov_keys.c @@ -261,7 +261,7 @@ static OQSX_KEY *oqsx_key_op(const X509_ALGOR *palg, } if (op == KEY_OP_PUBLIC) { -#ifdef BUILD_ENCODING_LIB +#ifdef USE_ENCODING_LIB if (key->oqsx_encoding_ctx.encoding_ctx && key->oqsx_encoding_ctx.encoding_impl) { key->pubkeylen = key->oqsx_encoding_ctx.encoding_ctx->raw_crypto_publickeybytes; if (key->oqsx_encoding_ctx.encoding_impl->crypto_publickeybytes != plen) { @@ -287,7 +287,7 @@ static OQSX_KEY *oqsx_key_op(const X509_ALGOR *palg, goto err; } memcpy(key->pubkey, p, plen); -#ifdef BUILD_ENCODING_LIB +#ifdef USE_ENCODING_LIB } #endif } else { @@ -305,7 +305,7 @@ static OQSX_KEY *oqsx_key_op(const X509_ALGOR *palg, } actualprivkeylen -= (key->evp_info->length_private_key - classical_privatekey_len); } -#ifdef BUILD_ENCODING_LIB +#ifdef USE_ENCODING_LIB if (key->oqsx_encoding_ctx.encoding_ctx && key->oqsx_encoding_ctx.encoding_impl) { const qsc_encoding_t* encoding_ctx = key->oqsx_encoding_ctx.encoding_ctx; #ifdef NOPUBKEY_IN_PRIVKEY @@ -371,7 +371,7 @@ static OQSX_KEY *oqsx_key_op(const X509_ALGOR *palg, memcpy(key->pubkey, p+key->privkeylen, plen-key->privkeylen); #endif } -#ifdef BUILD_ENCODING_LIB +#ifdef USE_ENCODING_LIB } #endif ret = oqsx_key_set_composites(key); @@ -616,10 +616,10 @@ OQSX_KEY *oqsx_key_new(OSSL_LIB_CTX *libctx, char* oqs_name, char* tls_name, int } if (alg_idx >= 0 && oqs_alg_encoding_list[alg_idx] != NULL) { -#ifdef BUILD_ENCODING_LIB +#ifdef USE_ENCODING_LIB if (qsc_encoding_by_name_oid(&ret->oqsx_encoding_ctx.encoding_ctx, &ret->oqsx_encoding_ctx.encoding_impl, oqs_oid_alg_list[2*alg_idx], oqs_alg_encoding_list[alg_idx]) != QSC_ENC_OK) { fprintf(stderr, "Could not create OQS signature encoding algorithm %s (%s, %s). Defaulting to no encoding.\n", oqs_alg_encoding_list[alg_idx], oqs_name, oqs_oid_alg_list[2*alg_idx]); - ret->oqsx_encoding_ctx.encoding_ctx = NULL; + ret->oqsx_encoding_ctx.encoding_ctx = NULL; ret->oqsx_encoding_ctx.encoding_impl = NULL; } #else diff --git a/scripts/runtests_encodings.sh b/scripts/runtests_encodings.sh index 4f07dad7..ae041eba 100755 --- a/scripts/runtests_encodings.sh +++ b/scripts/runtests_encodings.sh @@ -13,4 +13,4 @@ OQS_ENCODING_SPHINCSHARAKA128FSIMPLE=draft-uni-qsckeys-sphincsplus-00/sk-pk \ OQS_ENCODING_SPHINCSSHA256128FROBUST=draft-uni-qsckeys-sphincsplus-00/sk-pk \ OQS_ENCODING_SPHINCSSHA256128SSIMPLE=draft-uni-qsckeys-sphincsplus-00/sk-pk \ OQS_ENCODING_SPHINCSSHAKE256128FSIMPLE=draft-uni-qsckeys-sphincsplus-00/sk-pk \ -scripts/runtests.sh \ No newline at end of file +scripts/runtests.sh $@ \ No newline at end of file