| 240 | } |
| 241 | |
| 242 | pub fn encrypt_into( |
| 243 | &self, |
| 244 | target: &mut Vec<u8>, |
| 245 | nonce: &[u8], |
| 246 | client_nonce: &[u8], |
| 247 | plaintext: Vec<u8>, |
| 248 | max_target_size: usize, |
| 249 | ) -> Result<(), Error> { |
| 250 | ensure!( |
| 251 | max_target_size >= crypto_box_curve25519xchacha20poly1305_MACBYTES as usize, |
| 252 | "Max target size too small" |
| 253 | ); |
| 254 | let plaintext_len = plaintext.len(); |
| 255 | let max_padded_plaintext_len = |
| 256 | max_target_size - crypto_box_curve25519xchacha20poly1305_MACBYTES as usize; |
| 257 | let mut hasher = SipHasher13::new(); |
| 258 | hasher.write(&self.0); |
| 259 | hasher.write(client_nonce); |
| 260 | let pad_size: usize = 1 + (hasher.finish() as usize & 0xff); |
| 261 | let mut padded_plaintext_len = (plaintext_len + pad_size) & !63; |
| 262 | if padded_plaintext_len < plaintext_len { |
| 263 | padded_plaintext_len += 256; |
| 264 | } |
| 265 | if padded_plaintext_len > max_padded_plaintext_len { |
| 266 | padded_plaintext_len = max_padded_plaintext_len; |
| 267 | } |
| 268 | ensure!(padded_plaintext_len > plaintext_len, "No room for padding"); |
| 269 | let mut padded_plaintext = plaintext; |
| 270 | padded_plaintext.push(0x80); |
| 271 | while padded_plaintext.len() != padded_plaintext_len { |
| 272 | padded_plaintext.push(0x00); |
| 273 | } |
| 274 | let padded_plaintext_len = padded_plaintext.len(); |
| 275 | let target_header_len = target.len(); |
| 276 | target.resize( |
| 277 | target_header_len |
| 278 | + padded_plaintext_len |
| 279 | + crypto_box_curve25519xchacha20poly1305_MACBYTES as usize, |
| 280 | 0, |
| 281 | ); |
| 282 | let encrypted = &mut target[target_header_len..]; |
| 283 | let res = unsafe { |
| 284 | libsodium_sys::crypto_box_curve25519xchacha20poly1305_easy_afternm( |
| 285 | encrypted.as_mut_ptr(), |
| 286 | padded_plaintext.as_ptr(), |
| 287 | padded_plaintext_len as _, |
| 288 | nonce.as_ptr(), |
| 289 | self.0.as_ptr(), |
| 290 | ) |
| 291 | }; |
| 292 | ensure!(res == 0, "Unable to encrypt"); |
| 293 | Ok(()) |
| 294 | } |
| 295 | } |
| 296 | |
| 297 | pub fn bin2hex(bin: &[u8]) -> String { |