aboutsummaryrefslogtreecommitdiff
path: root/rust
diff options
context:
space:
mode:
authorEllen Arteca <emarteca@google.com>2024-06-03 22:21:14 +0000
committerBoringssl LUCI CQ <boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com>2024-06-04 00:40:06 +0000
commit25cf1bb965ba9ae0302cbc6de4ff4dd6cdbbc016 (patch)
tree096c170865412e9c2b3699fa210ac83995e0970e /rust
parentc8100f0f0d05c5185d58113e12a867ae0771a6c9 (diff)
downloadboringssl-25cf1bb965ba9ae0302cbc6de4ff4dd6cdbbc016.zip
boringssl-25cf1bb965ba9ae0302cbc6de4ff4dd6cdbbc016.tar.gz
boringssl-25cf1bb965ba9ae0302cbc6de4ff4dd6cdbbc016.tar.bz2
Adds functionality for instantiating and using `Algorithm`
This CL moves some methods that exist in every hashing algorithm implementation to the `Algorithm` trait; namely, `new`, `update`, and `digest`. This allows for clients to instantiate the hashing algorithms, and to call `update` and `digest` on objects that have this trait. It allows a generic representation of an algorithm that can be used. This CL also adds the block size as a const field in the `Algorithm` trait. Note: this specifically supports the hashing algorithm use in the style of what is done in AOSP's `packages/modules/Virtualization/libs/apkverify`, which was previously using the rust openssl `Hasher` to instantiate algorithms specified by their `MessageDigest`. Change-Id: Ic47691ee2a4303923519b246de7d9724da90f60d Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/68748 Commit-Queue: Ellen Arteca <emarteca@google.com> Commit-Queue: Adam Langley <agl@google.com> Reviewed-by: Adam Langley <agl@google.com>
Diffstat (limited to 'rust')
-rw-r--r--rust/bssl-crypto/src/digest.rs24
-rw-r--r--rust/bssl-crypto/src/macros.rs44
2 files changed, 50 insertions, 18 deletions
diff --git a/rust/bssl-crypto/src/digest.rs b/rust/bssl-crypto/src/digest.rs
index 645ab80..125f427 100644
--- a/rust/bssl-crypto/src/digest.rs
+++ b/rust/bssl-crypto/src/digest.rs
@@ -45,6 +45,8 @@ unsafe impl ForeignTypeRef for MdRef {
pub trait Algorithm {
/// The size of the resulting digest.
const OUTPUT_LEN: usize;
+ /// The block length (in bytes).
+ const BLOCK_LEN: usize;
/// Gets a reference to a message digest algorithm to be used by the HKDF implementation.
#[doc(hidden)]
@@ -52,6 +54,23 @@ pub trait Algorithm {
/// Hashes a message.
fn hash_to_vec(input: &[u8]) -> Vec<u8>;
+
+ /// Create a new context for incremental hashing.
+ fn new() -> Self;
+
+ /// Hash the contents of `input`.
+ fn update(&mut self, input: &[u8]);
+
+ /// Finish the hashing and return the digest.
+ fn digest_to_vec(mut self) -> Vec<u8>;
+}
+
+/// Trait parameterized by the size of the output of the digest
+/// so that it can provide algorithm functions that depend on
+/// this parameter.
+pub trait WithOutputLength<const OUTPUT_LEN: usize> {
+ /// Finish the hashing and return the digest.
+ fn digest(mut self) -> [u8; OUTPUT_LEN];
}
/// The insecure SHA-1 hash algorithm.
@@ -67,6 +86,7 @@ pub struct InsecureSha1 {
unsafe_iuf_algo!(
InsecureSha1,
20,
+ 64,
EVP_sha1,
SHA1,
SHA1_Init,
@@ -83,6 +103,7 @@ pub struct Sha256 {
unsafe_iuf_algo!(
Sha256,
32,
+ 64,
EVP_sha256,
SHA256,
SHA256_Init,
@@ -99,6 +120,7 @@ pub struct Sha384 {
unsafe_iuf_algo!(
Sha384,
48,
+ 128,
EVP_sha384,
SHA384,
SHA384_Init,
@@ -115,6 +137,7 @@ pub struct Sha512 {
unsafe_iuf_algo!(
Sha512,
64,
+ 128,
EVP_sha512,
SHA512,
SHA512_Init,
@@ -131,6 +154,7 @@ pub struct Sha512_256 {
unsafe_iuf_algo!(
Sha512_256,
32,
+ 128,
EVP_sha512_256,
SHA512_256,
SHA512_256_Init,
diff --git a/rust/bssl-crypto/src/macros.rs b/rust/bssl-crypto/src/macros.rs
index 6ac3d37..0d49646 100644
--- a/rust/bssl-crypto/src/macros.rs
+++ b/rust/bssl-crypto/src/macros.rs
@@ -22,9 +22,10 @@
// Safety: see the "Safety" sections within about the requirements for the
// functions named in the macro parameters.
macro_rules! unsafe_iuf_algo {
- ($name:ident, $output_len:expr, $evp_md:ident, $one_shot:ident, $init:ident, $update:ident, $final_func:ident) => {
+ ($name:ident, $output_len:expr, $block_len:expr, $evp_md:ident, $one_shot:ident, $init:ident, $update:ident, $final_func:ident) => {
impl Algorithm for $name {
const OUTPUT_LEN: usize = $output_len as usize;
+ const BLOCK_LEN: usize = $block_len as usize;
fn get_md(_: sealed::Sealed) -> &'static MdRef {
// Safety:
@@ -35,22 +36,9 @@ macro_rules! unsafe_iuf_algo {
fn hash_to_vec(input: &[u8]) -> Vec<u8> {
Self::hash(input).as_slice().to_vec()
}
- }
-
- impl $name {
- /// Digest `input` in a single operation.
- pub fn hash(input: &[u8]) -> [u8; $output_len] {
- // Safety: it is assumed that `$one_shot` indeed writes
- // `$output_len` bytes.
- unsafe {
- crate::with_output_array(|out, _| {
- bssl_sys::$one_shot(input.as_ffi_ptr(), input.len(), out);
- })
- }
- }
/// Create a new context for incremental hashing.
- pub fn new() -> Self {
+ fn new() -> Self {
unsafe {
Self {
ctx: crate::initialized_struct(|ctx| {
@@ -63,7 +51,7 @@ macro_rules! unsafe_iuf_algo {
}
/// Hash the contents of `input`.
- pub fn update(&mut self, input: &[u8]) {
+ fn update(&mut self, input: &[u8]) {
// Safety: arguments point to a valid buffer.
unsafe {
bssl_sys::$update(&mut self.ctx, input.as_ffi_void_ptr(), input.len());
@@ -71,7 +59,14 @@ macro_rules! unsafe_iuf_algo {
}
/// Finish the hashing and return the digest.
- pub fn digest(mut self) -> [u8; $output_len] {
+ fn digest_to_vec(mut self) -> alloc::vec::Vec<u8> {
+ WithOutputLength::<$output_len>::digest(self).to_vec()
+ }
+ }
+
+ impl<const OUTPUT_LEN: usize> WithOutputLength<OUTPUT_LEN> for $name {
+ /// Finish the hashing and return the digest.
+ fn digest(mut self) -> [u8; OUTPUT_LEN] {
// Safety: it is assumed that `$final_func` indeed writes
// `$output_len` bytes.
unsafe {
@@ -82,6 +77,19 @@ macro_rules! unsafe_iuf_algo {
}
}
+ impl $name {
+ /// Digest `input` in a single operation.
+ pub fn hash(input: &[u8]) -> [u8; $output_len] {
+ // Safety: it is assumed that `$one_shot` indeed writes
+ // `$output_len` bytes.
+ unsafe {
+ crate::with_output_array(|out, _| {
+ bssl_sys::$one_shot(input.as_ffi_ptr(), input.len(), out);
+ })
+ }
+ }
+ }
+
impl From<$name> for [u8; $output_len] {
fn from(ctx: $name) -> [u8; $output_len] {
ctx.digest()
@@ -90,7 +98,7 @@ macro_rules! unsafe_iuf_algo {
impl From<$name> for alloc::vec::Vec<u8> {
fn from(ctx: $name) -> alloc::vec::Vec<u8> {
- ctx.digest().into()
+ ctx.digest_to_vec()
}
}