Skip to content

Commit

Permalink
rust: add wrappings for ML-KEM and ML-DSA.
Browse files Browse the repository at this point in the history
Change-Id: Iff8547da5905e72648c4bf36f83fd2b5fc82ec30
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/71469
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: Adam Langley <agl@google.com>
  • Loading branch information
Adam Langley authored and Boringssl LUCI CQ committed Sep 30, 2024
1 parent 72a6050 commit f8bb652
Show file tree
Hide file tree
Showing 8 changed files with 737 additions and 1 deletion.
2 changes: 2 additions & 0 deletions gen/sources.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -2673,6 +2673,8 @@ rust_bssl_crypto_sources = [
"rust/bssl-crypto/src/lib.rs",
"rust/bssl-crypto/src/macros.rs",
"rust/bssl-crypto/src/mem.rs",
"rust/bssl-crypto/src/mldsa.rs",
"rust/bssl-crypto/src/mlkem.rs",
"rust/bssl-crypto/src/rand.rs",
"rust/bssl-crypto/src/rsa.rs",
"rust/bssl-crypto/src/scoped.rs",
Expand Down
2 changes: 2 additions & 0 deletions gen/sources.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2719,6 +2719,8 @@ set(
rust/bssl-crypto/src/lib.rs
rust/bssl-crypto/src/macros.rs
rust/bssl-crypto/src/mem.rs
rust/bssl-crypto/src/mldsa.rs
rust/bssl-crypto/src/mlkem.rs
rust/bssl-crypto/src/rand.rs
rust/bssl-crypto/src/rsa.rs
rust/bssl-crypto/src/scoped.rs
Expand Down
2 changes: 2 additions & 0 deletions gen/sources.gni
Original file line number Diff line number Diff line change
Expand Up @@ -2673,6 +2673,8 @@ rust_bssl_crypto_sources = [
"rust/bssl-crypto/src/lib.rs",
"rust/bssl-crypto/src/macros.rs",
"rust/bssl-crypto/src/mem.rs",
"rust/bssl-crypto/src/mldsa.rs",
"rust/bssl-crypto/src/mlkem.rs",
"rust/bssl-crypto/src/rand.rs",
"rust/bssl-crypto/src/rsa.rs",
"rust/bssl-crypto/src/scoped.rs",
Expand Down
2 changes: 2 additions & 0 deletions gen/sources.json
Original file line number Diff line number Diff line change
Expand Up @@ -2655,6 +2655,8 @@
"rust/bssl-crypto/src/lib.rs",
"rust/bssl-crypto/src/macros.rs",
"rust/bssl-crypto/src/mem.rs",
"rust/bssl-crypto/src/mldsa.rs",
"rust/bssl-crypto/src/mlkem.rs",
"rust/bssl-crypto/src/rand.rs",
"rust/bssl-crypto/src/rsa.rs",
"rust/bssl-crypto/src/scoped.rs",
Expand Down
67 changes: 66 additions & 1 deletion rust/bssl-crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
extern crate alloc;
extern crate core;

use alloc::vec::Vec;
use alloc::{boxed::Box, vec::Vec};
use core::ffi::c_void;

#[macro_use]
Expand All @@ -48,6 +48,8 @@ pub mod ed25519;
pub mod hkdf;
pub mod hmac;
pub mod hpke;
pub mod mldsa;
pub mod mlkem;
pub mod rsa;
pub mod x25519;

Expand Down Expand Up @@ -240,6 +242,37 @@ where
}
}

/// Returns a boxed BoringSSL structure that is initialized by some function.
/// Requires that the given function completely initializes the value.
///
/// Safety: the argument must fully initialize the pointed-to `T`.
unsafe fn initialized_boxed_struct<T, F>(init: F) -> Box<T>
where
F: FnOnce(*mut T),
{
let mut out_uninit = Box::new(core::mem::MaybeUninit::<T>::uninit());
init(out_uninit.as_mut_ptr());
unsafe { out_uninit.assume_init() }
}

/// Returns a boxed BoringSSL structure that is initialized by some function.
/// Requires that the given function completely initializes the value or else
/// returns false.
///
/// Safety: the argument must fully initialize the pointed-to `T` if it returns
/// true. If it returns false then there are no safety requirements.
unsafe fn initialized_boxed_struct_fallible<T, F>(init: F) -> Option<Box<T>>
where
F: FnOnce(*mut T) -> bool,
{
let mut out_uninit = Box::new(core::mem::MaybeUninit::<T>::uninit());
if init(out_uninit.as_mut_ptr()) {
Some(unsafe { out_uninit.assume_init() })
} else {
None
}
}

/// Wrap a closure that initializes an output buffer and return that buffer as
/// an array. Requires that the closure fully initialize the given buffer.
///
Expand Down Expand Up @@ -364,6 +397,13 @@ impl Drop for Buffer {
}
}

fn as_cbs(buf: &[u8]) -> bssl_sys::CBS {
bssl_sys::CBS {
data: buf.as_ffi_ptr(),
len: buf.len(),
}
}

/// Calls `parse_func` with a `CBS` structure pointing at `data`.
/// If that returns a null pointer then it returns [None].
/// Otherwise, if there's still data left in CBS, it calls `free_func` on the
Expand Down Expand Up @@ -414,6 +454,31 @@ fn cbb_to_buffer<F: FnOnce(*mut bssl_sys::CBB)>(initial_capacity: usize, func: F
unsafe { Buffer::new(ptr, len) }
}

/// Calls `func` with a `CBB` pointer that has been initialized to a vector
/// of `len` bytes. That function must write exactly `len` bytes to the
/// `CBB`. Those bytes are then returned as a vector.
#[allow(clippy::unwrap_used)]
fn cbb_to_vec<F: FnOnce(*mut bssl_sys::CBB)>(len: usize, func: F) -> Vec<u8> {
let mut boxed = Box::new_uninit_slice(len);
// Safety: type checking ensures that `cbb` is the correct size.
let mut cbb = unsafe {
initialized_struct_fallible(|cbb| {
bssl_sys::CBB_init_fixed(cbb, boxed.as_mut_ptr() as *mut u8, len) == 1
})
}
// `CBB_init` only fails if out of memory, which isn't something that this
// crate handles.
.unwrap();

func(&mut cbb);

unsafe {
assert_eq!(bssl_sys::CBB_len(&cbb), len);
// `boxed` has been fully written, as checked on the previous line.
boxed.assume_init().into()
}
}

/// Used to prevent external implementations of internal traits.
mod sealed {
pub struct Sealed;
Expand Down
Loading

0 comments on commit f8bb652

Please sign in to comment.