tink_core/subtle/
mod.rs

1// Copyright 2020 The Tink-Rust Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15////////////////////////////////////////////////////////////////////////////////
16
17//! Common methods needed in subtle implementations.
18
19use crate::TinkError;
20use digest::Digest;
21use subtle::ConstantTimeEq;
22use tink_proto::HashType;
23
24mod hkdf;
25pub use self::hkdf::*;
26pub mod random;
27
28/// Return the digest size of the specified hash algorithm.
29pub fn get_hash_digest_size(hash: HashType) -> Result<usize, TinkError> {
30    match hash {
31        HashType::Sha1 => Ok(20),
32        HashType::Sha224 => Ok(28),
33        HashType::Sha256 => Ok(32),
34        HashType::Sha384 => Ok(48),
35        HashType::Sha512 => Ok(64),
36        _ => Err("invalid hash algorithm".into()),
37    }
38}
39
40/// Hash function object.
41pub enum HashFunc {
42    Sha1(sha1::Sha1),
43    Sha224(sha2::Sha224),
44    Sha256(sha2::Sha256),
45    Sha384(sha2::Sha384),
46    Sha512(sha2::Sha512),
47}
48
49/// Return the corresponding hash function of the given hash.
50pub fn get_hash_func(hash: HashType) -> Option<HashFunc> {
51    match hash {
52        HashType::Sha1 => Some(HashFunc::Sha1(sha1::Sha1::new())),
53        HashType::Sha224 => Some(HashFunc::Sha224(sha2::Sha224::new())),
54        HashType::Sha256 => Some(HashFunc::Sha256(sha2::Sha256::new())),
55        HashType::Sha384 => Some(HashFunc::Sha384(sha2::Sha384::new())),
56        HashType::Sha512 => Some(HashFunc::Sha512(sha2::Sha512::new())),
57        _ => None,
58    }
59}
60
61/// Calculate a hash of the given data using the given hash function.
62pub fn compute_hash(hash_fn: &mut HashFunc, data: &[u8]) -> Result<Vec<u8>, TinkError> {
63    Ok(match hash_fn {
64        HashFunc::Sha1(h) => compute_hash_with(h, data),
65        HashFunc::Sha224(h) => compute_hash_with(h, data),
66        HashFunc::Sha256(h) => compute_hash_with(h, data),
67        HashFunc::Sha384(h) => compute_hash_with(h, data),
68        HashFunc::Sha512(h) => compute_hash_with(h, data),
69    })
70}
71
72/// Calculate a hash of the given data with the given hash function.
73fn compute_hash_with<T>(hash_func: &mut T, data: &[u8]) -> Vec<u8>
74where
75    T: digest::Digest + digest::Reset + digest::FixedOutputReset,
76{
77    Digest::reset(hash_func);
78    Digest::update(hash_func, data);
79    Digest::finalize_reset(hash_func).to_vec()
80}
81
82/// Compare two slices in constant time. Return `true` if they are equal, `false` otherwise.
83pub fn constant_time_compare(left: &[u8], right: &[u8]) -> bool {
84    left.ct_eq(right).into()
85}