1use crate::ffi;
47use libc::c_void;
48use std::mem::MaybeUninit;
49
50#[inline]
57#[allow(deprecated)] pub fn sha1(data: &[u8]) -> [u8; 20] {
59 unsafe {
60 let mut hash: MaybeUninit<[u8; 20]> = MaybeUninit::uninit();
61 ffi::SHA1(data.as_ptr(), data.len(), hash.as_mut_ptr().cast());
62 hash.assume_init()
63 }
64}
65
66#[inline]
68#[allow(deprecated)] pub fn sha224(data: &[u8]) -> [u8; 28] {
70 unsafe {
71 let mut hash: MaybeUninit<[u8; 28]> = MaybeUninit::uninit();
72 ffi::SHA224(data.as_ptr(), data.len(), hash.as_mut_ptr().cast());
73 hash.assume_init()
74 }
75}
76
77#[inline]
79#[allow(deprecated)] pub fn sha256(data: &[u8]) -> [u8; 32] {
81 unsafe {
82 let mut hash: MaybeUninit<[u8; 32]> = MaybeUninit::uninit();
83 ffi::SHA256(data.as_ptr(), data.len(), hash.as_mut_ptr().cast());
84 hash.assume_init()
85 }
86}
87
88#[inline]
90#[allow(deprecated)] pub fn sha384(data: &[u8]) -> [u8; 48] {
92 unsafe {
93 let mut hash: MaybeUninit<[u8; 48]> = MaybeUninit::uninit();
94 ffi::SHA384(data.as_ptr(), data.len(), hash.as_mut_ptr().cast());
95 hash.assume_init()
96 }
97}
98
99#[inline]
101#[allow(deprecated)] pub fn sha512(data: &[u8]) -> [u8; 64] {
103 unsafe {
104 let mut hash: MaybeUninit<[u8; 64]> = MaybeUninit::uninit();
105 ffi::SHA512(data.as_ptr(), data.len(), hash.as_mut_ptr().cast());
106 hash.assume_init()
107 }
108}
109
110#[inline]
112#[allow(deprecated)] pub fn sha512_256(data: &[u8]) -> [u8; 32] {
114 unsafe {
115 let mut hash: MaybeUninit<[u8; 32]> = MaybeUninit::uninit();
116 ffi::SHA512_256(data.as_ptr(), data.len(), hash.as_mut_ptr().cast());
117 hash.assume_init()
118 }
119}
120
121#[derive(Clone)]
128pub struct Sha1(ffi::SHA_CTX);
129
130impl Default for Sha1 {
131 #[inline]
132 fn default() -> Sha1 {
133 Sha1::new()
134 }
135}
136
137impl Sha1 {
138 #[inline]
140 #[allow(deprecated)] pub fn new() -> Sha1 {
142 unsafe {
143 let mut ctx = MaybeUninit::uninit();
144 ffi::SHA1_Init(ctx.as_mut_ptr());
145 Sha1(ctx.assume_init())
146 }
147 }
148
149 #[inline]
153 pub fn update(&mut self, buf: &[u8]) {
154 unsafe {
155 ffi::SHA1_Update(&mut self.0, buf.as_ptr() as *const c_void, buf.len());
156 }
157 }
158
159 #[inline]
161 #[allow(deprecated)] pub fn finish(mut self) -> [u8; 20] {
163 unsafe {
164 let mut hash: MaybeUninit<[u8; 20]> = MaybeUninit::uninit();
165 ffi::SHA1_Final(hash.as_mut_ptr().cast(), &mut self.0);
166 hash.assume_init()
167 }
168 }
169}
170
171#[derive(Clone)]
173pub struct Sha224(ffi::SHA256_CTX);
174
175impl Default for Sha224 {
176 #[inline]
177 fn default() -> Sha224 {
178 Sha224::new()
179 }
180}
181
182impl Sha224 {
183 #[inline]
185 #[allow(deprecated)] pub fn new() -> Sha224 {
187 unsafe {
188 let mut ctx = MaybeUninit::uninit();
189 ffi::SHA224_Init(ctx.as_mut_ptr());
190 Sha224(ctx.assume_init())
191 }
192 }
193
194 #[inline]
198 pub fn update(&mut self, buf: &[u8]) {
199 unsafe {
200 ffi::SHA224_Update(&mut self.0, buf.as_ptr() as *const c_void, buf.len());
201 }
202 }
203
204 #[inline]
206 #[allow(deprecated)] pub fn finish(mut self) -> [u8; 28] {
208 unsafe {
209 let mut hash: MaybeUninit<[u8; 28]> = MaybeUninit::uninit();
210 ffi::SHA224_Final(hash.as_mut_ptr().cast(), &mut self.0);
211 hash.assume_init()
212 }
213 }
214}
215
216#[derive(Clone)]
218pub struct Sha256(ffi::SHA256_CTX);
219
220impl Default for Sha256 {
221 #[inline]
222 fn default() -> Sha256 {
223 Sha256::new()
224 }
225}
226
227impl Sha256 {
228 #[inline]
230 #[allow(deprecated)] pub fn new() -> Sha256 {
232 unsafe {
233 let mut ctx = MaybeUninit::uninit();
234 ffi::SHA256_Init(ctx.as_mut_ptr());
235 Sha256(ctx.assume_init())
236 }
237 }
238
239 #[inline]
243 pub fn update(&mut self, buf: &[u8]) {
244 unsafe {
245 ffi::SHA256_Update(&mut self.0, buf.as_ptr() as *const c_void, buf.len());
246 }
247 }
248
249 #[inline]
251 #[allow(deprecated)] pub fn finish(mut self) -> [u8; 32] {
253 unsafe {
254 let mut hash: MaybeUninit<[u8; 32]> = MaybeUninit::uninit();
255 ffi::SHA256_Final(hash.as_mut_ptr().cast(), &mut self.0);
256 hash.assume_init()
257 }
258 }
259}
260
261#[derive(Clone)]
263pub struct Sha384(ffi::SHA512_CTX);
264
265impl Default for Sha384 {
266 #[inline]
267 fn default() -> Sha384 {
268 Sha384::new()
269 }
270}
271
272impl Sha384 {
273 #[inline]
275 #[allow(deprecated)] pub fn new() -> Sha384 {
277 unsafe {
278 let mut ctx = MaybeUninit::uninit();
279 ffi::SHA384_Init(ctx.as_mut_ptr());
280 Sha384(ctx.assume_init())
281 }
282 }
283
284 #[inline]
288 pub fn update(&mut self, buf: &[u8]) {
289 unsafe {
290 ffi::SHA384_Update(&mut self.0, buf.as_ptr() as *const c_void, buf.len());
291 }
292 }
293
294 #[inline]
296 #[allow(deprecated)] pub fn finish(mut self) -> [u8; 48] {
298 unsafe {
299 let mut hash: MaybeUninit<[u8; 48]> = MaybeUninit::uninit();
300 ffi::SHA384_Final(hash.as_mut_ptr().cast(), &mut self.0);
301 hash.assume_init()
302 }
303 }
304}
305
306#[derive(Clone)]
308pub struct Sha512(ffi::SHA512_CTX);
309
310impl Default for Sha512 {
311 #[inline]
312 fn default() -> Sha512 {
313 Sha512::new()
314 }
315}
316
317impl Sha512 {
318 #[inline]
320 #[allow(deprecated)] pub fn new() -> Sha512 {
322 unsafe {
323 let mut ctx = MaybeUninit::uninit();
324 ffi::SHA512_Init(ctx.as_mut_ptr());
325 Sha512(ctx.assume_init())
326 }
327 }
328
329 #[inline]
333 pub fn update(&mut self, buf: &[u8]) {
334 unsafe {
335 ffi::SHA512_Update(&mut self.0, buf.as_ptr() as *const c_void, buf.len());
336 }
337 }
338
339 #[inline]
341 #[allow(deprecated)] pub fn finish(mut self) -> [u8; 64] {
343 unsafe {
344 let mut hash: MaybeUninit<[u8; 64]> = MaybeUninit::uninit();
345 ffi::SHA512_Final(hash.as_mut_ptr().cast(), &mut self.0);
346 hash.assume_init()
347 }
348 }
349}
350
351#[derive(Clone)]
353pub struct Sha512_256(ffi::SHA512_CTX);
354
355impl Default for Sha512_256 {
356 #[inline]
357 fn default() -> Sha512_256 {
358 Sha512_256::new()
359 }
360}
361
362impl Sha512_256 {
363 #[inline]
365 #[allow(deprecated)] pub fn new() -> Sha512_256 {
367 unsafe {
368 let mut ctx = MaybeUninit::uninit();
369 ffi::SHA512_256_Init(ctx.as_mut_ptr());
370 Sha512_256(ctx.assume_init())
371 }
372 }
373
374 #[inline]
378 pub fn update(&mut self, buf: &[u8]) {
379 unsafe {
380 ffi::SHA512_256_Update(&mut self.0, buf.as_ptr() as *const c_void, buf.len());
381 }
382 }
383
384 #[inline]
386 #[allow(deprecated)] pub fn finish(mut self) -> [u8; 32] {
388 unsafe {
389 let mut hash: MaybeUninit<[u8; 32]> = MaybeUninit::uninit();
390 ffi::SHA512_256_Final(hash.as_mut_ptr().cast(), &mut self.0);
391 hash.assume_init()
392 }
393 }
394}
395
396#[cfg(test)]
397mod test {
398 use hex;
399
400 use super::*;
401
402 #[test]
403 fn standalone_1() {
404 let data = b"abc";
405 let expected = "a9993e364706816aba3e25717850c26c9cd0d89d";
406
407 assert_eq!(hex::encode(sha1(data)), expected);
408 }
409
410 #[test]
411 fn struct_1() {
412 let expected = "a9993e364706816aba3e25717850c26c9cd0d89d";
413
414 let mut hasher = Sha1::new();
415 hasher.update(b"a");
416 hasher.update(b"bc");
417 assert_eq!(hex::encode(hasher.finish()), expected);
418 }
419
420 #[test]
421 fn cloning_allows_incremental_hashing() {
422 let expected = "a9993e364706816aba3e25717850c26c9cd0d89d";
423
424 let mut hasher = Sha1::new();
425 hasher.update(b"a");
426
427 let mut incr_hasher = hasher.clone();
428 incr_hasher.update(b"bc");
429
430 assert_eq!(hex::encode(incr_hasher.finish()), expected);
431 assert_ne!(hex::encode(hasher.finish()), expected);
432 }
433
434 #[test]
435 fn standalone_224() {
436 let data = b"abc";
437 let expected = "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7";
438
439 assert_eq!(hex::encode(sha224(data)), expected);
440 }
441
442 #[test]
443 fn struct_224() {
444 let expected = "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7";
445
446 let mut hasher = Sha224::new();
447 hasher.update(b"a");
448 hasher.update(b"bc");
449 assert_eq!(hex::encode(hasher.finish()), expected);
450 }
451
452 #[test]
453 fn standalone_256() {
454 let data = b"abc";
455 let expected = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";
456
457 assert_eq!(hex::encode(sha256(data)), expected);
458 }
459
460 #[test]
461 fn struct_256() {
462 let expected = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";
463
464 let mut hasher = Sha256::new();
465 hasher.update(b"a");
466 hasher.update(b"bc");
467 assert_eq!(hex::encode(hasher.finish()), expected);
468 }
469
470 #[test]
471 fn standalone_384() {
472 let data = b"abc";
473 let expected =
474 "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e\
475 7cc2358baeca134c825a7";
476
477 assert_eq!(hex::encode(&sha384(data)[..]), expected);
478 }
479
480 #[test]
481 fn struct_384() {
482 let expected =
483 "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e\
484 7cc2358baeca134c825a7";
485
486 let mut hasher = Sha384::new();
487 hasher.update(b"a");
488 hasher.update(b"bc");
489 assert_eq!(hex::encode(&hasher.finish()[..]), expected);
490 }
491
492 #[test]
493 fn standalone_512() {
494 let data = b"abc";
495 let expected =
496 "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274\
497 fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
498
499 assert_eq!(hex::encode(&sha512(data)[..]), expected);
500 }
501
502 #[test]
503 fn struct_512() {
504 let expected =
505 "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274\
506 fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
507
508 let mut hasher = Sha512::new();
509 hasher.update(b"a");
510 hasher.update(b"bc");
511 assert_eq!(hex::encode(&hasher.finish()[..]), expected);
512 }
513
514 #[test]
515 fn standalone_512_256() {
516 let data = b"abc";
517 let expected = "53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23";
518
519 assert_eq!(hex::encode(&sha512_256(data)[..]), expected);
520 }
521
522 #[test]
523 fn struct_512_256() {
524 let expected = "53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23";
525
526 let mut hasher = Sha512_256::new();
527 hasher.update(b"a");
528 hasher.update(b"bc");
529 assert_eq!(hex::encode(&hasher.finish()[..]), expected);
530 }
531}