aboutsummaryrefslogtreecommitdiff
path: root/openssl/src/sha.rs
blob: c41410940481f958dc25f9f285e1365ccd19b71d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//! The SHA family of hashes.
use libc::c_void;
use ffi;
use std::mem;

/// Computes the SHA1 hash of some data.
///
/// # Warning
///
/// SHA1 is known to be insecure - it should not be used unless required for
/// compatibility with existing systems.
#[inline]
pub fn sha1(data: &[u8]) -> [u8; 20] {
    unsafe {
        let mut hash: [u8; 20] = mem::uninitialized();
        ffi::SHA1(data.as_ptr(), data.len(), hash.as_mut_ptr());
        hash
    }
}

/// Computes the SHA224 hash of some data.
#[inline]
pub fn sha224(data: &[u8]) -> [u8; 28] {
    unsafe {
        let mut hash: [u8; 28] = mem::uninitialized();
        ffi::SHA224(data.as_ptr(), data.len(), hash.as_mut_ptr());
        hash
    }
}

/// Computes the SHA256 hash of some data.
#[inline]
pub fn sha256(data: &[u8]) -> [u8; 32] {
    unsafe {
        let mut hash: [u8; 32] = mem::uninitialized();
        ffi::SHA256(data.as_ptr(), data.len(), hash.as_mut_ptr());
        hash
    }
}

/// Computes the SHA384 hash of some data.
#[inline]
pub fn sha384(data: &[u8]) -> [u8; 48] {
    unsafe {
        let mut hash: [u8; 48] = mem::uninitialized();
        ffi::SHA384(data.as_ptr(), data.len(), hash.as_mut_ptr());
        hash
    }
}

/// Computes the SHA512 hash of some data.
#[inline]
pub fn sha512(data: &[u8]) -> [u8; 64] {
    unsafe {
        let mut hash: [u8; 64] = mem::uninitialized();
        ffi::SHA512(data.as_ptr(), data.len(), hash.as_mut_ptr());
        hash
    }
}

/// An object which calculates a SHA256 hash of some data.
pub struct Sha256(ffi::SHA256_CTX);

impl Sha256 {
    /// Creates a new hasher.
    #[inline]
    pub fn new() -> Sha256 {
        unsafe {
            let mut ctx = mem::uninitialized();
            ffi::SHA256_Init(&mut ctx);
            Sha256(ctx)
        }
    }

    /// Feeds some data into the hasher.
    ///
    /// This can be called multiple times.
    #[inline]
    pub fn update(&mut self, buf: &[u8]) {
        unsafe {
            ffi::SHA256_Update(&mut self.0, buf.as_ptr() as *const c_void, buf.len());
        }
    }

    /// Returns the hash of the data.
    #[inline]
    pub fn finish(mut self) -> [u8; 32] {
        unsafe {
            let mut hash: [u8; 32] = mem::uninitialized();
            ffi::SHA256_Final(hash.as_mut_ptr(), &mut self.0);
            hash
        }
    }
}

#[cfg(test)]
mod test {
    use hex::ToHex;

    use super::*;

    #[test]
    fn standalone_1() {
        let data = b"abc";
        let expected = "a9993e364706816aba3e25717850c26c9cd0d89d";

        assert_eq!(sha1(data).to_hex(), expected);
    }

    #[test]
    fn standalone_224() {
        let data = b"abc";
        let expected = "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7";

        assert_eq!(sha224(data).to_hex(), expected);
    }

    #[test]
    fn standalone_256() {
        let data = b"abc";
        let expected = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";

        assert_eq!(sha256(data).to_hex(), expected);
    }

    #[test]
    fn struct_256() {
        let expected = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";

        let mut hasher = Sha256::new();
        hasher.update(b"a");
        hasher.update(b"bc");
        assert_eq!(hasher.finish().to_hex(), expected);
    }

    #[test]
    fn standalone_384() {
        let data = b"abc";
        let expected = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e\
                        7cc2358baeca134c825a7";

        assert_eq!((&sha384(data)[..]).to_hex(), expected);
    }

    #[test]
    fn standalone_512() {
        let data = b"abc";
        let expected = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274\
                        fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";

        assert_eq!((&sha512(data)[..]).to_hex(), expected);
    }
}