Skip to content

feat(streaming): add high-level streaming encrypt/decrypt API #44

Closed
Adel-Ayoub wants to merge 4 commits into
devfrom
adelayoub/streaming-encrypt-decrypt
Closed

feat(streaming): add high-level streaming encrypt/decrypt API #44
Adel-Ayoub wants to merge 4 commits into
devfrom
adelayoub/streaming-encrypt-decrypt

Conversation

@Adel-Ayoub

Copy link
Copy Markdown
Collaborator

Summary

  • Add streaming file encryption/decryption with 64KB AEAD chunks and FRB StreamSink progress reporting
  • Atomic temp-file-then-rename with TempFileGuard drop guard — failed decrypt never leaves plaintext on disk
  • 9-byte AAD (chunk_index + is_final) prevents reorder, duplication, deletion, truncation, and append attacks
  • Uniform encrypted chunk sizes on disk (last chunk padded) — no file-size leakage
  • Header algorithm cross-checked against cipher at decrypt time
  • pub(crate) methods on CipherHandle for internal streaming use
  • Generated Dart bindings untracked from git (honor .gitignore)
  • 16 new streaming API tests, 117 total tests pass, clippy clean

Files Changed

  • rust/src/api/streaming.rsnew encrypt/decrypt impl + FRB wrappers + 16 tests
  • rust/src/api/encryption/mod.rs — add encrypt_raw, decrypt_raw, algorithm_id pub(crate)
  • rust/src/api/mod.rs — add pub mod streaming
  • rust/Cargo.toml — add tempfile = "3" dev-dependency
  • rust/src/frb_generated.rs — codegen updated (StreamSink support)
  • lib/src/rust/** — untracked generated Dart bindings

Security

Attack Prevention
Chunk reorder Index in AAD → auth fails
Chunk deletion Subsequent indices wrong → auth fails
Truncation Missing is_final=0x01 → detected
Append after final Decryptor stops at sentinel
Tampered padding Zero-byte validation → DecryptionFailed
Partial output on failure TempFileGuard deletes temp file on drop

Test plan

  • cargo test streaming — 16 tests pass (roundtrip, tamper, reorder, truncation, progress, cleanup)
  • cargo clippy -- -D warnings — clean (with and without testing feature)
  • flutter_rust_bridge_codegen generate — succeeds
  • total tests pass

…6B): magic/version/algorithm/reserved

  - ChunkAad (9B): index(u64 LE) + is_final(u8) for truncation protection                                          - ChunkReader: fill-in-place zero-alloc read_chunk(&mut chunk)
  - ChunkWriter: internal buffer for single-syscall writes
  - Last-chunk padding with zero-byte validation
  - EncryptedChunk pre-allocation + Default
  - StreamAlgorithm <-> Algorithm conversion bridge
  - Generic finish() + finish_file() for fsync
  - 22 unit tests covering all acceptance criteria
feat(streaming): add low-level streaming primitives                  …
  - encrypt_file_impl / decrypt_file_impl: 64KB AEAD chunk streaming
  - Per-chunk AAD (index + is_final) prevents reorder/truncation/append
  - Last-chunk padding to uniform ENCRYPTED_CHUNK_SIZE
  - Atomic temp-file-then-rename: failed ops leave no partial output
  - Algorithm cross-check between header and CipherHandle
  - Progress callbacks (0.0..1.0) via closure, FRB StreamSink wrappers
  - CipherHandle: add pub(crate) encrypt_raw/decrypt_raw/algorithm_id
  - 16 tests: roundtrip, tamper detection, progress, cleanup guarantees
@Adel-Ayoub Adel-Ayoub closed this Feb 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant