# MASTRPass Vault- und Exportformate

MASTRPass 0.4.0 lässt das bestehende Rust-Vault-Format `MASTRP01` unverändert
und ergänzt einen getrennten verschlüsselten Speicher für Zugangsdaten, Notizen,
Bildanhänge und die Entsperrrichtlinie. Ein Gesamtexport trägt das neue
Bundle-Magic `MASTRB02`. Alle importierten Längen, Anzahlen und Pfade werden vor
einer Allokation bzw. Dateierstellung begrenzt.

## Primärer Rust-Vault `MASTRP01`

Alle Ganzzahlen dieses Containers sind Little-Endian.

| Offset | Länge | Inhalt |
|---:|---:|---|
| 0 | 8 | Magic `MASTRP01` |
| 8 | 2 | Formatversion `1` |
| 10 | 2 | Flags |
| 12 | 12 | Argon2id: memory KiB, iterations, parallelism |
| 24 | 16 | zufällige Vault-ID |
| 40 | 16 | Argon2-Salt |
| 56 | 32 | HKDF-Mix-Salt |
| 88 | 24 | XChaCha20-Nonce für DEK-Wrapper |
| 112 | 48 | verschlüsselter 32-Byte-DEK plus AEAD-Tag |
| 160 | 24 | XChaCha20-Payload-Nonce |
| 184 | 8 | Payload-Ciphertext-Länge |
| 192 | variabel | authentifizierter, aufgefüllter Payload |

### Schlüsselableitung

1. Argon2id leitet 32 Byte aus dem UTF-8-Masterpasswort und einem zufälligen
   16-Byte-Salt ab (128 MiB, t=4, p=2).
2. Diese 32 Byte und der separat erzeugte 256-Bit-Recovery-Key werden mit
   Längenpräfixen verkettet.
3. HKDF-SHA-256 mit zufälligem Mix-Salt und festem Domain-Label erzeugt den KEK.
4. Der KEK öffnet den zufälligen DEK. Falsche Faktoren und Manipulation liefern
   nach aussen denselben generischen Fehlerpfad.

Headerfelder sind Associated Data des DEK-Wrappers; der vollständige
Wrapper-Header ist Associated Data des Payloads. Der entschlüsselte Payload
enthält ein Längenpräfix, JSON-Daten und zufälliges Padding bis zur nächsten
Grössenklasse (64 KiB, 256 KiB, 1 MiB, 4 MiB, 16 MiB oder 64 MiB).

Seed-Phrasen werden innerhalb des bereits verschlüsselten Payloads nochmals pro
Eintrag mit einem vom DEK und der Eintrags-ID abgeleiteten Schlüssel
verschlüsselt. Primäre Metadaten befinden sich ebenfalls nur im äusseren
Ciphertext.

## Verschlüsselter Zusatzspeicher `MPXENC01`

Der Zusatzspeicher liegt ausschliesslich im privaten App-Verzeichnis unter der
hexadezimalen Vault-ID. Er enthält `metadata.mpx`, optional
`content/<entry-id>.mpx` und optional `images/<entry-id>.mpx`. Zulässige IDs
bestehen exakt aus 32 kleingeschriebenen Hex-Zeichen; andere Pfade werden
abgelehnt.

Jede `.mpx`-Datei hat folgende Struktur:

| Offset | Länge | Inhalt |
|---:|---:|---|
| 0 | 8 | Magic `MPXENC01` |
| 8 | 12 | zufälliger AES-GCM-Nonce |
| 20 | variabel | AES-256-GCM-Ciphertext eines aufgefüllten Payloads plus 16-Byte-Tag |

Der GCM-Plaintext beginnt mit einer 4-Byte-Länge in Big-Endian-Reihenfolge,
gefolgt von Nutzdaten und kryptografisch zufälligem Padding. Metadaten verwenden
Grössenklassen von 64 KiB bis 4 MiB, Zugangsdaten/Notizen 4 KiB bis 256 KiB und
Bilder 256 KiB bis 8 MiB.

Aus dem zufälligen 32-Byte-DEK wird mit HMAC-SHA-256 und festen
Domain-Separation-Labels ein Zusatzspeicher-Root-Key abgeleitet. Für Metadaten,
jeden Zugangsdaten-/Notiz-Payload und jedes Bild wird daraus wiederum ein
eigener Purpose-Key erzeugt. Vault-ID und Purpose sind GCM Associated Data.
Damit scheitern Umbenennen, Vertauschen, Mischen mit einem anderen Vault und
jede Ciphertext-Manipulation bei der Authentifizierung.

`metadata.mpx` enthält nach der Entschlüsselung ein versioniertes JSON mit
Vault-ID, Entsperrrichtlinie und einer begrenzten Eintragsliste. Zugangsdaten und
sichere Notizen liegen getrennt in `content/`; Bilddateien enthalten die
unveränderten, vor dem Speichern geprüften PNG-, JPEG- oder WebP-Bytes. Alle
Dateien werden atomar geschrieben.

## Gesamtexport `MASTRB02`

Ganzzahlen im Bundle sind Big-Endian, entsprechend `DataOutputStream`.

| Reihenfolge | Länge | Inhalt |
|---:|---:|---|
| 1 | 8 | Magic `MASTRB02` |
| 2 | 4 | Länge des primären Vaults |
| 3 | variabel | vollständiger `MASTRP01`-Vault |
| 4 | 4 | Anzahl verschlüsselter Zusatzdateien |
| 5 | 2 | ASCII-Pfadlänge |
| 6 | variabel | erlaubter relativer ASCII-Pfad |
| 7 | 4 | Länge der verschlüsselten Datei |
| 8 | variabel | vollständige `MPXENC01`-Datei |

Die Schritte 5 bis 8 wiederholen sich für jede Zusatzdatei. Das Bundle besitzt
keine zusätzliche äussere Verschlüsselung: Der primäre Vault und jede
Zusatzdatei sind bereits unabhängig authentifiziert verschlüsselt; Vault-ID,
Purpose und Pfadbindung verhindern unbemerktes Mischen.

## Kompatibilität

0.4.0 importiert sowohl alte rohe `MASTRP01`-Dateien als auch vollständige
`MASTRB02`-Bundles. Neue Exporte verwenden `MASTRB02`. Der primäre Rust-Vault
bleibt binär kompatibel; eine Änderung an Header, Domain-Labels,
Serialisierung oder KDF-Semantik erfordert weiterhin eine neue Formatversion und
eine explizite, getestete Migration. Unbekannte Formate werden nie „best effort“
geöffnet.
