diff --git a/.github/workflows/rust-wrapper.yml b/.github/workflows/rust-wrapper.yml new file mode 100644 index 00000000000..634df1d994a --- /dev/null +++ b/.github/workflows/rust-wrapper.yml @@ -0,0 +1,30 @@ +name: Build Rust Wrapper + +# START OF COMMON SECTION +on: + push: + branches: [ 'master', 'main', 'release/**' ] + pull_request: + branches: [ '*' ] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true +# END OF COMMON SECTION + +jobs: + build_wolfssl: + name: Build wolfSSL Rust Wrapper + if: github.repository_owner == 'wolfssl' + runs-on: ubuntu-24.04 + # This should be a safe limit for the tests to run. + timeout-minutes: 10 + steps: + - name: Build wolfSSL + uses: wolfSSL/actions-build-autotools-project@v1 + with: + path: wolfssl + configure: --enable-all + - name: Build Rust Wrapper + working-directory: wolfssl + run: make -C wrapper/rust diff --git a/.gitignore b/.gitignore index f5544aa7986..d618c27064d 100644 --- a/.gitignore +++ b/.gitignore @@ -33,7 +33,7 @@ aclocal.m4 aminclude.am lt*.m4 Makefile.in -Makefile +/Makefile depcomp missing libtool @@ -457,6 +457,9 @@ wrapper/Ada/config/ wrapper/Ada/lib/ wrapper/Ada/obj/ +# Rust wrapper files +/wrapper/rust/*/target/ + # PlatformIO /**/.pio /**/.vscode/.browse.c_cpp.db* diff --git a/wrapper/include.am b/wrapper/include.am index 0bdcbc78ff5..e0e76aabfdf 100644 --- a/wrapper/include.am +++ b/wrapper/include.am @@ -4,5 +4,6 @@ include wrapper/Ada/include.am include wrapper/CSharp/include.am +include wrapper/rust/include.am EXTRA_DIST+= wrapper/python/README.md diff --git a/wrapper/rust/Makefile b/wrapper/rust/Makefile new file mode 100644 index 00000000000..ffe2ae8bbf3 --- /dev/null +++ b/wrapper/rust/Makefile @@ -0,0 +1,9 @@ +.PHONY: all +all: + +$(MAKE) -C wolfssl-sys + +$(MAKE) -C wolfssl + +.PHONY: clean +clean: + +$(MAKE) -C wolfssl-sys clean + +$(MAKE) -C wolfssl clean diff --git a/wrapper/rust/README.md b/wrapper/rust/README.md new file mode 100644 index 00000000000..417645f52b6 --- /dev/null +++ b/wrapper/rust/README.md @@ -0,0 +1,17 @@ +# wolfSSL Rust Wrapper + +## Building the wolfssl Rust Wrapper + +First, configure and build wolfssl C library. + +Then build the wolfssl Rust wrapper with: + + make -C wrapper/rust + +## Repository Directory Structure + +| Repository Directory | Description | +| --- | --- | +| `/wrapper/rust` | Top level container for all Rust wrapper functionality. | +| `/wrapper/rust/wolfssl` | Top level for the `wolfssl` library crate. This crate contains high-level Rust sources that use the bindings from the `wolfssl-sys` crate. | +| `/wrapper/rust/wolfssl-sys` | Top level for the `wolfssl-sys` library crate. This crate contains only automatically generated bindings to the `wolfssl` C library. | diff --git a/wrapper/rust/include.am b/wrapper/rust/include.am new file mode 100644 index 00000000000..b70e866e4b3 --- /dev/null +++ b/wrapper/rust/include.am @@ -0,0 +1,16 @@ +# vim:ft=automake +# included from Top Level Makefile.am +# All paths should be given relative to the root + +EXTRA_DIST += wrapper/rust/Makefile +EXTRA_DIST += wrapper/rust/README.md +EXTRA_DIST += wrapper/rust/wolfssl-sys/Cargo.lock +EXTRA_DIST += wrapper/rust/wolfssl-sys/Cargo.toml +EXTRA_DIST += wrapper/rust/wolfssl-sys/Makefile +EXTRA_DIST += wrapper/rust/wolfssl-sys/build.rs +EXTRA_DIST += wrapper/rust/wolfssl-sys/headers.h +EXTRA_DIST += wrapper/rust/wolfssl-sys/src/lib.rs +EXTRA_DIST += wrapper/rust/wolfssl/Cargo.lock +EXTRA_DIST += wrapper/rust/wolfssl/Cargo.toml +EXTRA_DIST += wrapper/rust/wolfssl/Makefile +EXTRA_DIST += wrapper/rust/wolfssl/src/lib.rs diff --git a/wrapper/rust/wolfssl-sys/Cargo.lock b/wrapper/rust/wolfssl-sys/Cargo.lock new file mode 100644 index 00000000000..d43a739f4c2 --- /dev/null +++ b/wrapper/rust/wolfssl-sys/Cargo.lock @@ -0,0 +1,293 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "bindgen" +version = "0.72.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", +] + +[[package]] +name = "bitflags" +version = "2.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "libc" +version = "0.2.175" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" + +[[package]] +name = "libloading" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +dependencies = [ + "cfg-if", + "windows-targets", +] + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-targets" +version = "0.53.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "wolfssl-sys" +version = "0.1.0" +dependencies = [ + "bindgen", +] diff --git a/wrapper/rust/wolfssl-sys/Cargo.toml b/wrapper/rust/wolfssl-sys/Cargo.toml new file mode 100644 index 00000000000..c959a2d9905 --- /dev/null +++ b/wrapper/rust/wolfssl-sys/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "wolfssl-sys" +version = "0.1.0" +edition = "2024" + +[features] +std = [] + +[build-dependencies] +bindgen = "0.72.1" + +[profile.release] +strip = true +opt-level = "s" +lto = true +codegen-units = 1 +panic = "abort" diff --git a/wrapper/rust/wolfssl-sys/Makefile b/wrapper/rust/wolfssl-sys/Makefile new file mode 100644 index 00000000000..6414a60f6ce --- /dev/null +++ b/wrapper/rust/wolfssl-sys/Makefile @@ -0,0 +1,7 @@ +.PHONY: all +all: + cargo build + +.PHONY: clean +clean: + cargo clean diff --git a/wrapper/rust/wolfssl-sys/build.rs b/wrapper/rust/wolfssl-sys/build.rs new file mode 100644 index 00000000000..3f902be0cbf --- /dev/null +++ b/wrapper/rust/wolfssl-sys/build.rs @@ -0,0 +1,58 @@ +extern crate bindgen; + +use std::env; +use std::io::{self, Result}; +use std::path::PathBuf; + +/// Perform crate build. +fn main() { + if let Err(e) = run_build() { + eprintln!("Build failed: {}", e); + std::process::exit(1); + } +} + +/// Perform all build steps. +/// +/// Returns `Ok(())` if successful, or an error if any step fails. +fn run_build() -> Result<()> { + // Generate Rust bindings for wolfssl C library. + generate_bindings()?; + Ok(()) +} + +/// Generate Rust bindings for the wolfssl C library using bindgen. +/// +/// This function: +/// 1. Sets up the library and include paths +/// 2. Configures the build environment +/// 3. Generates Rust bindings using bindgen +/// 4. Writes the bindings to a file +/// +/// Returns `Ok(())` if successful, or an error if binding generation fails. +fn generate_bindings() -> Result<()> { + let wrapper_dir = std::env::current_dir()?.display().to_string(); + let wolfssl_base_dir = format!("{}/../../..", wrapper_dir); + let wolfssl_lib_dir = format!("{}/src/.libs", wolfssl_base_dir); + + println!("cargo:rustc-link-search={}", wolfssl_lib_dir); +// TODO: do we need this if only a static library is built? +// println!("cargo:rustc-link-lib=static=wolfssl"); + + let bindings = bindgen::Builder::default() + .header("headers.h") + .clang_arg(format!("-I{}", wolfssl_base_dir)) + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + .generate() + .map_err(|_| io::Error::new(io::ErrorKind::Other, "Failed to generate bindings"))?; + + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(out_path.join("bindings.rs")) + .map_err(|e| { + io::Error::new( + io::ErrorKind::Other, + format!("Couldn't write bindings: {}", e), + ) + }) +} diff --git a/wrapper/rust/wolfssl-sys/headers.h b/wrapper/rust/wolfssl-sys/headers.h new file mode 100644 index 00000000000..da081544999 --- /dev/null +++ b/wrapper/rust/wolfssl-sys/headers.h @@ -0,0 +1,20 @@ +#include "wolfssl/options.h" +#include "wolfssl/wolfcrypt/settings.h" +#include "wolfssl/wolfcrypt/types.h" +#include "wolfssl/wolfcrypt/error-crypt.h" +#include "wolfssl/wolfcrypt/random.h" +#include "wolfssl/wolfcrypt/hmac.h" +#include "wolfssl/wolfcrypt/rsa.h" +#include "wolfssl/wolfcrypt/sha256.h" +#include "wolfssl/wolfcrypt/curve25519.h" +#include "wolfssl/wolfcrypt/ed25519.h" +#include "wolfssl/wolfcrypt/ed448.h" +#include "wolfssl/wolfcrypt/ecc.h" +#include "wolfssl/wolfcrypt/asn_public.h" +#include "wolfssl/wolfcrypt/asn.h" +#include "wolfssl/wolfcrypt/chacha20_poly1305.h" +#include "wolfssl/wolfcrypt/kdf.h" +#include "wolfssl/wolfcrypt/coding.h" +#include "wolfssl/wolfcrypt/signature.h" +#include "wolfssl/wolfcrypt/logging.h" +#include "wolfssl/wolfcrypt/aes.h" diff --git a/wrapper/rust/wolfssl-sys/src/lib.rs b/wrapper/rust/wolfssl-sys/src/lib.rs new file mode 100644 index 00000000000..3ab98816b7c --- /dev/null +++ b/wrapper/rust/wolfssl-sys/src/lib.rs @@ -0,0 +1,16 @@ +/* + * Suppress warnings for bindgen-generated bindings to wolfssl C library. + */ +#![allow(clippy::missing_safety_doc)] +#![allow(clippy::ptr_offset_with_cast)] +#![allow(clippy::too_many_arguments)] +#![allow(clippy::upper_case_acronyms)] +#![allow(clippy::useless_transmute)] +#![allow(dead_code)] +#![allow(improper_ctypes)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(unnecessary_transmutes)] +#![allow(unsafe_op_in_unsafe_fn)] +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/wrapper/rust/wolfssl/Cargo.lock b/wrapper/rust/wolfssl/Cargo.lock new file mode 100644 index 00000000000..65491787114 --- /dev/null +++ b/wrapper/rust/wolfssl/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "wolfssl" +version = "0.1.0" diff --git a/wrapper/rust/wolfssl/Cargo.toml b/wrapper/rust/wolfssl/Cargo.toml new file mode 100644 index 00000000000..5a2b3a0e393 --- /dev/null +++ b/wrapper/rust/wolfssl/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "wolfssl" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/wrapper/rust/wolfssl/Makefile b/wrapper/rust/wolfssl/Makefile new file mode 100644 index 00000000000..6414a60f6ce --- /dev/null +++ b/wrapper/rust/wolfssl/Makefile @@ -0,0 +1,7 @@ +.PHONY: all +all: + cargo build + +.PHONY: clean +clean: + cargo clean diff --git a/wrapper/rust/wolfssl/src/lib.rs b/wrapper/rust/wolfssl/src/lib.rs new file mode 100644 index 00000000000..e69de29bb2d