(data: &[u8])
| 5 | use sha2::Sha256; |
| 6 | |
| 7 | pub fn decrypt(data: &[u8]) -> Result<(*mut u8, usize), Box<dyn std::error::Error>> { |
| 8 | if data.len() < 32 + 33 + 12 + 16 { |
| 9 | return Err("Data too short".into()); |
| 10 | } |
| 11 | |
| 12 | let priv_key_bytes = &data[0..32]; |
| 13 | let peer_pub_bytes = &data[32..32+33]; |
| 14 | let nonce = &data[32+33..32+33+12]; |
| 15 | let ciphertext_with_tag = &data[32+33+12..]; |
| 16 | |
| 17 | let priv_key = SecretKey::from_bytes(priv_key_bytes.into()) |
| 18 | .map_err(|e| format!("Invalid private key: {}", e))?; |
| 19 | |
| 20 | let peer_pub = PublicKey::from_sec1_bytes(peer_pub_bytes) |
| 21 | .map_err(|e| format!("Invalid public key: {}", e))?; |
| 22 | |
| 23 | let shared_secret = elliptic_curve::ecdh::diffie_hellman( |
| 24 | priv_key.to_nonzero_scalar(), |
| 25 | peer_pub.as_affine() |
| 26 | ); |
| 27 | |
| 28 | let hkdf = Hkdf::<Sha256>::new(None, shared_secret.raw_secret_bytes().as_ref()); |
| 29 | let mut key_bytes = [0u8; 32]; |
| 30 | hkdf.expand(&[], &mut key_bytes).map_err(|_| "HKDF expansion failed")?; |
| 31 | |
| 32 | let key = Key::<Aes256Gcm>::from_slice(&key_bytes); |
| 33 | let cipher = Aes256Gcm::new(key); |
| 34 | let nonce_slice = Nonce::from_slice(nonce); |
| 35 | |
| 36 | let tag_pos = ciphertext_with_tag.len() - 16; |
| 37 | let ciphertext = &ciphertext_with_tag[..tag_pos]; |
| 38 | let tag = Tag::from_slice(&ciphertext_with_tag[tag_pos..]); |
| 39 | |
| 40 | let plaintext_len = ciphertext.len(); |
| 41 | |
| 42 | let ptr = unsafe { crate::alloc_mem::alloc_mem(plaintext_len).map_err(|e| e)? }; |
| 43 | |
| 44 | if ptr.is_null() { |
| 45 | return Err("Memory allocation failed".into()); |
| 46 | } |
| 47 | |
| 48 | unsafe { |
| 49 | std::ptr::copy_nonoverlapping(ciphertext.as_ptr(), ptr, plaintext_len); |
| 50 | } |
| 51 | |
| 52 | let mut buffer = unsafe { std::slice::from_raw_parts_mut(ptr, plaintext_len) }; |
| 53 | |
| 54 | match cipher.decrypt_in_place_detached(nonce_slice, &[], &mut buffer, tag) { |
| 55 | Ok(_) => { |
| 56 | Ok((ptr, plaintext_len)) |
| 57 | } |
| 58 | Err(_) => { |
| 59 | Err("Decryption failed".into()) |
| 60 | } |
| 61 | } |
| 62 | } |
nothing calls this directly
no test coverage detected