Skip to content

[Draft] opaque types #75

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/builld.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@ jobs:
include:
- target: x86_64-pc-windows-msvc
os: windows-latest
symcrypt: "https://github.com/microsoft/SymCrypt/releases/download/v103.4.2/symcrypt-windows-amd64-release-103.4.2-171f697.zip"
symcrypt: "https://github.com/microsoft/SymCrypt/releases/download/v103.8.0/symcrypt-windows-amd64-release-103.8.0-53be637d.zip"
run-tests: true
- target: aarch64-pc-windows-msvc
os: windows-latest
symcrypt: "https://github.com/microsoft/SymCrypt/releases/download/v103.4.2/symcrypt-windows-arm64-release-103.4.2-171f697.zip"
symcrypt: "https://github.com/microsoft/SymCrypt/releases/download/v103.8.0/symcrypt-windows-arm64-release-103.8.0-53be637d.zip"
run-tests: false # Windows doesn't support ARM64 emulation
- target: x86_64-unknown-linux-gnu
symcrypt: "https://github.com/microsoft/SymCrypt/releases/download/v103.4.2/symcrypt-linux-generic-amd64-release-103.4.2-171f697.tar.gz"
symcrypt: "https://github.com/microsoft/SymCrypt/releases/download/v103.8.0/symcrypt-linux-generic-amd64-release-103.8.0-53be637.tar.gz"
os: ubuntu-latest
run-tests: true
- target: aarch64-unknown-linux-gnu
os: ubuntu-latest
symcrypt: "https://github.com/microsoft/SymCrypt/releases/download/v103.4.2/symcrypt-linux-generic-arm64-release-103.4.2-171f697.tar.gz"
symcrypt: "https://github.com/microsoft/SymCrypt/releases/download/v103.8.0/symcrypt-linux-generic-arm64-release-103.8.0-53be637.tar.gz"
run-tests: false

runs-on: ${{ matrix.os }}
Expand Down
2 changes: 2 additions & 0 deletions scripts/generate-all-bindings.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ $PSNativeCommandUseErrorActionPreference = $True
Push-Location "$PSScriptRoot/.." # Move to the root of the project

git submodule update --init
git -C symcrypt-sys/symcrypt/3rdparty/jitterentropy-library submodule update --init

python3 "./symcrypt-sys/symcrypt/scripts/version.py" --build-info
mv -Force "./symcrypt-sys/symcrypt/inc/buildInfo.h" "./symcrypt-sys/inc/"
mv -Force "./symcrypt-sys/symcrypt/inc/symcrypt_internal_shared.inc" "./symcrypt-sys/inc/"

