(decoded: &[u8])
| 2 | use obfstr::obfstr; |
| 3 | |
| 4 | pub unsafe fn decrypt(decoded: &[u8]) -> Result<(usize, usize), String> { |
| 5 | use chacha20poly1305::{XChaCha20Poly1305, Key, XNonce}; |
| 6 | use chacha20poly1305::aead::{AeadInPlace, KeyInit}; |
| 7 | |
| 8 | let key_len = 32; |
| 9 | let nonce_len = 24; |
| 10 | let tag_len = 16; |
| 11 | |
| 12 | if decoded.len() < key_len + nonce_len + tag_len { |
| 13 | return Err(obfstr!("xchacha20 payload too short").to_string()); |
| 14 | } |
| 15 | |
| 16 | let key_bytes = &decoded[0..key_len]; |
| 17 | let nonce_bytes = &decoded[key_len..key_len + nonce_len]; |
| 18 | let tag_bytes = &decoded[key_len + nonce_len..key_len + nonce_len + tag_len]; |
| 19 | let ciphertext = &decoded[key_len + nonce_len + tag_len..]; |
| 20 | |
| 21 | let p = unsafe { alloc_mem(ciphertext.len())? }; |
| 22 | std::ptr::copy_nonoverlapping(ciphertext.as_ptr(), p, ciphertext.len()); |
| 23 | |
| 24 | let buf = std::slice::from_raw_parts_mut(p, ciphertext.len()); |
| 25 | |
| 26 | let key = Key::from_slice(key_bytes); |
| 27 | let nonce = XNonce::from_slice(nonce_bytes); |
| 28 | let tag = chacha20poly1305::Tag::from_slice(tag_bytes); |
| 29 | |
| 30 | let cipher = XChaCha20Poly1305::new(key); |
| 31 | |
| 32 | cipher.decrypt_in_place_detached(nonce, b"", buf, tag) |
| 33 | .map_err(|_| obfstr!("xchacha20 decrypt fail").to_string())?; |
| 34 | |
| 35 | Ok((p as usize, ciphertext.len())) |
| 36 | } |
nothing calls this directly
no test coverage detected