fix(crypto): K-02 — format v3 chunk replay protection with generation aad

This commit is contained in:
2026-09-19 00:52:13 +02:00
parent ad531d8393
commit 36a4094336
9 changed files with 553 additions and 99 deletions
+15 -3
View File
@@ -171,8 +171,12 @@ impl SanctumFile {
.unwrap_or(0);
if let Some((idx, ref data, true)) = self.cached_chunk {
let gen = self
.db
.next_chunk_generation(self.node_id, idx)
.unwrap_or(0);
let (ciphertext, nonce, tag) =
encrypt_chunk(&self.dek, self.node_id, idx, data, self.format_version).map_err(
encrypt_chunk(&self.dek, self.node_id, idx, data, self.format_version, gen).map_err(
|e| {
error!("Verschlüsselungsfehler beim Chunk-Flush: {e}");
FsError::GeneralFailure
@@ -182,6 +186,7 @@ impl SanctumFile {
if let Err(e) = self.db.write_chunk_and_update_size(
self.node_id,
idx,
gen,
&nonce,
&tag,
&ciphertext,
@@ -246,6 +251,7 @@ impl SanctumFile {
&record.nonce,
&record.tag,
self.format_version,
record.generation,
)
.map_err(|e| {
error!("AEAD-Entschlüsselungsfehler bei Chunk #{chunk_index}: {e}");
@@ -490,7 +496,7 @@ impl SanctumFs {
let dek_arc = Arc::new(dek);
let carrier_dek_arc = carrier_dek.map(Arc::new);
db.set_active_dek((*dek_arc).clone());
let db = db.with_session(vault_id, (*dek_arc).clone());
// Im Decoy-Vault (Slot 0): Stelle sicher, dass carrier_node_id stets bekannt ist,
// um die Trägerdatei vor versehentlichem Löschen oder Überschreiben zu schützen.
@@ -1018,20 +1024,26 @@ impl DavFileSystem for SanctumFs {
&record.nonce,
&record.tag,
self.format_version,
record.generation,
)
.map_err(|_| FsError::GeneralFailure)?;
let gen = self
.db
.next_chunk_generation(dest_node.id, idx)
.map_err(|_| FsError::GeneralFailure)?;
let (new_ct, new_nonce, new_tag) = encrypt_chunk(
&self.dek,
dest_node.id,
idx,
&plaintext,
self.format_version,
gen,
)
.map_err(|_| FsError::GeneralFailure)?;
self.db
.write_chunk(dest_node.id, idx, &new_nonce, &new_tag, &new_ct)
.write_chunk(dest_node.id, idx, gen, &new_nonce, &new_tag, &new_ct)
.map_err(|_| FsError::GeneralFailure)?;
}
}