openssl_crypto_only/lib.rs
1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Provides a macro for ensuring only `libcrypto` is linked and not `libssl`.
5
6#![cfg(unix)]
7// UNSAFETY: needed for exporting unmangled names and importing openssl
8// routines.
9#![expect(unsafe_code)]
10#![no_std]
11
12use core::ffi::c_int;
13use core::ffi::c_void;
14
15unsafe extern "C" {
16 #[doc(hidden)]
17 pub fn OPENSSL_init_crypto(opts: u64, settings: *const c_void) -> c_int;
18}
19
20/// Ensure only libcrypto is linked by its use in the `openssl` crate, instead
21/// of both libssl and libcrypto.
22///
23/// The `openssl` crate calls `OPENSSL_init_ssl` unconditionally, which
24/// initializes both libcrypto and libssl.
25///
26/// This module redefines `OPENSSL_init_ssl` so that it calls
27/// `OPENSSL_init_crypto` instead. As a result, the linker will skip pulling in
28/// and initializing libssl.
29#[macro_export]
30macro_rules! openssl_crypto_only {
31 () => {
32 /// # Safety
33 ///
34 /// The caller must call as documented for `OPENSSL_init_ssl`.
35 // SAFETY: We are purposefully overriding this symbol and we have made
36 // sure the definition is compatible with the original.
37 #[unsafe(no_mangle)]
38 unsafe extern "C" fn OPENSSL_init_ssl(
39 opts: u64,
40 settings: *const ::core::ffi::c_void,
41 ) -> ::core::ffi::c_int {
42 // SAFETY: this method has the same interface as `OPENSSL_init_ssl`, so this
43 // is guaranteed by the caller.
44 unsafe { $crate::OPENSSL_init_crypto(opts, settings) }
45 }
46 };
47}