8000 cbio: classify the live GS1 FF31 reply as unresolved by shroominic · Pull Request #132 · shroominic/OpenGlucose · GitHub
[go: up one dir, main page]

Skip to content

cbio: classify the live GS1 FF31 reply as unresolved - #132

Closed
shroominic wants to merge 2 commits into
feature/cbio-gs1-livefrom
feature/cbio-gs1-frame-decode
Closed

shroominic wants to merge 2 commits into
feature/cbio-gs1-livefrom
feature/cbio-gs1-frame-decode

Conversation

@shroominic
Copy link
Copy Markdown
Owner

Refs #131. Stacked on feature/cbio-gs1-live (PR #127); base is that branch, not
main.

What this adds

A read-only inspection of one raw FF31 notification, plus the tests and the
evidence record for the five-byte reply the live GS1 driver receives.

  • packages/cgm_cbio/lib/src/cbio_reply_inspection.dart reports the plaintext
    invariants (declared length, additive checksum, acknowledgement marker, mapped
    opcode), whether any rotation or the reversed payload satisfies the contract,
    and whether one constant XOR or additive mask would expose a frame.
  • packages/cgm_cbio/test/cbio_reply_inspection_test.dart pins the captured
    payload, the synthetic round-trips that prove each search has power, and the
    truncation and orientation cases.
  • docs/testing/cbio-gs1-reply-decode.md records the bytes, the failed
    hypotheses with their evidence, and the missing evidence needed to continue.

Proven

  • The reply is a deterministic response to the single bounded read
    06 08 01 00 00 00 F1, not a broadcast: 9 ms and 18 ms after write
    completion in two sessions, with nothing during 12 s and 20 s passive windows.
  • It is byte-identical across every recorded session: 23 F7 6F D9 F4.
  • It is not a complete plaintext frame: byte zero declares 36 bytes rather than
    5, the sum is 0x56 rather than 0, byte one is the unmapped 0xF7, and no
    rotation, reversal, or constant byte mask exposes a valid frame.
  • The inspection returns unresolved with a null frame for these bytes, so an
    unresolved payload cannot be mistaken for a decode.

Not proven

  • What the bytes mean, and whether the sensor treats the read as
    authenticated, authorized, or malformed.
  • That the sensor expects a fragmented remainder or another command first.
  • Any glucose value, unit, epoch, or sensor state. No glucose claim is made.

The surviving explanation is a keyed stream-cipher mask: on this sensor model,
earlier plaintext F0/0A queries also returned five-byte notifications that
only became length-valid and sum-to-zero after the native RC4 transform with the
vendor's registered 16-byte key. That key is BSS-registered from an app token,
and neither the token, the key, nor the vendor artifacts are present in this
repository or on this host. A constant-mask search cannot substitute for it, so
no decode was fabricated.

Verification

  • dart format --output=none --set-exit-if-changed lib test - passed
  • dart analyze --fatal-infos - no issues
  • dart test - 36 tests passed, including 11 new inspection tests
  • Live confirmation capture on branch feature/cbio-gs1-live tip: one write,
    one 5-byte FF31 notification, harness All tests passed!

This PR stays open; it is not merged here.

The single bounded 08 read on the live SIBIONICS/CBio GS1 sensor returns one
five-byte FF31 notification, byte-identical across every recorded session.
Add a read-only structural inspection that reports which plaintext hypotheses
those bytes survive, with tests for the exact contract, orientation, constant
mask, and truncation searches.

The captured payload is not a complete plaintext frame: byte zero declares 36
bytes rather than 5, the additive sum is 0x56 rather than 0, byte one is not a
mapped opcode, and no rotation, reversal, or constant mask exposes a valid
frame. No decode is produced and none is claimed.
The vendor storage, time, and glucose read queries all return the same five
bytes, so the reply is not a per-command answer and the in-flight fragment
reading is refuted for this path.
shroominic added a commit that referenced this pull request Sep 18, 2026
Absorbs feature/cbio-gs1-app-live at 05785b0, which carries the redacted
credential API (#166 verbatim as a7c21bc) and the live lane's adoption of an
injected CbioCredentialSource (PR #192, issue #191).

Conflict resolution:
- packages/cgm_cbio/README.md: union. The aggregate's FF31 reply-decode
  paragraph (#132) and the lane's new injected-material section are both kept;
  neither lineage had the other.
- packages/cgm_cbio/test/cbio_crypto_test.dart: take the lane's version. It
  supersedes the masked-vector fixture from #148 by removing the published
  vectors entirely and testing the mask with synthetic material.
@shroominic
Copy link
Copy Markdown
Owner Author

Carried by the GS1 consolidation in PR #209 (branch feature/cbio-gs1, head 3eca4f4).

This PR is contained in the consolidated line; the merge that carries it is c85f827.

Closing as subsumed by the consolidation - not as won't fix. The per-defect evidence stays in this thread, and the carrying commit above is where the change now lives.

@shroominic shroominic closed this Sep 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

0