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}