diff options
author | Ellen Arteca <emarteca@google.com> | 2024-06-03 22:21:14 +0000 |
---|---|---|
committer | Boringssl LUCI CQ <boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2024-06-04 00:40:06 +0000 |
commit | 25cf1bb965ba9ae0302cbc6de4ff4dd6cdbbc016 (patch) | |
tree | 096c170865412e9c2b3699fa210ac83995e0970e /rust | |
parent | c8100f0f0d05c5185d58113e12a867ae0771a6c9 (diff) | |
download | boringssl-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.rs | 24 | ||||
-rw-r--r-- | rust/bssl-crypto/src/macros.rs | 44 |
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() } } |