aboutsummaryrefslogtreecommitdiff
path: root/nearby/crypto/crypto_provider_rustcrypto/src/hmac_rc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'nearby/crypto/crypto_provider_rustcrypto/src/hmac_rc.rs')
-rw-r--r--nearby/crypto/crypto_provider_rustcrypto/src/hmac_rc.rs114
1 files changed, 114 insertions, 0 deletions
diff --git a/nearby/crypto/crypto_provider_rustcrypto/src/hmac_rc.rs b/nearby/crypto/crypto_provider_rustcrypto/src/hmac_rc.rs
new file mode 100644
index 0000000..e31b815
--- /dev/null
+++ b/nearby/crypto/crypto_provider_rustcrypto/src/hmac_rc.rs
@@ -0,0 +1,114 @@
+// Copyright 2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use crypto_provider::hmac::{InvalidLength, MacError};
+use hmac::digest::block_buffer::Eager;
+use hmac::digest::consts::U256;
+use hmac::digest::core_api::{
+ BlockSizeUser, BufferKindUser, CoreProxy, FixedOutputCore, UpdateCore,
+};
+use hmac::digest::typenum::{IsLess, Le, NonZero};
+use hmac::digest::{HashMarker, OutputSizeUser};
+use hmac::Mac;
+
+/// RustCrypto based hmac implementation
+pub struct Hmac<D>
+where
+ D: OutputSizeUser,
+ D: CoreProxy,
+ D::Core: HashMarker
+ + UpdateCore
+ + FixedOutputCore
+ + BufferKindUser<BufferKind = Eager>
+ + Default
+ + Clone,
+ <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
+ Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
+{
+ hmac_impl: hmac::Hmac<D>,
+}
+
+impl crypto_provider::hmac::Hmac<32> for Hmac<sha2::Sha256> {
+ #[allow(clippy::expect_used)]
+ fn new_from_key(key: [u8; 32]) -> Self {
+ hmac::Hmac::new_from_slice(&key)
+ .map(|hmac| Self { hmac_impl: hmac })
+ .expect("length will always be valid because input key is of fixed size")
+ }
+
+ fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
+ hmac::Hmac::new_from_slice(key)
+ .map(|hmac| Self { hmac_impl: hmac })
+ .map_err(|_| InvalidLength)
+ }
+
+ fn update(&mut self, data: &[u8]) {
+ self.hmac_impl.update(data);
+ }
+
+ fn finalize(self) -> [u8; 32] {
+ self.hmac_impl.finalize().into_bytes().into()
+ }
+
+ fn verify_slice(self, tag: &[u8]) -> Result<(), MacError> {
+ self.hmac_impl.verify_slice(tag).map_err(|_| MacError)
+ }
+
+ fn verify(self, tag: [u8; 32]) -> Result<(), MacError> {
+ self.hmac_impl.verify(&tag.into()).map_err(|_| MacError)
+ }
+
+ fn verify_truncated_left(self, tag: &[u8]) -> Result<(), MacError> {
+ self.hmac_impl
+ .verify_truncated_left(tag)
+ .map_err(|_| MacError)
+ }
+}
+
+impl crypto_provider::hmac::Hmac<64> for Hmac<sha2::Sha512> {
+ #[allow(clippy::expect_used)]
+ fn new_from_key(key: [u8; 64]) -> Self {
+ hmac::Hmac::new_from_slice(&key)
+ .map(|hmac| Self { hmac_impl: hmac })
+ .expect("length will always be valid because input key is of fixed size")
+ }
+
+ fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
+ hmac::Hmac::new_from_slice(key)
+ .map(|hmac| Self { hmac_impl: hmac })
+ .map_err(|_| InvalidLength)
+ }
+
+ fn update(&mut self, data: &[u8]) {
+ self.hmac_impl.update(data);
+ }
+
+ fn finalize(self) -> [u8; 64] {
+ self.hmac_impl.finalize().into_bytes().into()
+ }
+
+ fn verify_slice(self, tag: &[u8]) -> Result<(), MacError> {
+ self.hmac_impl.verify_slice(tag).map_err(|_| MacError)
+ }
+
+ fn verify(self, tag: [u8; 64]) -> Result<(), MacError> {
+ self.hmac_impl.verify(&tag.into()).map_err(|_| MacError)
+ }
+
+ fn verify_truncated_left(self, tag: &[u8]) -> Result<(), MacError> {
+ self.hmac_impl
+ .verify_truncated_left(tag)
+ .map_err(|_| MacError)
+ }
+}