Skip to content

Commit 9036957

Browse files
committed
docs: cite the documented all-zero key B instead of inferring it
The previous round stated the key B premise as an inference and closed the paragraph with "No key B is published, derived, or claimed anywhere in the guide." That sentence is false. BambuLabRfid.md line 70 documents the sector trailer as | 10 (BB) | 6 | RAW Bin | B-Key (always `00 00 00 00 00 00` for Bambu tags) | and the guide's examples/exampleDump.bin carries six zero bytes at offset 10 of all 16 trailers. This strengthens the change rather than weakening it: the derived key A is a non-zero HKDF output, so it is definitively not the tag's key B, and the 80 -> 16 arithmetic is established rather than conditional. Lead the code comment with the two reasons that do not depend on what upstream happens to publish: the tag's key B is all zeros so no derived key can match it, and key A alone reads every block this plugin parses so any key B entry is waste regardless. The old wording led with the absence of a published key B derivation, which a reader who later finds BambuLabRfid.md could take as refuted and use to justify restoring the key B assignment. Drop the CHANGELOG's "were a tag's key B in fact equal to its key A" hedge for the same reason. "Publishes that derivation alone" is narrower and stays. No behaviour change: .text 3,364, .rodata 7,596, .fal 21,548 and the 18-symbol import list are identical before and after.
1 parent f72404b commit 9036957

2 files changed

Lines changed: 13 additions & 13 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4646
[RFID-Tag-Guide](https://github.com/Bambu-Research-Group/RFID-Tag-Guide)
4747
publishes that derivation alone, describing what it recovers as "all required
4848
A-Keys" — and key A on its own reads every block this plugin parses, so the
49-
key B entries could not unlock anything key A could not. Taking the upstream
50-
evidence at face value, the tag's real key B differs from the derived key A,
51-
each of those 16 offers failed, and because a failed authentication halts the
52-
tag the poller retried each one once per block in the sector: 64 failed
53-
authentications and 64 card re-selections per scan, so the read path drops
54-
from 80 authentications to 16. Were a tag's key B in fact equal to its key A,
55-
the drop would instead be 32 to 16 with no failures involved. The read is
56-
strictly cheaper either way and the parsed result is unchanged.
57-
([#3](https://github.com/uzyn/flipper-bambu/issues/3))
49+
key B entries could not unlock anything key A could not. That guide's
50+
`BambuLabRfid.md` also documents the trailer's key B as "always
51+
`00 00 00 00 00 00` for Bambu tags", which the non-zero derived key never
52+
matches, so each of those 16 offers failed; and because a failed
53+
authentication halts the tag, the poller retried each one once per block in
54+
the sector: 64 failed authentications and 64 card re-selections per scan, so
55+
the read path drops from 80 authentications to 16. The parsed result is
56+
unchanged. ([#3](https://github.com/uzyn/flipper-bambu/issues/3))
5857

5958
## [1.1.0] - 2026-05-13
6059

‎plugin/bambu.c‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,10 +267,11 @@ static void bambu_derive_keys_from_uid(const uint8_t* uid, size_t uid_len, MfCla
267267
generated += chunk_len;
268268
}
269269

270-
// Key A only — do not restore the key B assignment. The HKDF context is
271-
// "RFID-A" and upstream publishes no key B derivation, and the trailers'
272-
// 87 87 87 access bits leave every block this plugin parses readable with
273-
// key A, so key B entries buy nothing and cost an auth attempt per block.
270+
// Key A only — do not restore the key B assignment. Bambu tags carry an
271+
// all-zero key B (RFID-Tag-Guide, BambuLabRfid.md), so no derived key can
272+
// match it; and the trailers' 87 87 87 access bits leave every block this
273+
// plugin parses readable with key A, so any key B entry — derived, guessed
274+
// or known — buys nothing and costs an auth attempt per block.
274275
for(size_t sector = 0; sector < sector_count; sector++) {
275276
const uint8_t* sector_key = &key_material[sector * key_size];
276277
memcpy(keys->key_a[sector].data, sector_key, key_size);

0 commit comments

Comments
 (0)