summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Staessens <Dimitri.Staessens@Quantum.Com>2026-01-28 00:35:28 +0100
committerSander Vrijders <sander@ouroboros.rocks>2026-02-02 08:07:04 +0100
commit37e3dbdd8206e4f0f03fab13ff3f38aa932be065 (patch)
treec7508d4a50bb8a1e6025b489418a5f9aae4a308e
parente9fb0eb1130a8efacab3add17f524197a9044a88 (diff)
downloadouroboros-37e3dbdd8206e4f0f03fab13ff3f38aa932be065.tar.gz
ouroboros-37e3dbdd8206e4f0f03fab13ff3f38aa932be065.zip
lib: Fix OpenSSL includes and explicit_bzero on OSX
The include headers and NIDs are different on macOS X. It also doesn't have explicit_bzero. The crypt.h includes are now guarded to work on OS X (trying to avoid the includes by defining the OpenSSL mac header guard led to a whole list of other issues). The explicit zero'ing of buffers temporarily holding secrets has now been abstracted in a crypt_secure_clear() function defaulting to OpenSSL_cleanse, explicit_bzero (if present) or a best-effort option using a volatile pointer. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
-rw-r--r--cmake/dependencies.cmake1
-rw-r--r--cmake/dependencies/explicit_bzero.cmake1
-rw-r--r--cmake/dependencies/openssl.cmake2
-rw-r--r--include/ouroboros/crypt.h38
-rw-r--r--src/irmd/main.c2
-rw-r--r--src/irmd/oap/cli.c6
-rw-r--r--src/lib/config.h.in1
-rw-r--r--src/lib/crypt.c21
-rw-r--r--src/lib/crypt/openssl.c6
-rw-r--r--src/lib/crypt/openssl.h3
-rw-r--r--src/lib/dev.c6
-rw-r--r--src/lib/tests/kex_test.c2
12 files changed, 68 insertions, 21 deletions
diff --git a/cmake/dependencies.cmake b/cmake/dependencies.cmake
index e9dc17a1..4c999250 100644
--- a/cmake/dependencies.cmake
+++ b/cmake/dependencies.cmake
@@ -2,6 +2,7 @@ include(FindPkgConfig)
include(CheckSymbolExists)
include(dependencies/protobufc)
+include(dependencies/explicit_bzero)
include(dependencies/systemlibraries)
include(dependencies/robustmutex)
include(dependencies/fuse)
diff --git a/cmake/dependencies/explicit_bzero.cmake b/cmake/dependencies/explicit_bzero.cmake
new file mode 100644
index 00000000..54a11d21
--- /dev/null
+++ b/cmake/dependencies/explicit_bzero.cmake
@@ -0,0 +1 @@
+check_symbol_exists(explicit_bzero "string.h" HAVE_EXPLICIT_BZERO) \ No newline at end of file
diff --git a/cmake/dependencies/openssl.cmake b/cmake/dependencies/openssl.cmake
index d679b050..b02d64b4 100644
--- a/cmake/dependencies/openssl.cmake
+++ b/cmake/dependencies/openssl.cmake
@@ -7,7 +7,7 @@ if (OPENSSL_FOUND)
else ()
set(DISABLE_OPENSSL FALSE CACHE BOOL "Disable OpenSSL support")
if (NOT DISABLE_OPENSSL)
- message(STATUS "OpenSSL support enabled")
+ message(STATUS "OpenSSL support enabled, found version ${OPENSSL_VERSION}")
set(HAVE_OPENSSL TRUE CACHE INTERNAL "")
set(DISABLE_PQC FALSE CACHE BOOL "Disable post-quantum cryptography support")
if (OPENSSL_VERSION VERSION_GREATER_EQUAL "3.4.0")
diff --git a/include/ouroboros/crypt.h b/include/ouroboros/crypt.h
index 6587a277..5b39fb5f 100644
--- a/include/ouroboros/crypt.h
+++ b/include/ouroboros/crypt.h
@@ -35,8 +35,14 @@
#define KEX_CIPHER_BUFSZ 32
#define MSGBUFSZ 2048
+/*
+ * On OSX the OpenSSL NIDs are automatically loaded with evp.h.
+ * Some have a different spelling. This header avoids the double definitions.
+ */
+
+ #define NID_undef 0
+
/* Cipher NIDs (match OpenSSL values) */
-#define NID_undef 0
#define NID_aes_128_gcm 895
#define NID_aes_192_gcm 898
#define NID_aes_256_gcm 901
@@ -45,17 +51,7 @@
#define NID_aes_256_ctr 906
#define NID_chacha20_poly1305 1018
-/* KDF NIDs (match OpenSSL values) */
-#define NID_hkdf 1036
-#define NID_sha256 672
-#define NID_sha384 673
-#define NID_sha512 674
-#define NID_sha3_256 1096
-#define NID_sha3_384 1097
-#define NID_sha3_512 1098
-#define NID_blake2b512 1056
-#define NID_blake2s256 1057
-
+ #if !defined (__APPLE__) || !defined ( HAVE_OPENSSL )
/* KEX algorithm NIDs (match OpenSSL values) */
#define NID_X9_62_prime256v1 415
#define NID_secp384r1 715
@@ -65,12 +61,27 @@
#define NID_ffdhe2048 1126
#define NID_ffdhe3072 1127
#define NID_ffdhe4096 1128
+#endif /* __APPLE__ */
#define NID_MLKEM512 1454
#define NID_MLKEM768 1455
#define NID_MLKEM1024 1456
#define NID_X25519MLKEM768 2053 /* !! not in OpenSSL */
#define NID_X448MLKEM1024 2054 /* !! not in OpenSSL */
+/* KDF NIDs (match OpenSSL values) */
+#define NID_hkdf 1036
+#define NID_sha256 672
+#define NID_sha384 673
+#define NID_sha512 674
+#if !defined (__APPLE__) || !defined ( HAVE_OPENSSL )
+#define NID_sha3_256 1096
+#define NID_sha3_384 1097
+#define NID_sha3_512 1098
+#endif /* __APPLE__ */
+#define NID_blake2b512 1056
+#define NID_blake2s256 1057
+
+
#define IS_KEM_ALGORITHM(algo) \
(strstr(algo, "ML-KEM") != NULL || strstr(algo, "MLKEM") != NULL)
@@ -351,4 +362,7 @@ void * crypt_secure_malloc(size_t size);
void crypt_secure_free(void * ptr,
size_t size);
+void crypt_secure_clear(void * ptr,
+ size_t size);
+
#endif /* OUROBOROS_LIB_CRYPT_H */
diff --git a/src/irmd/main.c b/src/irmd/main.c
index e67fdd23..5b787a24 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -1553,7 +1553,7 @@ static irm_msg_t * do_command_msg(irm_msg_t * msg)
else
ret_msg->result = res;
- explicit_bzero(kbuf, SYMMKEYSZ);
+ crypt_secure_clear(kbuf, SYMMKEYSZ);
return ret_msg;
}
diff --git a/src/irmd/oap/cli.c b/src/irmd/oap/cli.c
index 12660d7f..ea2a25d1 100644
--- a/src/irmd/oap/cli.c
+++ b/src/irmd/oap/cli.c
@@ -191,7 +191,7 @@ static int do_client_kex_prepare_kem_encap(const char * server_name,
return -ENOMEM;
}
memcpy(s->key, key_buf, SYMMKEYSZ);
- explicit_bzero(key_buf, SYMMKEYSZ);
+ crypt_secure_clear(key_buf, SYMMKEYSZ);
return 0;
}
@@ -395,7 +395,7 @@ static int do_client_kex_complete_kem(struct oap_cli_ctx * s,
memcpy(sk->key, key_buf, SYMMKEYSZ);
sk->nid = kcfg->c.nid;
- explicit_bzero(key_buf, SYMMKEYSZ);
+ crypt_secure_clear(key_buf, SYMMKEYSZ);
log_info_id(id, "Negotiated %s + %s.", kcfg->x.str, kcfg->c.str);
@@ -425,7 +425,7 @@ static int do_client_kex_complete_dhe(struct oap_cli_ctx * s,
memcpy(sk->key, key_buf, SYMMKEYSZ);
sk->nid = kcfg->c.nid;
- explicit_bzero(key_buf, SYMMKEYSZ);
+ crypt_secure_clear(key_buf, SYMMKEYSZ);
log_info_id(id, "Negotiated %s + %s.", kcfg->x.str, kcfg->c.str);
diff --git a/src/lib/config.h.in b/src/lib/config.h.in
index b2b17669..6065ac41 100644
--- a/src/lib/config.h.in
+++ b/src/lib/config.h.in
@@ -21,6 +21,7 @@
*/
#cmakedefine HAVE_SYS_RANDOM
+#cmakedefine HAVE_EXPLICIT_BZERO
#cmakedefine HAVE_LIBGCRYPT
#cmakedefine HAVE_OPENSSL
#ifdef HAVE_OPENSSL
diff --git a/src/lib/crypt.c b/src/lib/crypt.c
index fdbae776..38dd9f29 100644
--- a/src/lib/crypt.c
+++ b/src/lib/crypt.c
@@ -1064,3 +1064,24 @@ void crypt_secure_free(void * ptr,
free(ptr);
#endif
}
+
+void crypt_secure_clear(void * ptr,
+ size_t size)
+{
+ volatile uint8_t * p;
+
+ if (ptr == NULL)
+ return;
+
+#ifdef HAVE_OPENSSL
+ (void) p;
+ openssl_secure_clear(ptr, size);
+#elif defined(HAVE_EXPLICIT_BZERO)
+ (void) p;
+ explicit_bzero(ptr, size);
+#else /* best effort to avoid optimizing out */
+ p = ptr;
+ while (size-- > 0)
+ *p++ = 0;
+#endif
+}
diff --git a/src/lib/crypt/openssl.c b/src/lib/crypt/openssl.c
index b8233593..232aa6c9 100644
--- a/src/lib/crypt/openssl.c
+++ b/src/lib/crypt/openssl.c
@@ -1872,3 +1872,9 @@ void openssl_secure_free(void * ptr)
{
OPENSSL_secure_free(ptr);
}
+
+void openssl_secure_clear(void * ptr,
+ size_t size)
+{
+ OPENSSL_cleanse(ptr, size);
+}
diff --git a/src/lib/crypt/openssl.h b/src/lib/crypt/openssl.h
index 083e8dde..a6bb5840 100644
--- a/src/lib/crypt/openssl.h
+++ b/src/lib/crypt/openssl.h
@@ -166,4 +166,7 @@ void * openssl_secure_malloc(size_t size);
void openssl_secure_free(void * ptr,
size_t size);
+void openssl_secure_clear(void * ptr,
+ size_t size);
+
#endif /* OUROBOROS_LIB_CRYPT_OPENSSL_H */
diff --git a/src/lib/dev.c b/src/lib/dev.c
index 35ea701b..fb06c496 100644
--- a/src/lib/dev.c
+++ b/src/lib/dev.c
@@ -870,7 +870,7 @@ int flow_accept(qosspec_t * qs,
fd = flow_init(&flow, &crypt);
- explicit_bzero(key, SYMMKEYSZ);
+ crypt_secure_clear(key, SYMMKEYSZ);
if (qs != NULL)
*qs = flow.qs;
@@ -917,7 +917,7 @@ int flow_alloc(const char * dst,
fd = flow_init(&flow, &crypt);
- explicit_bzero(key, SYMMKEYSZ);
+ crypt_secure_clear(key, SYMMKEYSZ);
if (qs != NULL)
*qs = flow.qs;
@@ -956,7 +956,7 @@ int flow_join(const char * dst,
fd = flow_init(&flow, &crypt);
- explicit_bzero(key, SYMMKEYSZ);
+ crypt_secure_clear(key, SYMMKEYSZ);
return fd;
}
diff --git a/src/lib/tests/kex_test.c b/src/lib/tests/kex_test.c
index 58cf8b43..0a588550 100644
--- a/src/lib/tests/kex_test.c
+++ b/src/lib/tests/kex_test.c
@@ -574,7 +574,7 @@ static int test_kex_parse_config_empty(void)
memset(&kex, 0, sizeof(kex));
- fp = FMEMOPEN_STR("");
+ fp = FMEMOPEN_STR("\n");
if (fp == NULL) {
printf("Failed to open memory stream.\n");
goto fail;