Decrypt a segment envelope produced by [`encrypt_segment_envelope`]. The caller supplies the expected `magic`; mismatches surface as [`WalError::EncryptionError`].
(
key: &WalEncryptionKey,
magic: &[u8; 4],
blob: &[u8],
)
| 412 | /// The caller supplies the expected `magic`; mismatches surface as |
| 413 | /// [`WalError::EncryptionError`]. |
| 414 | pub fn decrypt_segment_envelope( |
| 415 | key: &WalEncryptionKey, |
| 416 | magic: &[u8; 4], |
| 417 | blob: &[u8], |
| 418 | ) -> Result<Vec<u8>> { |
| 419 | if blob.len() < SEGMENT_ENVELOPE_MIN_SIZE { |
| 420 | return Err(WalError::EncryptionError { |
| 421 | detail: "encrypted envelope too short".into(), |
| 422 | }); |
| 423 | } |
| 424 | let preamble: [u8; SEGMENT_ENVELOPE_PREAMBLE_SIZE] = blob[..SEGMENT_ENVELOPE_PREAMBLE_SIZE] |
| 425 | .try_into() |
| 426 | .expect("slice is preamble size"); |
| 427 | if &preamble[0..4] != magic { |
| 428 | return Err(WalError::EncryptionError { |
| 429 | detail: "envelope preamble magic mismatch".into(), |
| 430 | }); |
| 431 | } |
| 432 | let version = u16::from_le_bytes([preamble[4], preamble[5]]); |
| 433 | if version != SEGMENT_ENVELOPE_VERSION { |
| 434 | return Err(WalError::EncryptionError { |
| 435 | detail: format!("unsupported envelope preamble version {version}"), |
| 436 | }); |
| 437 | } |
| 438 | let mut epoch = [0u8; 4]; |
| 439 | epoch.copy_from_slice(&preamble[8..12]); |
| 440 | let ciphertext = &blob[SEGMENT_ENVELOPE_PREAMBLE_SIZE..]; |
| 441 | key.decrypt_aad(&epoch, SEGMENT_ENVELOPE_NONCE_LSN, &preamble, ciphertext) |
| 442 | } |
| 443 | |
| 444 | /// Derive a 12-byte nonce from an epoch and LSN. |
| 445 | /// |
no test coverage detected