forked from omnibor/omnibor-rs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(gitoid): Add BoringSSL backend support for SHA-1 and SHA-256 in …
…gitoid (omnibor#182) * feat(gitoid): Add BoringSSL backend support for SHA-1 and SHA-256 in gitoid This commit introduces support for the BoringSSL backend for SHA-1 and SHA-256 in the gitoid Rust package. The SHA-1CD algorithm is not supported with this backend. To enable BoringSSL, use the "boring" feature in Cargo. Additionally, benchmarks have been added to measure the performance of the implemented cryptographic algorithms. Signed-off-by: Frederick F. Kautz IV <[email protected]> * chore(gitoid): removed some commented unnecessary code Signed-off-by: Frederick F. Kautz IV <[email protected]> * chore(gitoid): Refactor feature setup and conditional compilation in gitoid - Remove conditional compilation annotations within `boring_sha.rs` since the entire module is conditionally compiled. - Introduce separate features for RustCrypto and BoringSSL backends. - Adjust `Cargo.toml` to include `rustcrypto` and `boringssl` features. - Ensure `boringssl` always activates `sha1` and `sha256` since it provides both. - Modify logic to prevent `sha1cd` from being used with only the BoringSSL backend. - Update hash algorithm implementations in `hash_algorithm.rs` to respect the new feature setup. - Add compilation errors for invalid feature combinations to `lib.rs`. - Update tests in `tests.rs` to conditionally compile based on feature setup. Signed-off-by: Frederick F. Kautz IV <[email protected]> * chore(gh-actions): Update CI workflow to include BoringSSL feature - Modify `.github/workflows/ci.yml` to build and test with the `boring` feature enabled. Signed-off-by: Frederick F. Kautz IV <[email protected]> * feat: Make "boringssl" and "rustcrypto" features non-exclusive. This commit makes it so both the "boringssl" and "rustcrypto" features can be active at the same time, meaning users of the `gitoid` crate will be able to select at runtime which of the algorithms they want to use, rather than solely deciding at compile time. Signed-off-by: Andrew Lilley Brinker <[email protected]> * chore: Hide internal types for "boringssl" backend This commit hides the `BoringSha1` and `BoringSha256` types from the `boringssl` backend. They technically have to be public because the associated type of a public trait must be public, but they only exist to wrap the types from the `boring` crate and implement the relevant traits from the `digest` crate so those types can fit into the interface we require for a cryptography backend. We don't _really_ want downstream users to use these types, so we make them public but `#[doc(hidden)]`. Signed-off-by: Andrew Lilley Brinker <[email protected]> * fix(ci): correct build feature from 'boring' to 'boringssl' Signed-off-by: Frederick F. Kautz IV <[email protected]> --------- Signed-off-by: Frederick F. Kautz IV <[email protected]> Signed-off-by: Andrew Lilley Brinker <[email protected]> Co-authored-by: Andrew Lilley Brinker <[email protected]>
- Loading branch information
1 parent
54d0b76
commit 178f7c4
Showing
10 changed files
with
404 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,11 +22,11 @@ jobs: | |
- uses: actions/checkout@v4 | ||
- uses: dtolnay/rust-toolchain@stable | ||
- name: Building | ||
run: cargo build --verbose | ||
run: cargo build --verbose --features=boringssl | ||
- name: Testing (Rust) | ||
run: cargo test --verbose | ||
run: cargo test --verbose --features=boringssl | ||
- name: Linting | ||
run: cargo clippy --verbose | ||
run: cargo clippy --verbose --features=boringssl | ||
|
||
conventional-commits: | ||
name: Conventional Commits | ||
|
@@ -35,4 +35,4 @@ jobs: | |
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: webiny/[email protected] | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
use criterion::black_box; | ||
use criterion::criterion_group; | ||
use criterion::criterion_main; | ||
use criterion::Criterion; | ||
#[cfg(feature = "boringssl")] | ||
use gitoid::boringssl::Sha1 as BoringSha1; | ||
#[cfg(feature = "boringssl")] | ||
use gitoid::boringssl::Sha256 as BoringSha256; | ||
#[cfg(all(feature = "rustcrypto", feature = "sha1"))] | ||
use gitoid::rustcrypto::Sha1 as RustSha1; | ||
#[cfg(all(feature = "rustcrypto", feature = "sha256"))] | ||
use gitoid::rustcrypto::Sha256 as RustSha256; | ||
use gitoid::Blob; | ||
use gitoid::GitOid; | ||
|
||
#[cfg(not(any(feature = "rustcrypto", feature = "boringssl",)))] | ||
compile_error!( | ||
r#"At least one cryptography backend must be active: "rustcrypto" and/or "boringssl""# | ||
); | ||
|
||
#[cfg(feature = "rustcrypto")] | ||
fn bench_rustcrypto_sha1_small(c: &mut Criterion) { | ||
let name = "GitOid RustCrypto SHA-1 11B"; | ||
let input = b"hello world"; | ||
c.bench_function(name, |b| { | ||
b.iter(|| { | ||
let _ = GitOid::<RustSha1, Blob>::id_bytes(black_box(input)); | ||
}) | ||
}); | ||
} | ||
|
||
#[cfg(feature = "boringssl")] | ||
fn bench_boring_sha1_small(c: &mut Criterion) { | ||
let name = "GitOid BoringSSL SHA-1 11B"; | ||
let input = b"hello world"; | ||
c.bench_function(name, |b| { | ||
b.iter(|| { | ||
let _ = GitOid::<BoringSha1, Blob>::id_bytes(black_box(input)); | ||
}) | ||
}); | ||
} | ||
|
||
#[cfg(feature = "rustcrypto")] | ||
fn bench_rustcrypto_sha256_small(c: &mut Criterion) { | ||
let name = "GitOid RustCrypto SHA-256 11B"; | ||
let input = b"hello world"; | ||
c.bench_function(name, |b| { | ||
b.iter(|| { | ||
let _ = GitOid::<RustSha256, Blob>::id_bytes(black_box(input)); | ||
}) | ||
}); | ||
} | ||
|
||
#[cfg(feature = "boringssl")] | ||
fn bench_boring_sha256_small(c: &mut Criterion) { | ||
let name = "GitOid BoringSSL SHA-256 11B"; | ||
let input = b"hello world"; | ||
c.bench_function(name, |b| { | ||
b.iter(|| { | ||
let _ = GitOid::<BoringSha256, Blob>::id_bytes(black_box(input)); | ||
}) | ||
}); | ||
} | ||
|
||
#[cfg(feature = "rustcrypto")] | ||
fn bench_rustcrypto_sha1_large(c: &mut Criterion) { | ||
let name = "GitOid RustCrypto SHA-1 100MB"; | ||
let input = &[0; 1024 * 1024 * 100]; // 100 MB | ||
c.bench_function(name, |b| { | ||
b.iter(|| { | ||
let _ = GitOid::<RustSha1, Blob>::id_bytes(black_box(input)); | ||
}) | ||
}); | ||
} | ||
|
||
#[cfg(feature = "boringssl")] | ||
fn bench_boring_sha1_large(c: &mut Criterion) { | ||
let name = "GitOid BoringSSL SHA-1 100MB"; | ||
let input = &[0; 1024 * 1024 * 100]; // 100 MB | ||
c.bench_function(name, |b| { | ||
b.iter(|| { | ||
let _ = GitOid::<BoringSha1, Blob>::id_bytes(black_box(input)); | ||
}) | ||
}); | ||
} | ||
|
||
#[cfg(feature = "rustcrypto")] | ||
fn bench_rustcrypto_sha256_large(c: &mut Criterion) { | ||
let name = "GitOid RustCrypto SHA-256 100MB"; | ||
let input = &[0; 1024 * 1024 * 100]; // 100 MB | ||
c.bench_function(name, |b| { | ||
b.iter(|| { | ||
let _ = GitOid::<RustSha256, Blob>::id_bytes(black_box(input)); | ||
}) | ||
}); | ||
} | ||
|
||
#[cfg(feature = "boringssl")] | ||
fn bench_boring_sha256_large(c: &mut Criterion) { | ||
let name = "GitOid BoringSSL SHA-256 100MB"; | ||
let input = &[0; 1024 * 1024 * 100]; // 100 MB | ||
c.bench_function(name, |b| { | ||
b.iter(|| { | ||
let _ = GitOid::<BoringSha256, Blob>::id_bytes(black_box(input)); | ||
}) | ||
}); | ||
} | ||
|
||
#[cfg(feature = "rustcrypto")] | ||
criterion_group!( | ||
name = rustcrypto_benches; | ||
config = Criterion::default(); | ||
targets = bench_rustcrypto_sha1_small, | ||
bench_rustcrypto_sha256_small, | ||
bench_rustcrypto_sha1_large, | ||
bench_rustcrypto_sha256_large | ||
); | ||
|
||
#[cfg(feature = "boringssl")] | ||
criterion_group!( | ||
name = boringssl_benches; | ||
config = Criterion::default(); | ||
targets = bench_boring_sha1_small, | ||
bench_boring_sha256_small, | ||
bench_boring_sha1_large, | ||
bench_boring_sha256_large | ||
); | ||
|
||
#[cfg(all(feature = "rustcrypto", feature = "boringssl"))] | ||
criterion_main!(rustcrypto_benches, boringssl_benches); | ||
|
||
#[cfg(all(feature = "rustcrypto", not(feature = "boringssl")))] | ||
criterion_main!(rustcrypto_benches); | ||
|
||
#[cfg(all(not(feature = "rustcrypto"), feature = "boringssl"))] | ||
criterion_main!(boringssl_benches); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
//! BoringSSL-based cryptography backend. | ||
use crate::impl_hash_algorithm; | ||
use crate::sealed::Sealed; | ||
use crate::HashAlgorithm; | ||
use boring::sha; | ||
use digest::consts::U20; | ||
use digest::consts::U32; | ||
use digest::generic_array::GenericArray; | ||
use digest::Digest; | ||
use digest::FixedOutput; | ||
use digest::HashMarker; | ||
use digest::Output; | ||
use digest::OutputSizeUser; | ||
use digest::Update; | ||
|
||
#[cfg(feature = "sha1")] | ||
/// SHA-1 algorithm | ||
pub struct Sha256 { | ||
#[doc(hidden)] | ||
_private: (), | ||
} | ||
|
||
/// Boring SHA-256 implementation. | ||
#[doc(hidden)] | ||
pub struct BoringSha256 { | ||
hash: sha::Sha256, | ||
} | ||
|
||
#[cfg(all(feature = "sha256", feature = "boringssl"))] | ||
impl_hash_algorithm!(Sha256, BoringSha256, "sha256"); | ||
|
||
impl Update for BoringSha256 { | ||
fn update(&mut self, data: &[u8]) { | ||
self.hash.update(data); | ||
} | ||
} | ||
|
||
impl OutputSizeUser for BoringSha256 { | ||
type OutputSize = U32; | ||
} | ||
|
||
impl FixedOutput for BoringSha256 { | ||
fn finalize_into(self, out: &mut Output<Self>) { | ||
out.copy_from_slice(self.hash.finish().as_slice()); | ||
} | ||
|
||
fn finalize_fixed(self) -> Output<Self> { | ||
let mut out = Output::<Self>::default(); | ||
out.copy_from_slice(self.hash.finish().as_slice()); | ||
out | ||
} | ||
} | ||
|
||
impl HashMarker for BoringSha256 {} | ||
|
||
impl Default for BoringSha256 { | ||
fn default() -> Self { | ||
Self { | ||
hash: sha::Sha256::new(), | ||
} | ||
} | ||
} | ||
|
||
#[cfg(feature = "sha1")] | ||
/// SHA-1 algorithm | ||
pub struct Sha1 { | ||
#[doc(hidden)] | ||
_private: (), | ||
} | ||
|
||
/// Boring SHA-1 implementation. | ||
#[doc(hidden)] | ||
pub struct BoringSha1 { | ||
hash: sha::Sha1, | ||
} | ||
|
||
#[cfg(all(feature = "sha1", feature = "boringssl"))] | ||
impl_hash_algorithm!(Sha1, BoringSha1, "sha1"); | ||
|
||
impl Update for BoringSha1 { | ||
fn update(&mut self, data: &[u8]) { | ||
self.hash.update(data); | ||
} | ||
} | ||
|
||
impl OutputSizeUser for BoringSha1 { | ||
type OutputSize = U20; | ||
} | ||
|
||
impl FixedOutput for BoringSha1 { | ||
fn finalize_into(self, out: &mut Output<Self>) { | ||
out.copy_from_slice(self.hash.finish().as_slice()); | ||
} | ||
|
||
fn finalize_fixed(self) -> Output<Self> { | ||
let mut out = Output::<Self>::default(); | ||
out.copy_from_slice(self.hash.finish().as_slice()); | ||
out | ||
} | ||
} | ||
|
||
impl HashMarker for BoringSha1 {} | ||
|
||
impl Default for BoringSha1 { | ||
fn default() -> Self { | ||
Self { | ||
hash: sha::Sha1::new(), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
//! Cryptography backends, providing hash function implementations. | ||
#[cfg(feature = "boringssl")] | ||
pub mod boringssl; | ||
|
||
#[cfg(feature = "rustcrypto")] | ||
pub mod rustcrypto; |
Oops, something went wrong.