Releases: MicroClub-USTHB/M-Security
Releases · MicroClub-USTHB/M-Security
v0.3.5
Added
- Per-segment metadata:
vault_write()andvault_write_stream()accept optionalHashMap<String, String>metadata, encrypted within the index block.vault_read()returnsSegmentReadResult { data, metadata }. - Segment rename:
vault_rename_segment(old_name, new_name)updates the index without re-encryption. WAL-protected for crash safety.DuplicateSegmenterror variant added. - Index caching: in-memory dirty flag tracks index mutations. Read-only operations skip redundant index encryption/flush. New
vault_flush()API for explicit durability control. - Parallel reads:
vault_read_parallel(handle, names)decrypts multiple segments concurrently viarayon+ mmap zero-copy. Returns per-segmentSegmentResult { name, data, error }. - Dart
VaultServicewrappers:renameSegment(),flush(),readParallel(). Updatedwrite()/writeStream()to accept optionalmetadataparameter. Updatedread()to returnSegmentReadResult. - 15 Dart integration tests covering metadata (4), rename (4), flush (2), parallel read (3), and combined workflows (2).
- Rust test suite refactored from monolithic
tests.rsinto 13 focused modules. 407 total Rust tests. - Example app: metadata input field, rename dialog, flush button, parallel read all button.
Changed
VAULT_VERSIONbumped 1 → 2 for backward-compatible metadata deserialization (v1 vaults return empty metadata).ARCHIVE_VERSIONbumped 1 → 2 for metadata preservation in export/import (v1 archives import with empty metadata).vault_write_filenow passes metadata through tovault_write_stream(was hardcoded toNone).vault_close()flushes dirty index before releasing lock, with best-effort WAL checkpoint on error.
Security
- Metadata encrypted within the index block (AEAD with index key), not in the segment cipher — no plaintext leakage.
- OOM guards:
MAX_METADATA_PAIRS(1024) andMAX_METADATA_BYTES(64 KB) enforced on both read and write paths. - Parallel reads use immutable
&VaultHandle— no shared mutable state between threads. Compile-timeSyncassertion. - Checked offset arithmetic in parallel mmap slicing (
checked_addinstead of bare+). - Plaintext zeroized on all checksum failure paths in parallel reads.
Fixed
- Async error assertions in Dart rename tests changed from
expect()toawait expectLater(). - Example app
evfs_test.dartupdated forSegmentReadResultreturn type.
v0.3.4
Added
- Master key rotation via
vault_rotate_key()— re-encrypts all vault data under a new key using atomic copy-to-new-vault + rename strategy. Crash recovery: stale.rotatingfile cleaned onvault_open(). - Vault export via
vault_export()— produces a self-contained.mvexencrypted archive with BLAKE3 integrity trailer, ephemeral export key AEAD-wrapped with caller's wrapping key, and per-segment re-encryption. - Vault import via
vault_import()— reads.mvexarchive, creates new vault re-encrypted under a local master key. Validates header, unwraps export key, verifies per-segment BLAKE3 checksums and trailer integrity. ImportFailed,ExportFailed, andKeyRotationFailederror variants inCryptoError.- Dart
VaultService.rotateKey(),VaultService.export(), andVaultService.importVault()static methods. - 7 Dart integration tests for key management (rotation roundtrip, old key rejection, export-import roundtrip, wrong wrapping key, 1MB+ segment, multiple rotations, rotate-then-export-import).
- 26 Rust tests for key management (10 rotation + 7 export + 9 import).
- Example app Key Management section with Rotate Key, Export, and Import buttons.
- CI workflow pinned
flutter_rust_bridge_codegento v2.11.1 to match runtime dependency.
Security
- Old sub-keys zeroized immediately after rotation via
ZeroizeOnDrop. - Export wrapping uses AAD
b"msec-export-key-wrap"for domain separation. - Archive format authenticated: per-segment AAD (segment name) + BLAKE3 trailer covering all preceding bytes.
vault_writeplaintext wrapped inZeroizing<Vec<u8>>— guarantees zeroization on all exit paths includingencrypt_segmentfailure.- Import hardened:
u64tousizesafe cast viatry_from(32-bit overflow protection), OOM guard inu64arithmetic withsaturating_add,.lockfile cleanup in error paths, segment name validation (1-255 bytes),segment_countsanity bound (100K), unknown compression byte rejection. - Atomic rename before lock release in rotation (closes race window).
Fixed
unwrap()inarchive.rsreplaced withmap_err()for clippy compliance.from_byteserrors remapped toImportFailedat import call sites.- Example app lint: replaced
src/imports with publicm_security.dartre-exports.
v0.3.3
Added
- Zero-copy vault reads via
memmap2memory-mapped I/O —vault_readandvault_read_streamnow slice directly into mapped file pages instead of allocating heap buffers withread_exact. VaultMmapwrapper withmlock()on unix to pin ciphertext pages in RAM and prevent swap-to-disk. Graceful fallback to heap reads when mmap fails (32-bit targets, lowmlocklimits).- mmap invalidation/recreation after every vault mutation (write, delete, defrag, resize).
- ELF linker version script (
ffi-exports.map) restricting Android/Linux.sodynamic symbol table to FRB FFI symbols only — hides#[no_mangle]symbols leaked by dependencies. build.rsfor conditional version script application on Android/Linux cdylib builds.
Changed
- Switched all 50 FRB functions from SSE to CST+DCO codec via
full_dep: true—Vec<u8>returns now useallo-isolateExternalTypedData(pointer transfer, no memcpy) instead of SSE serialization. - Release profile hardened:
lto = "fat",codegen-units = 1,strip = "symbols",opt-level = 3. VaultHandlefield order:mmapbeforefilesomunlock/munmapruns while the fd is still open.
Security
- Symbol stripping removes internal Rust function names from release binaries —
nm -Dshows only FRB entry points and libc on ELF targets. mlock()prevents OS from swapping mmap'd ciphertext pages to disk swap.- Fewer intermediate
Vec<u8>copies means shorter plaintext residency in memory. - ZeroizeOnDrop behavior preserved — no regression from zero-copy refactoring.
v0.3.2
Added
vault_write_stream()for constant-memory chunked segment writes — encrypts data in 64 KB chunks without loading the full segment into RAM.vault_read_stream()for chunked segment reads viaStreamSink— delivers decrypted data as a stream of byte chunks.- Per-chunk AEAD encryption with domain-separated nonce derivation (
0x01prefix, chunk index, generation) — provably disjoint from monolithic nonce space. VaultChunkAadstruct binding generation and chunk position to each chunk's authentication tag (cross-segment splice defense).vault_write_file()FRB-callable wrapper that reads a file in 64 KB chunks and pipes intovault_write_stream.- Dart
VaultService.writeStream()— accepts aStream<Uint8List>, buffers to a temp file, and delegates to Rust for bounded-memory encryption. - Dart
VaultService.readStream()— returns aStream<Uint8List>of decrypted chunks with optionalonProgresscallback. - Streaming interop: segments written via streaming can be read one-shot (and vice versa).
- Integration tests for streaming: 10 MB roundtrip, write/read interop, progress reporting, error handling, and 50 MB memory-bounded validation.
- Example app streaming I/O section in the Vault tab — stream-write and stream-read with configurable size and live progress bar.
Fixed
- Checked arithmetic in
decrypt_streaming_chunksread path — prevents wrong-region reads from crafted chunk counts. - I/O errors in
vault_write_filenow surface asCryptoError::IoErrorinstead of a misleading "stream underflow" message. total_receivedaccumulation useschecked_addto prevent silent overflow on pathological input.- Per-chunk
fsyncreplaced with a single post-loop durability barrier — reduces streaming write I/O from O(N) fsyncs to O(1). - WAL checkpoint after streaming write commit — prevents unbounded WAL growth.
readStreamcancellation leak —onCancelhandler now cleans up data and progress subscriptions.- Overflow error message now reports exact byte count, chunk size, and offset for easier debugging.
v0.3.1
Added
- Vault defragmentation with crash-safe WAL operations and secure erase.
- Vault resize (grow/shrink) with safe data relocation.
- Vault health check with consistency invariant (
used + free_list + unallocated == total). - Dynamic index sizing that scales with capacity (64KB per MB, min 64KB, max 16MB).
- Dart
VaultServicewrappers fordefragment(),resize(), andhealth().
Changed
- Improved crash safety during persistence operations.
- Strengthened bounds checks and memory allocation limits.
- Internal bindings regenerated and validated.
Security
- No new information leaks,
index_sizeremains deterministic from file size. - Enforced index size bounds (64KB–16MB).
- Added safeguards against excessive memory usage.
- Header tampering results in authentication failure (no data exposure).
v0.3.0
Added
- Streaming encryption and decryption with chunk-based AES-256-GCM and ChaCha20-Poly1305, including progress callbacks for large file processing.
- Zstd and Brotli compression with configurable levels, integrated into both the streaming pipeline and the EVFS.
- Encrypted Virtual File System (EVFS): a
.vaultcontainer supporting named segments, WAL crash recovery, shadow index, capacity management, and secure deletion. - Full-featured Flutter example app demonstrating all library APIs (hashing, encryption, KDF, streaming, compression, vault).
Fixed
- Integration test reliability improvements for async race conditions and matcher corrections.
v0.1.1
v0.1.0
Initial release of M-Security, a native Rust cryptographic SDK for Flutter.
Added
- AES-256-GCM authenticated encryption with 32-byte keys, 12-byte auto-generated nonces, and 16-byte authentication tags.
- ChaCha20-Poly1305 authenticated encryption optimized for mobile processors lacking dedicated AES hardware.
- Unified
CipherHandleinterface for both ciphers (create, encrypt, decrypt, generate key). Output format:nonce || ciphertext || tag. - BLAKE3 hashing with one-shot and streaming APIs via
HasherHandle. - SHA-3-256 (Keccak) hashing with one-shot and streaming APIs.
- Argon2id password hashing with Mobile (64 MiB, t=3, p=4) and Desktop (256 MiB, t=4, p=8) presets, automatic salt generation, and PHC string output.
- HKDF-SHA256 key derivation (RFC 5869) with
derive,extract, andexpandoperations. Output range: 1-8160 bytes. - Secure memory management with
ZeroizeOnDropon all key-holding structs. - Opaque
#[frb(opaque)]handles ensuring raw keys never cross the FFI boundary. - Internal nonce generation via
OsRng; callers never handle nonces. - CI pipeline with Rust linting/testing, Dart analysis, and platform builds (Android, iOS, Linux).
- Integration tests for all cryptographic operations.
- Platform support: Android (ARM64, ARM32), iOS (ARM64, Simulator), macOS (ARM64, Intel), Linux (x86_64), Windows (x86_64).