apple_cryptokit/hashing/
sha256.rs1use super::HashFunction;
4use std::ffi::c_void;
5
6pub const SHA256_OUTPUT_SIZE: usize = 32;
8
9extern "C" {
11 #[link_name = "sha256_hash"]
12 fn swift_sha256_hash(data: *const u8, length: i32, out_hash: *mut u8);
13
14 #[link_name = "sha256_init"]
15 fn swift_sha256_init() -> *mut c_void;
16
17 #[link_name = "sha256_update"]
18 fn swift_sha256_update(ptr: *mut c_void, data: *const u8, len: i32);
19
20 #[link_name = "sha256_finalize"]
21 fn swift_sha256_finalize(ptr: *mut c_void, out: *mut u8);
22
23 #[link_name = "sha256_free"]
24 fn swift_sha256_free(ptr: *mut c_void);
25}
26
27pub fn sha256_hash(data: &[u8]) -> [u8; 32] {
29 let mut output = [0u8; 32];
30 sha256_hash_to(data, &mut output);
31 output
32}
33
34pub fn sha256_hash_to(data: &[u8], output: &mut [u8]) {
42 assert!(
43 output.len() >= SHA256_OUTPUT_SIZE,
44 "Output buffer too small: {} < {}",
45 output.len(),
46 SHA256_OUTPUT_SIZE
47 );
48 unsafe {
49 swift_sha256_hash(data.as_ptr(), data.len() as i32, output.as_mut_ptr());
50 }
51}
52
53pub struct Sha256 {
55 ptr: *mut c_void,
56}
57
58impl Sha256 {
59 pub fn new() -> Self {
61 let ptr = unsafe { swift_sha256_init() };
62 Self { ptr }
63 }
64
65 pub fn update(&mut self, data: &[u8]) {
67 unsafe {
68 swift_sha256_update(self.ptr, data.as_ptr(), data.len() as i32);
69 }
70 }
71
72 pub fn finalize(self) -> [u8; 32] {
74 self.snapshot()
75 }
76
77 pub fn snapshot(&self) -> [u8; 32] {
78 let mut hash = [0u8; 32];
79 unsafe {
80 swift_sha256_finalize(self.ptr, hash.as_mut_ptr());
81 }
82 hash
83 }
84}
85
86impl Default for Sha256 {
87 fn default() -> Self {
88 Self::new()
89 }
90}
91
92impl Drop for Sha256 {
93 fn drop(&mut self) {
94 unsafe {
95 swift_sha256_free(self.ptr);
96 }
97 }
98}
99
100pub struct SHA256;
102
103impl HashFunction for SHA256 {
104 const OUTPUT_SIZE: usize = SHA256_OUTPUT_SIZE;
105
106 fn hash_to(data: &[u8], output: &mut [u8]) {
107 sha256_hash_to(data, output)
108 }
109}
110
111pub use SHA256 as Sha256Algorithm;