1use crate::{sealed, FfiSlice, ForeignTypeRef};
46use alloc::vec::Vec;
47
48#[non_exhaustive]
49#[doc(hidden)]
50pub struct MdRef;
51
52unsafe impl ForeignTypeRef for MdRef {
53 type CType = bssl_sys::EVP_MD;
54}
55
56pub trait Algorithm {
58 const OUTPUT_LEN: usize;
60 const BLOCK_LEN: usize;
62
63 #[doc(hidden)]
65 fn get_md(_: sealed::SealedType) -> &'static MdRef;
66
67 fn hash_to_vec(input: &[u8]) -> Vec<u8>;
69
70 fn new() -> Self;
72
73 fn update(&mut self, input: &[u8]);
75
76 fn digest_to_vec(self) -> Vec<u8>;
78}
79
80#[derive(Clone)]
86pub struct InsecureSha1 {
87 ctx: bssl_sys::SHA_CTX,
88}
89
90unsafe_iuf_algo!(
91 InsecureSha1,
92 20,
93 64,
94 EVP_sha1,
95 SHA1,
96 SHA1_Init,
97 SHA1_Update,
98 SHA1_Final
99);
100
101#[derive(Clone)]
103pub struct Sha256 {
104 ctx: bssl_sys::SHA256_CTX,
105}
106
107unsafe_iuf_algo!(
108 Sha256,
109 32,
110 64,
111 EVP_sha256,
112 SHA256,
113 SHA256_Init,
114 SHA256_Update,
115 SHA256_Final
116);
117
118#[derive(Clone)]
120pub struct Sha384 {
121 ctx: bssl_sys::SHA512_CTX,
122}
123
124unsafe_iuf_algo!(
125 Sha384,
126 48,
127 128,
128 EVP_sha384,
129 SHA384,
130 SHA384_Init,
131 SHA384_Update,
132 SHA384_Final
133);
134
135#[derive(Clone)]
137pub struct Sha512 {
138 ctx: bssl_sys::SHA512_CTX,
139}
140
141unsafe_iuf_algo!(
142 Sha512,
143 64,
144 128,
145 EVP_sha512,
146 SHA512,
147 SHA512_Init,
148 SHA512_Update,
149 SHA512_Final
150);
151
152#[derive(Clone)]
154pub struct Sha512_256 {
155 ctx: bssl_sys::SHA512_CTX,
156}
157
158unsafe_iuf_algo!(
159 Sha512_256,
160 32,
161 128,
162 EVP_sha512_256,
163 SHA512_256,
164 SHA512_256_Init,
165 SHA512_256_Update,
166 SHA512_256_Final
167);
168
169#[cfg(test)]
170mod test {
171 use super::*;
172 use crate::test_helpers::decode_hex;
173
174 #[test]
175 fn sha256_c_type() {
176 unsafe {
177 assert_eq!(
178 MdRef::from_ptr(bssl_sys::EVP_sha256() as *mut _).as_ptr(),
179 bssl_sys::EVP_sha256() as *mut _
180 )
181 }
182 }
183
184 #[test]
185 fn sha512_c_type() {
186 unsafe {
187 assert_eq!(
188 MdRef::from_ptr(bssl_sys::EVP_sha512() as *mut _).as_ptr(),
189 bssl_sys::EVP_sha512() as *mut _
190 )
191 }
192 }
193
194 #[test]
195 fn sha1() {
196 assert_eq!(
197 decode_hex("a9993e364706816aba3e25717850c26c9cd0d89d"),
198 InsecureSha1::hash(b"abc")
199 );
200 }
201
202 #[test]
203 fn sha256() {
204 let msg: [u8; 4] = decode_hex("74ba2521");
205 let expected_digest: [u8; 32] =
206 decode_hex("b16aa56be3880d18cd41e68384cf1ec8c17680c45a02b1575dc1518923ae8b0e");
207
208 assert_eq!(Sha256::hash(&msg), expected_digest);
209
210 let mut ctx = Sha256::new();
211 ctx.update(&msg);
212 assert_eq!(expected_digest, ctx.digest());
213
214 let mut ctx = Sha256::new();
215 ctx.update(&msg[0..1]);
216 let mut ctx2 = ctx.clone();
217 ctx2.update(&msg[1..]);
218 assert_eq!(expected_digest, ctx2.digest());
219 }
220
221 #[test]
222 fn sha384() {
223 assert_eq!(
224 decode_hex("cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7"),
225 Sha384::hash(b"abc")
226 );
227 }
228
229 #[test]
230 fn sha512() {
231 let msg: [u8; 4] = decode_hex("23be86d5");
232 let expected_digest: [u8; 64] = decode_hex(concat!(
233 "76d42c8eadea35a69990c63a762f330614a4699977f058adb988f406fb0be8f2",
234 "ea3dce3a2bbd1d827b70b9b299ae6f9e5058ee97b50bd4922d6d37ddc761f8eb"
235 ));
236
237 assert_eq!(Sha512::hash(&msg), expected_digest);
238
239 let mut ctx = Sha512::new();
240 ctx.update(&msg);
241 assert_eq!(expected_digest, ctx.digest());
242 }
243
244 #[test]
245 fn sha512_256() {
246 assert_eq!(
247 decode_hex("53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23"),
248 Sha512_256::hash(b"abc")
249 );
250 }
251}