From bc228753bfb4a2faea540cddb20fc39ebd265db5 Mon Sep 17 00:00:00 2001 From: cirakg Date: Tue, 20 Oct 2026 01:51:05 +0200 Subject: feat(storage): add keyed secret fingerprints to record headers An 8-byte HMAC of kind, type and secret (key derived from the device key) in header tag 13 lets imports find duplicates of locked entries while the watch is locked. Vault gains anyHeader() and storage(). Co-Authored-By: Claude Opus 5.5 --- source/storage/Record.mc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source/storage/Record.mc') diff --git a/source/storage/Record.mc b/source/storage/Record.mc index 01c3c53..b26a4ba 100644 --- a/source/storage/Record.mc +++ b/source/storage/Record.mc @@ -6,7 +6,7 @@ // v (1 byte, = 1) | kr (1 byte) | hlen (2 bytes, big-endian) | header (hlen bytes) | box // // kr = 0: sealed with the device key, 1: sealed with the locked master key -// header = Codec TLV of the header fields (tags 1-12), readable without a key +// header = Codec TLV of the header fields (tags 1-13), readable without a key // box = SealedBox of the Codec TLV of the sensitive fields (tags 20-28) // aad = UTF-8 id || v || kr || hlen || header // @@ -47,6 +47,7 @@ module Record { const H_COUNTER = 10; const H_CREATED = 11; const H_NAMES_ENCRYPTED = 12; + const H_FINGERPRINT = 13; // Sensitive tags (inside the box). const S_ALGORITHM = 20; @@ -107,6 +108,7 @@ module Record { entry.counter = f.long(H_COUNTER); entry.created = f.long(H_CREATED); entry.namesEncrypted = f.flag(H_NAMES_ENCRYPTED); + entry.fingerprint = f.bytes(H_FINGERPRINT); if (!f.ok || !Entry.isValidId(entry.id) || entry.counter < 0) { return null; } @@ -170,6 +172,10 @@ module Record { w.addInt(H_COUNTER, entry.counter); w.addInt(H_CREATED, entry.created); w.addBool(H_NAMES_ENCRYPTED, entry.namesEncrypted); + var fingerprint = entry.fingerprint; + if (fingerprint != null) { + w.addBytes(H_FINGERPRINT, fingerprint); + } return w.bytes; } -- cgit v1.2.3