From c883d9cd470b5c9ee5022d5df759f4a08f2281a3 Mon Sep 17 00:00:00 2001 From: Michael Baentsch <57787676+baentsch@users.noreply.github.com> Date: Tue, 13 Jun 2023 04:37:48 +0000 Subject: [PATCH] Enable building on platforms without _Atomic support (#183) * increase release to dev & make _Atomic switchable Signed-off-by: Felipe Ventura --- CMakeLists.txt | 11 ++++++++++- RELEASE.md | 17 +++++++++++++++-- oqsprov/CMakeLists.txt | 3 --- oqsprov/oqs_kmgmt.c | 2 +- oqsprov/oqs_prov.h | 16 +++++++++++++++- oqsprov/oqsprov_keys.c | 29 +++++++++++++++++++++++++---- test/oqs_test_tlssig.c | 2 ++ 7 files changed, 68 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 43da3815..19c725bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.0 FATAL_ERROR) project(oqs-provider LANGUAGES C) -set(OQSPROVIDER_VERSION_TEXT "0.5.0") +set(OQSPROVIDER_VERSION_TEXT "0.5.1-dev") set(CMAKE_C_STANDARD 11) set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS ON) if(CMAKE_BUILD_TYPE STREQUAL "Debug") @@ -10,6 +10,15 @@ else() add_definitions( -DNDEBUG ) endif() +if(MSVC) + set(CMAKE_EXE_LINKER_FLAGS + "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB:LIBCMT") + add_definitions(-DOQS_PROVIDER_NOATOMIC) + add_definitions(-D_CRT_SECURE_NO_WARNINGS) +else() + add_compile_options(-Wunused-function) +endif() + option(NOPUBKEY_IN_PRIVKEY "Do not include public keys in private key structures/PKCS#8 " OFF) if(${NOPUBKEY_IN_PRIVKEY}) message(STATUS "Build will not store public keys alongside private keys in PKCS#8 structures") diff --git a/RELEASE.md b/RELEASE.md index 6d7ff195..61ec9ee3 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,5 +1,5 @@ -oqs-provider 0.5.0 -================== +oqs-provider 0.5.1-dev +====================== About ----- @@ -17,6 +17,19 @@ Further details on building, testing and use can be found in [README.md](https:/ Release notes ============= +This is version 0.5.1-dev of oqs-provider. + +Security considerations +----------------------- + +None. + +What's New +---------- + +Previous Release Notes +====================== + This is version 0.5.0 of oqs-provider. Security considerations diff --git a/oqsprov/CMakeLists.txt b/oqsprov/CMakeLists.txt index fd1e2e0e..bd6e942f 100644 --- a/oqsprov/CMakeLists.txt +++ b/oqsprov/CMakeLists.txt @@ -22,9 +22,6 @@ endif() add_definitions(-DOQSPROVIDER_VERSION_TEXT="${OQSPROVIDER_VERSION_TEXT}") message(STATUS "Building commit ${GIT_COMMIT_HASH} in ${CMAKE_SOURCE_DIR}") add_definitions(-DOQS_PROVIDER_COMMIT=" \(${GIT_COMMIT_HASH}\)") -if (NOT WIN32) -add_compile_options(-Wunused-function) -endif() set(PROVIDER_SOURCE_FILES oqsprov.c oqsprov_capabilities.c oqsprov_keys.c oqs_kmgmt.c oqs_sig.c oqs_kem.c diff --git a/oqsprov/oqs_kmgmt.c b/oqsprov/oqs_kmgmt.c index f7f13525..a8148330 100644 --- a/oqsprov/oqs_kmgmt.c +++ b/oqsprov/oqs_kmgmt.c @@ -320,7 +320,7 @@ static int oqsx_get_params(void *key, OSSL_PARAM params[]) if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY)) != NULL) { // hybrid KEMs are special in that the classic length information shall not be passed out: if (oqsxk->keytype == KEY_TYPE_ECP_HYB_KEM || oqsxk->keytype == KEY_TYPE_ECX_HYB_KEM) { - if (!OSSL_PARAM_set_octet_string(p, oqsxk->pubkey+SIZE_OF_UINT32, oqsxk->pubkeylen-SIZE_OF_UINT32)) + if (!OSSL_PARAM_set_octet_string(p, (char*)oqsxk->pubkey+SIZE_OF_UINT32, oqsxk->pubkeylen-SIZE_OF_UINT32)) return 0; } else { diff --git a/oqsprov/oqs_prov.h b/oqsprov/oqs_prov.h index ac5302fc..befc5a9a 100644 --- a/oqsprov/oqs_prov.h +++ b/oqsprov/oqs_prov.h @@ -12,7 +12,10 @@ #ifndef OQSX_H # define OQSX_H +#ifndef OQS_PROVIDER_NOATOMIC # include +#endif + # include # include @@ -24,6 +27,11 @@ /* internal, but useful OSSL define */ # define OSSL_NELEM(x) (sizeof(x)/sizeof((x)[0])) +#ifdef _MSC_VER +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#endif + /* oqsprovider error codes */ #define OQSPROV_R_INVALID_DIGEST 1 #define OQSPROV_R_INVALID_SIZE 2 @@ -133,6 +141,9 @@ typedef enum oqsx_key_type_en OQSX_KEY_TYPE; struct oqsx_key_st { OSSL_LIB_CTX *libctx; +#ifdef OQS_PROVIDER_NOATOMIC + CRYPTO_RWLOCK *lock; +#endif char *propq; OQSX_KEY_TYPE keytype; OQSX_PROVIDER_CTX oqsx_provider_ctx; @@ -149,7 +160,10 @@ struct oqsx_key_st { size_t pubkeylen; size_t bit_security; char *tls_name; - _Atomic int references; +#ifndef OQS_PROVIDER_NOATOMIC + _Atomic +#endif + int references; /* point to actual priv key material -- classic key, if present, first * i.e., OQS key always at comp_*key[numkeys-1] diff --git a/oqsprov/oqsprov_keys.c b/oqsprov/oqsprov_keys.c index 8d18b95d..825aa2c4 100644 --- a/oqsprov/oqsprov_keys.c +++ b/oqsprov/oqsprov_keys.c @@ -136,18 +136,18 @@ static int oqsx_key_set_composites(OQSX_KEY *key) { int classic_pubkey_len, classic_privkey_len; if (key->privkey) { - key->comp_privkey[0] = key->privkey + SIZE_OF_UINT32; + key->comp_privkey[0] = (char*)key->privkey + SIZE_OF_UINT32; DECODE_UINT32(classic_privkey_len, key->privkey); - key->comp_privkey[1] = key->privkey + classic_privkey_len + SIZE_OF_UINT32; + key->comp_privkey[1] = (char*)key->privkey + classic_privkey_len + SIZE_OF_UINT32; } else { key->comp_privkey[0] = NULL; key->comp_privkey[1] = NULL; } if (key->pubkey) { - key->comp_pubkey[0] = key->pubkey + SIZE_OF_UINT32; + key->comp_pubkey[0] = (char*)key->pubkey + SIZE_OF_UINT32; DECODE_UINT32(classic_pubkey_len, key->pubkey); - key->comp_pubkey[1] = key->pubkey + classic_pubkey_len + SIZE_OF_UINT32; + key->comp_pubkey[1] = (char*)key->pubkey + classic_pubkey_len + SIZE_OF_UINT32; } else { @@ -612,6 +612,14 @@ OQSX_KEY *oqsx_key_new(OSSL_LIB_CTX *libctx, char* oqs_name, char* tls_name, int if (ret == NULL) goto err; +#ifdef OQS_PROVIDER_NOATOMIC + ret->lock = CRYPTO_THREAD_lock_new(); + if (ret->lock == NULL) { + OPENSSL_free(ret); + goto err; + } +#endif + if (oqs_name == NULL) { OQS_KEY_PRINTF("OQSX_KEY: Fatal error: No OQS key name provided:\n"); goto err; @@ -735,10 +743,15 @@ void oqsx_key_free(OQSX_KEY *key) if (key == NULL) return; +#ifndef OQS_PROVIDER_NOATOMIC refcnt = atomic_fetch_sub_explicit(&key->references, 1, memory_order_relaxed) - 1; if (refcnt == 0) atomic_thread_fence(memory_order_acquire); +#else + CRYPTO_atomic_add(&key->references, -1, &refcnt, key->lock); +#endif + OQS_KEY_PRINTF3("%p:%4d:OQSX_KEY\n", (void*)key, refcnt); if (refcnt > 0) return; @@ -762,6 +775,9 @@ void oqsx_key_free(OQSX_KEY *key) } else OQS_SIG_free(key->oqsx_provider_ctx.oqsx_qs_ctx.sig); OPENSSL_free(key->classical_pkey); +#ifdef OQS_PROVIDER_NOATOMIC + CRYPTO_THREAD_lock_free(key->lock); +#endif OPENSSL_free(key); } @@ -769,8 +785,13 @@ int oqsx_key_up_ref(OQSX_KEY *key) { int refcnt; +#ifndef OQS_PROVIDER_NOATOMIC refcnt = atomic_fetch_add_explicit(&key->references, 1, memory_order_relaxed) + 1; +#else + CRYPTO_atomic_add(&key->references, 1, &refcnt, key->lock); +#endif + OQS_KEY_PRINTF3("%p:%4d:OQSX_KEY\n", (void*)key, refcnt); #ifndef NDEBUG assert(refcnt > 1); diff --git a/test/oqs_test_tlssig.c b/test/oqs_test_tlssig.c index 12aa6885..d720b230 100644 --- a/test/oqs_test_tlssig.c +++ b/test/oqs_test_tlssig.c @@ -63,6 +63,7 @@ static int test_oqs_tlssig(const char *sig_name) return ret; } +/* reactivate when EVP_SIGNATURE_do_all_provided doesn't crash any more: static void test_oqs_sigs(EVP_SIGNATURE *evpsig, void *vp) { OSSL_PROVIDER* prov = EVP_SIGNATURE_get0_provider(evpsig); if (!strcmp(OSSL_PROVIDER_get0_name(prov), "oqsprovider")) { @@ -70,6 +71,7 @@ static void test_oqs_sigs(EVP_SIGNATURE *evpsig, void *vp) { test_oqs_tlssig(EVP_SIGNATURE_get0_name(evpsig)); } } +*/ static int test_signature(const OSSL_PARAM params[], void *data) {