rc_crypto/
digest.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5// This file contains code that was copied from the ring crate which is under
6// the ISC license, reproduced below:
7
8// Copyright 2015-2017 Brian Smith.
9
10// Permission to use, copy, modify, and/or distribute this software for any
11// purpose with or without fee is hereby granted, provided that the above
12// copyright notice and this permission notice appear in all copies.
13
14// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
15// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
17// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
19// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21
22use crate::error::*;
23
24pub use nss::pk11::context::HashAlgorithm::{self as Algorithm, *};
25
26/// A calculated digest value.
27#[derive(Clone)]
28pub struct Digest {
29    pub(crate) value: Vec<u8>,
30    pub(crate) algorithm: Algorithm,
31}
32
33impl Digest {
34    pub fn algorithm(&self) -> &Algorithm {
35        &self.algorithm
36    }
37}
38
39impl AsRef<[u8]> for Digest {
40    fn as_ref(&self) -> &[u8] {
41        self.value.as_ref()
42    }
43}
44
45/// Returns the digest of data using the given digest algorithm.
46pub fn digest(algorithm: &Algorithm, data: &[u8]) -> Result<Digest> {
47    let value = nss::pk11::context::hash_buf(algorithm, data)?;
48    Ok(Digest {
49        value,
50        algorithm: *algorithm,
51    })
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    const MESSAGE: &[u8] = b"bobo";
59    const DIGEST_HEX: &str = "bf0c97708b849de696e7373508b13c5ea92bafa972fc941d694443e494a4b84d";
60
61    #[test]
62    fn sha256_digest() {
63        nss::ensure_initialized();
64        assert_eq!(hex::encode(digest(&SHA256, MESSAGE).unwrap()), DIGEST_HEX);
65        assert_ne!(
66            hex::encode(digest(&SHA256, b"notbobo").unwrap()),
67            DIGEST_HEX
68        );
69    }
70
71    #[test]
72    fn digest_cleanly_rejects_gigantic_messages() {
73        nss::ensure_initialized();
74        let message = vec![0; (i32::MAX as usize) + 1];
75        assert!(digest(&SHA256, &message).is_err());
76    }
77}