common_crypto/
hash.rs

1use std::ffi::c_void;
2
3pub struct Hash;
4
5macro_rules! implement_hash {
6    ($func:ident, $struct:ident, $ctx:ident, $one_shot:ident, $init:ident, $update:ident, $final:ident, $len:expr) => {
7        extern "C" {
8            fn $one_shot(data: *const c_void, len: i32, output: *mut u8) -> *mut u8;
9            fn $init(ctx: *mut $ctx) -> i32;
10            fn $update(ctx: *mut $ctx, data: *const c_void, len: i32) -> i32;
11            fn $final(output: *mut c_void, ctx: *mut $ctx) -> i32;
12        }
13
14        impl Hash {
15            pub fn $func(data: impl AsRef<[u8]>) -> [u8; $len] {
16                let mut output = [0u8; $len];
17
18                unsafe {
19                    $one_shot(
20                        data.as_ref().as_ptr() as *const c_void,
21                        data.as_ref().len() as i32,
22                        output.as_mut_ptr(),
23                    );
24                }
25
26                output
27            }
28        }
29
30        pub struct $struct {
31            ctx: $ctx,
32        }
33
34        impl $struct {
35            pub fn new() -> Self {
36                let mut ctx = $ctx::default();
37
38                unsafe {
39                    $init(&mut ctx);
40                }
41
42                Self { ctx }
43            }
44
45            pub fn update(&mut self, data: impl AsRef<[u8]>) {
46                unsafe {
47                    $update(
48                        &mut self.ctx,
49                        data.as_ref().as_ptr() as *const c_void,
50                        data.as_ref().len() as i32,
51                    );
52                }
53            }
54
55            pub fn finish(mut self) -> [u8; $len] {
56                let mut output = [0u8; $len];
57                unsafe { $final(output.as_mut_ptr() as *mut c_void, &mut self.ctx) };
58                output
59            }
60        }
61    };
62}
63
64#[repr(C)]
65#[derive(Default)]
66struct SHA1Context {
67    h0: u32,
68    h1: u32,
69    h2: u32,
70    h3: u32,
71    h4: u32,
72    nl: u32,
73    nh: u32,
74    data: [u32; 16],
75    num: i32,
76}
77implement_hash!(
78    sha1,
79    SHA1,
80    SHA1Context,
81    CC_SHA1,
82    CC_SHA1_Init,
83    CC_SHA1_Update,
84    CC_SHA1_Final,
85    20
86);
87
88#[repr(C)]
89#[derive(Default)]
90struct SHA256Context {
91    count: [u32; 2],
92    hash: [u32; 8],
93    wbuf: [u32; 16],
94}
95
96implement_hash!(
97    sha224,
98    SHA224,
99    SHA256Context,
100    CC_SHA224,
101    CC_SHA224_Init,
102    CC_SHA224_Update,
103    CC_SHA224_Final,
104    28
105);
106
107implement_hash!(
108    sha256,
109    SHA256,
110    SHA256Context,
111    CC_SHA256,
112    CC_SHA256_Init,
113    CC_SHA256_Update,
114    CC_SHA256_Final,
115    32
116);
117
118#[repr(C)]
119#[derive(Default)]
120struct SHA512Context {
121    count: [u64; 2],
122    hash: [u64; 8],
123    wbuf: [u64; 16],
124}
125
126implement_hash!(
127    sha384,
128    SHA384,
129    SHA512Context,
130    CC_SHA384,
131    CC_SHA384_Init,
132    CC_SHA384_Update,
133    CC_SHA384_Final,
134    48
135);
136
137implement_hash!(
138    sha512,
139    SHA512,
140    SHA512Context,
141    CC_SHA512,
142    CC_SHA512_Init,
143    CC_SHA512_Update,
144    CC_SHA512_Final,
145    64
146);
147
148#[repr(C)]
149#[derive(Default)]
150struct MD2Context {
151    num: i32,
152    data: [u8; 16],
153    cksm: [u32; 16],
154    state: [u32; 16],
155}
156
157implement_hash!(
158    md2,
159    MD2,
160    MD2Context,
161    CC_MD2,
162    CC_MD2_Init,
163    CC_MD2_Update,
164    CC_MD2_Final,
165    16
166);
167
168#[repr(C)]
169#[derive(Default)]
170struct MD4Context {
171    a: u32,
172    b: u32,
173    c: u32,
174    d: u32,
175    nl: u32,
176    nh: u32,
177    data: [u32; 16],
178    num: i32,
179}
180
181implement_hash!(
182    md4,
183    MD4,
184    MD4Context,
185    CC_MD4,
186    CC_MD4_Init,
187    CC_MD4_Update,
188    CC_MD4_Final,
189    16
190);
191
192#[repr(C)]
193#[derive(Default)]
194struct MD5Context {
195    a: u32,
196    b: u32,
197    c: u32,
198    d: u32,
199    nl: u32,
200    nh: u32,
201    data: [u32; 16],
202    num: i32,
203}
204
205implement_hash!(
206    md5,
207    MD5,
208    MD5Context,
209    CC_MD5,
210    CC_MD5_Init,
211    CC_MD5_Update,
212    CC_MD5_Final,
213    16
214);