$bindingsDir = "./symcrypt-sys/src/bindings" # is relative to the project root
if (Test-Path $bindingsDir) {
Expand Down
71 changes: 42 additions & 29 deletions symcrypt-bindgen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,14 @@ fn main() {

std::fs::create_dir_all(out_dir).expect("Unable to create output directory");

let bindings = bindgen::builder()
let mut builder = bindgen::builder()
.header(wrapper_header.display().to_string())
.rust_target(bindgen::RustTarget::from_str(&rust_target).unwrap())

// Clang arguments
.clang_arg("-v")
.clang_args(["-target", triple])
.clang_arg(format!("-I{}/inc", symcrypt_sys_crate.display()))
.clang_arg(format!("-I{}/symcrypt/inc", symcrypt_sys_crate.display()))
.clang_arg(format!("-I{}/symcrypt/lib", symcrypt_sys_crate.display()))

Expand Down Expand Up @@ -106,8 +107,23 @@ fn main() {
.allowlist_function("SymCryptWipe")
.allowlist_function("SymCryptRandom")
.allowlist_function("SymCryptLoadMsbFirstUint64")
.allowlist_function("SymCryptStoreMsbFirstUint64")

.allowlist_function("SymCryptStoreMsbFirstUint64");

// Opaque types
builder = builder
.opaque_type("_SYMCRYPT_.*_STATE")
.opaque_type("_SYMCRYPT_.*_EXPANDED_KEY")
.opaque_type("_SYMCRYPT_BLOCKCIPHER")
.opaque_type("_SYMCRYPT_ECURVE")
.opaque_type("_SYMCRYPT_ECURVE_PARAMS")
.opaque_type("_SYMCRYPT_INT")
.opaque_type("_SYMCRYPT_DIVISOR")
.opaque_type("_SYMCRYPT_MODULUS")
.opaque_type("_SYMCRYPT_ECKEY")
.opaque_type("_SYMCRYPT_RSAKEY")
.opaque_type("_SYMCRYPT_MAC");

let bindings = builder
.generate_comments(true)
.derive_default(true)
.generate()
Expand All @@ -117,7 +133,7 @@ fn main() {
.write_to_file(&bindings_file)
.expect("Couldn't write bindings!");

fix_bindings_for_windows(triple, &bindings_file);
fix_bindings_for_windows(&bindings_file);
}

fn get_parent_n(path: &Path, n: usize) -> PathBuf {
Expand Down Expand Up @@ -148,32 +164,29 @@ fn get_rust_version_from_cargo_metadata() -> String {
}

#[allow(clippy::collapsible_if)]
fn fix_bindings_for_windows(triple: &str, bindings_file: &str) {
if triple.contains("windows") {
println!("Fixing bindings for Windows");
let link_str = "#[link(name = \"symcrypt\", kind = \"dylib\")]";
let regex_exp1 = regex::Regex::new(r"pub static \w+: \[SYMCRYPT_OID; \d+usize\];").unwrap();
let regex_exp2 = regex::Regex::new(r"pub static \w+: PCSYMCRYPT_\w+;").unwrap();
let bindings_content =
std::fs::read_to_string(bindings_file).expect("Unable to read bindings file");

let mut out_content = Vec::new();
let lines: Vec<&str> = bindings_content.lines().collect();
out_content.push(lines[0]);

for i in 1..lines.len() {
if lines[i - 1].contains("extern \"C\" {") {
if regex_exp1.is_match(lines[i]) || regex_exp2.is_match(lines[i]) {
out_content.pop();
out_content.push(link_str);
out_content.push(lines[i - 1]);
}
fn fix_bindings_for_windows(bindings_file: &str) {
println!("Fixing bindings for Windows");
let link_str = r#"#[cfg_attr(target_os = "windows", link(name = "symcrypt", kind = "dylib"))]"#;
let regex_exp1 = regex::Regex::new(r"pub static \w+: \[SYMCRYPT_OID; \d+usize\];").unwrap();
let regex_exp2 = regex::Regex::new(r"pub static \w+: PCSYMCRYPT_\w+;").unwrap();
let bindings_content =
std::fs::read_to_string(bindings_file).expect("Unable to read bindings file");

let mut out_content = Vec::new();
let lines: Vec<&str> = bindings_content.lines().collect();
out_content.push(lines[0]);

for i in 1..lines.len() {
if lines[i - 1].contains("extern \"C\" {") {
if regex_exp1.is_match(lines[i]) || regex_exp2.is_match(lines[i]) {
out_content.pop();
out_content.push(link_str);
out_content.push(lines[i - 1]);
}
out_content.push(lines[i]);
}

out_content.push(""); // Add an empty line at the end
std::fs::write(bindings_file, out_content.join("\n"))
.expect("Unable to write bindings file");
out_content.push(lines[i]);
}

out_content.push(""); // Add an empty line at the end
std::fs::write(bindings_file, out_content.join("\n")).expect("Unable to write bindings file");
}
10 changes: 5 additions & 5 deletions symcrypt-sys/inc/buildInfo.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "symcrypt_internal_shared.inc"

#define _SYMCRYPT_JOIN(a, b) #a "." #b
#define _SYMCRYPT_EXPAND_JOIN(a, b) _SYMCRYPT_JOIN(a, b)
#define _SYMCRYPT_STRING_INT(a) #a
#define _SYMCRYPT_STRING(a) _SYMCRYPT_STRING_INT(a)
#define SYMCRYPT_BUILD_INFO_BRANCH ""
#define SYMCRYPT_BUILD_INFO_COMMIT "2024-04-12T07:54:16+02:00_171f697"
#define SYMCRYPT_BUILD_INFO_VERSION _SYMCRYPT_EXPAND_JOIN(_SYMCRYPT_EXPAND_JOIN(SYMCRYPT_CODE_VERSION_API, SYMCRYPT_CODE_VERSION_MINOR), SYMCRYPT_CODE_VERSION_PATCH)
#define SYMCRYPT_BUILD_INFO_TIMESTAMP "2025-01-14T14:29:07"
#define SYMCRYPT_BUILD_INFO_COMMIT "2025-01-28T01:44:15+01:00_53be637"
#define SYMCRYPT_BUILD_INFO_VERSION _SYMCRYPT_STRING(SYMCRYPT_CODE_VERSION_API) "." _SYMCRYPT_STRING(SYMCRYPT_CODE_VERSION_MINOR) "." _SYMCRYPT_STRING(SYMCRYPT_CODE_VERSION_PATCH)
#define SYMCRYPT_BUILD_INFO_TIMESTAMP "2025-01-31T15:53:40"
33 changes: 33 additions & 0 deletions symcrypt-sys/inc/symcrypt_internal_shared.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// symcrypt_internal_shared.inc
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//
// This is the file that contains the SymCrypt version information and defines SYMCRYPT_DEBUG.
// It is included in both C and ASM such that the values are the same on both sides.
// We use the C preprocessor to set ASM constants, as we already need to use the C preprocessor for
// symcryptasm processing (see scripts/symcryptasm_processor.py).
//
// In previous releases we had a numbering system with major/minor version number.
// This worked well with the sequential servicing imposed by SourceDepot.
// With the switch to Git this no longer works due to having multiple branches.
// We move to having the version here only specify the API and minor version number
// These will NOT be changed for every build. The API version only changes when there are
// breaking changes to the API in symcrypt.h. (Note: symcrypt_low_level.h is not stable and can change
// at any time.) The minor version is changed at regular intervals, but not necessarily at
// every build of the library.
//
// Separate from these numbers the build system includes information about the branch,
// last commit, build time, etc.
//
// The API numbering starts at 100 to avoid number conflicts with the old system.
//

#define SYMCRYPT_CODE_VERSION_API 103
#define SYMCRYPT_CODE_VERSION_MINOR 8
#define SYMCRYPT_CODE_VERSION_PATCH 0

#if defined(DBG)
#define SYMCRYPT_DEBUG 1
#else
#define SYMCRYPT_DEBUG 0
#endif
2 changes: 2 additions & 0 deletions symcrypt-sys/src/bindings.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![allow(improper_ctypes)] // bindgen uses u128 for opaque types which is not officially stable yet

#[cfg(all(target_os = "windows", target_arch = "x86_64"))]
mod x86_64_pc_windows_msvc;
#[cfg(all(target_os = "windows", target_arch = "x86_64"))]
Expand Down
Loading