@@ -7,6 +7,13 @@ use wacore_appstate::{
77 expand_app_state_keys,
88} ;
99
10+ #[ inline]
11+ fn bytes_to_uint8array ( bytes : & [ u8 ] ) -> Uint8Array {
12+ let arr = Uint8Array :: new_with_length ( bytes. len ( ) as u32 ) ;
13+ arr. copy_from ( bytes) ;
14+ arr
15+ }
16+
1017#[ wasm_bindgen]
1118pub struct LTHashAntiTampering {
1219 inner : & ' static LTHash ,
@@ -56,9 +63,7 @@ impl LTHashAntiTampering {
5663 . inner
5764 . subtract_then_add ( base, & subtract_vecs, & add_vecs) ;
5865
59- let output = Uint8Array :: new_with_length ( result. len ( ) as u32 ) ;
60- output. copy_from ( & result) ;
61- Ok ( output)
66+ Ok ( bytes_to_uint8array ( & result) )
6267 }
6368}
6469
@@ -78,37 +83,27 @@ pub struct ExpandedAppStateKeys {
7883impl ExpandedAppStateKeys {
7984 #[ wasm_bindgen( getter, js_name = indexKey) ]
8085 pub fn index_key ( & self ) -> Uint8Array {
81- let arr = Uint8Array :: new_with_length ( 32 ) ;
82- arr. copy_from ( & self . inner . index ) ;
83- arr
86+ bytes_to_uint8array ( & self . inner . index )
8487 }
8588
8689 #[ wasm_bindgen( getter, js_name = valueEncryptionKey) ]
8790 pub fn value_encryption_key ( & self ) -> Uint8Array {
88- let arr = Uint8Array :: new_with_length ( 32 ) ;
89- arr. copy_from ( & self . inner . value_encryption ) ;
90- arr
91+ bytes_to_uint8array ( & self . inner . value_encryption )
9192 }
9293
9394 #[ wasm_bindgen( getter, js_name = valueMacKey) ]
9495 pub fn value_mac_key ( & self ) -> Uint8Array {
95- let arr = Uint8Array :: new_with_length ( 32 ) ;
96- arr. copy_from ( & self . inner . value_mac ) ;
97- arr
96+ bytes_to_uint8array ( & self . inner . value_mac )
9897 }
9998
10099 #[ wasm_bindgen( getter, js_name = snapshotMacKey) ]
101100 pub fn snapshot_mac_key ( & self ) -> Uint8Array {
102- let arr = Uint8Array :: new_with_length ( 32 ) ;
103- arr. copy_from ( & self . inner . snapshot_mac ) ;
104- arr
101+ bytes_to_uint8array ( & self . inner . snapshot_mac )
105102 }
106103
107104 #[ wasm_bindgen( getter, js_name = patchMacKey) ]
108105 pub fn patch_mac_key ( & self ) -> Uint8Array {
109- let arr = Uint8Array :: new_with_length ( 32 ) ;
110- arr. copy_from ( & self . inner . patch_mac ) ;
111- arr
106+ bytes_to_uint8array ( & self . inner . patch_mac )
112107 }
113108}
114109
@@ -151,9 +146,7 @@ impl LTHashState {
151146
152147 #[ wasm_bindgen( getter) ]
153148 pub fn hash ( & self ) -> Uint8Array {
154- let arr = Uint8Array :: new_with_length ( self . hash . len ( ) as u32 ) ;
155- arr. copy_from ( & self . hash ) ;
156- arr
149+ bytes_to_uint8array ( & self . hash )
157150 }
158151
159152 #[ wasm_bindgen( setter) ]
@@ -166,11 +159,9 @@ impl LTHashState {
166159
167160 #[ wasm_bindgen( js_name = getValueMac) ]
168161 pub fn get_value_mac ( & self , index_mac_base64 : & str ) -> Option < Uint8Array > {
169- self . index_value_map . get ( index_mac_base64) . map ( |v| {
170- let arr = Uint8Array :: new_with_length ( v. len ( ) as u32 ) ;
171- arr. copy_from ( v) ;
172- arr
173- } )
162+ self . index_value_map
163+ . get ( index_mac_base64)
164+ . map ( |v| bytes_to_uint8array ( v) )
174165 }
175166
176167 #[ wasm_bindgen( js_name = setValueMac) ]
@@ -201,36 +192,46 @@ impl Default for LTHashState {
201192 }
202193}
203194
195+ fn validate_key_length ( key : & [ u8 ] , expected : usize , name : & str ) -> Result < ( ) , JsValue > {
196+ if key. len ( ) != expected {
197+ return Err ( JsValue :: from_str ( & format ! (
198+ "{} must be {} bytes, got {}" ,
199+ name,
200+ expected,
201+ key. len( )
202+ ) ) ) ;
203+ }
204+ Ok ( ( ) )
205+ }
206+
207+ fn create_mac (
208+ algo : & str ,
209+ key : & [ u8 ] ,
210+ ) -> Result < wacore_libsignal:: crypto:: CryptographicMac , JsValue > {
211+ wacore_libsignal:: crypto:: CryptographicMac :: new ( algo, key)
212+ . map_err ( |e| JsValue :: from_str ( & format ! ( "Failed to create MAC: {}" , e) ) )
213+ }
214+
204215#[ wasm_bindgen( js_name = generateContentMac) ]
205216pub fn generate_content_mac (
206217 operation : u8 ,
207218 data : & [ u8 ] ,
208219 key_id : & [ u8 ] ,
209220 key : & [ u8 ] ,
210221) -> Result < Uint8Array , JsValue > {
211- use wacore_libsignal:: crypto:: CryptographicMac ;
212-
213- if key. len ( ) != 32 {
214- return Err ( JsValue :: from_str ( & format ! (
215- "Value MAC key must be 32 bytes, got {}" ,
216- key. len( )
217- ) ) ) ;
218- }
222+ validate_key_length ( key, 32 , "Value MAC key" ) ?;
219223
220224 let op_byte = [ operation] ;
221225 let key_data_length = ( ( key_id. len ( ) + 1 ) as u64 ) . to_be_bytes ( ) ;
222226
223- let mut mac = CryptographicMac :: new ( "HmacSha512" , key)
224- . map_err ( |e| JsValue :: from_str ( & format ! ( "Failed to create MAC: {}" , e) ) ) ?;
227+ let mut mac = create_mac ( "HmacSha512" , key) ?;
225228 mac. update ( & op_byte) ;
226229 mac. update ( key_id) ;
227230 mac. update ( data) ;
228231 mac. update ( & key_data_length) ;
229232 let mac_full = mac. finalize ( ) ;
230233
231- let result = Uint8Array :: new_with_length ( 32 ) ;
232- result. copy_from ( & mac_full[ ..32 ] ) ;
233- Ok ( result)
234+ Ok ( bytes_to_uint8array ( & mac_full[ ..32 ] ) )
234235}
235236
236237#[ wasm_bindgen( js_name = generateSnapshotMac) ]
@@ -240,34 +241,15 @@ pub fn generate_snapshot_mac(
240241 name : & str ,
241242 key : & [ u8 ] ,
242243) -> Result < Uint8Array , JsValue > {
243- use wacore_libsignal:: crypto:: CryptographicMac ;
244-
245- if lt_hash. len ( ) != 128 {
246- return Err ( JsValue :: from_str ( & format ! (
247- "LT-Hash must be 128 bytes, got {}" ,
248- lt_hash. len( )
249- ) ) ) ;
250- }
251-
252- if key. len ( ) != 32 {
253- return Err ( JsValue :: from_str ( & format ! (
254- "Snapshot MAC key must be 32 bytes, got {}" ,
255- key. len( )
256- ) ) ) ;
257- }
258-
259- let version_be = version. to_be_bytes ( ) ;
244+ validate_key_length ( lt_hash, 128 , "LT-Hash" ) ?;
245+ validate_key_length ( key, 32 , "Snapshot MAC key" ) ?;
260246
261- let mut mac = CryptographicMac :: new ( "HmacSha256" , key)
262- . map_err ( |e| JsValue :: from_str ( & format ! ( "Failed to create MAC: {}" , e) ) ) ?;
247+ let mut mac = create_mac ( "HmacSha256" , key) ?;
263248 mac. update ( lt_hash) ;
264- mac. update ( & version_be ) ;
249+ mac. update ( & version . to_be_bytes ( ) ) ;
265250 mac. update ( name. as_bytes ( ) ) ;
266- let mac_result = mac. finalize ( ) ;
267251
268- let result = Uint8Array :: new_with_length ( mac_result. len ( ) as u32 ) ;
269- result. copy_from ( & mac_result) ;
270- Ok ( result)
252+ Ok ( bytes_to_uint8array ( & mac. finalize ( ) ) )
271253}
272254
273255#[ wasm_bindgen( js_name = generatePatchMac) ]
@@ -278,64 +260,39 @@ pub fn generate_patch_mac(
278260 name : & str ,
279261 key : & [ u8 ] ,
280262) -> Result < Uint8Array , JsValue > {
281- use wacore_libsignal :: crypto :: CryptographicMac ;
263+ validate_key_length ( key , 32 , "Patch MAC key" ) ? ;
282264
283- if key. len ( ) != 32 {
284- return Err ( JsValue :: from_str ( & format ! (
285- "Patch MAC key must be 32 bytes, got {}" ,
286- key. len( )
287- ) ) ) ;
288- }
289-
290- let version_be = version. to_be_bytes ( ) ;
291-
292- let mut mac = CryptographicMac :: new ( "HmacSha256" , key)
293- . map_err ( |e| JsValue :: from_str ( & format ! ( "Failed to create MAC: {}" , e) ) ) ?;
265+ let mut mac = create_mac ( "HmacSha256" , key) ?;
294266 mac. update ( snapshot_mac) ;
295267
296268 // Use stack buffer for value MACs (typically 32 bytes) to avoid heap allocations
297- let mut value_mac_buf = [ 0u8 ; 64 ] ; // Support up to 64 byte MACs
269+ let mut value_mac_buf = [ 0u8 ; 64 ] ;
298270 for value_mac in & value_macs {
299271 let len = value_mac. length ( ) as usize ;
300272 if len <= 64 {
301273 value_mac. copy_to ( & mut value_mac_buf[ ..len] ) ;
302274 mac. update ( & value_mac_buf[ ..len] ) ;
303275 } else {
304- // Fallback for larger MACs (unlikely)
305276 let mut vec = vec ! [ 0u8 ; len] ;
306277 value_mac. copy_to ( & mut vec) ;
307278 mac. update ( & vec) ;
308279 }
309280 }
310281
311- mac. update ( & version_be ) ;
282+ mac. update ( & version . to_be_bytes ( ) ) ;
312283 mac. update ( name. as_bytes ( ) ) ;
313- let mac_result = mac. finalize ( ) ;
314284
315- let result = Uint8Array :: new_with_length ( mac_result. len ( ) as u32 ) ;
316- result. copy_from ( & mac_result) ;
317- Ok ( result)
285+ Ok ( bytes_to_uint8array ( & mac. finalize ( ) ) )
318286}
319287
320288#[ wasm_bindgen( js_name = generateIndexMac) ]
321289pub fn generate_index_mac ( index_bytes : & [ u8 ] , key : & [ u8 ] ) -> Result < Uint8Array , JsValue > {
322- use wacore_libsignal:: crypto:: CryptographicMac ;
323-
324- if key. len ( ) != 32 {
325- return Err ( JsValue :: from_str ( & format ! (
326- "Index key must be 32 bytes, got {}" ,
327- key. len( )
328- ) ) ) ;
329- }
290+ validate_key_length ( key, 32 , "Index key" ) ?;
330291
331- let mut mac = CryptographicMac :: new ( "HmacSha256" , key)
332- . map_err ( |e| JsValue :: from_str ( & format ! ( "Failed to create MAC: {}" , e) ) ) ?;
292+ let mut mac = create_mac ( "HmacSha256" , key) ?;
333293 mac. update ( index_bytes) ;
334- let mac_result = mac. finalize ( ) ;
335294
336- let result = Uint8Array :: new_with_length ( mac_result. len ( ) as u32 ) ;
337- result. copy_from ( & mac_result) ;
338- Ok ( result)
295+ Ok ( bytes_to_uint8array ( & mac. finalize ( ) ) )
339296}
340297
341298#[ cfg( test) ]
0 commit comments