From 8b0e632526d9504c5c0e09bab72ab83db1c46f9b Mon Sep 17 00:00:00 2001 From: cirakg Date: Sun, 18 Oct 2026 20:28:09 +0200 Subject: docs: record final decisions, test watch and SDK login details - README: Forerunner 70 is the test watch, the phone is Android, Docker access is settled; how `make sdk` logs in and why the browser login can't be used; the new `make products` and `make lock` targets. - FEASIBILITY: final decisions D1-D5. - Space out table separator rows and turn bold-only lines into headings so markdownlint passes. Co-Authored-By: Claude Opus 5.5 --- docs/FEASIBILITY.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'docs') diff --git a/docs/FEASIBILITY.md b/docs/FEASIBILITY.md index e150a48..255f195 100644 --- a/docs/FEASIBILITY.md +++ b/docs/FEASIBILITY.md @@ -9,7 +9,7 @@ Verdicts: **Supported**, **Partially** (works with a workaround or a limit), **N ## Summary | # | Question | Verdict | Consequence | -|---|---|---|---| +| --- | --- | --- | --- | | 1 | Unlock entries with the Garmin device PIN | Not possible | App-level PIN instead (decision D1) | | 2 | SHA-1/256/512, HMAC, PBKDF2, AES on the watch | Partially | Native: SHA-1, SHA-256, AES-ECB/CBC, HMAC-SHA256, ECDH, random bytes. SHA-512 and PBKDF2 are built from their standards in Monkey C | | 3 | Import and manual entry through app settings | Partially | Text fields only, no file upload. Settings only work for apps installed from the Connect IQ Store (a private beta counts). Dynamic lists are broken today | @@ -32,7 +32,7 @@ Verdicts: **Supported**, **Partially** (works with a workaround or a limit), **N Alternatives (decision **D1**): | Option | How it works | Trade-off | -|---|---|---| +| --- | --- | --- | | **A. App PIN, session unlock** (recommended) | 4 to 10 digit PIN (6 or more advised), entered with an on-screen keypad (touch) or up/down/start (buttons). PBKDF2 turns it into a key that unwraps the key for locked entries. Everything stays unlocked until you leave the app, or until an inactivity timeout (default 60 s). | One PIN entry per session. | | **B. PIN every time** | Same derivation, but the key is discarded as soon as you leave a locked entry. | Safer if the watch is grabbed mid-session. You wait for the key derivation (about 1 s, to measure) every time. | | **C. Per-entry choice of A or B** | Each entry's lock setting picks "session" or "every time". | Most flexible. More UI states to build and test. | @@ -50,7 +50,7 @@ Wrong attempts, for every option: `Toybox.Cryptography` exists since API 3.0.0 and needs no manifest permission. Every candidate watch in section 5 appears in the Hash, Cipher and HMAC device lists (the original vívoactive 3 is missing from Cipher and HMAC). | Primitive | Native? | Notes | -|---|---|---| +| --- | --- | --- | | SHA-1, SHA-256, MD5 | Yes | `Hash` class, streaming | | SHA-512 | **No** | | | HMAC | SHA-256 only | Docs: "HASH_SHA256 is the only supported algorithm in Connect IQ 3.x" | @@ -94,7 +94,7 @@ Garmin documents growable lists that the app reads as an array of dictionaries. Verdict: not usable. Alternatives (decision **D3**): | Option | How it works | Trade-off | -|---|---|---| +| --- | --- | --- | | **S1. Fixed slots** (recommended) | N slot groups per kind (for example 10 OTP and 10 code slots, a build-time constant). Each slot has every field from requirement 11, plus "enabled" and "order". Edit in place, reorder with "order", delete by switching off or clearing. Secret fields are write-only: blank means "keep the stored secret". | Hard cap on hand-entered entries. The phone shows groups named "OTP slot 1" and so on, because group titles can't be dynamic. Imported entries aren't shown in slots; you delete, reorder and lock them on the watch. Works even if write-back (3e) doesn't. | | **S2. Inbox plus manage form** | One "new OTP" and one "new code" form that the watch reads and then clears. A "manage" form takes an entry ID (shown on the watch) and an action: edit fields, delete, move to position, lock. | No cap on entries and a small settings payload. You need the entry ID from the watch. The watch must ignore forms it has already applied. | | **S3. One entry per line** | One text field with one line per entry (`otpauth://...` lines and a similar `code://...` format), parsed and validated on the watch with an error per line. | Compact, for power users. Limited by field length (about 800 characters, see 3d) and the `&` problem on iOS. Secrets stay in the field unless write-back works. | @@ -126,7 +126,7 @@ The watch can change its own settings values with `Properties.setValue` (saved w Memory in KB from Garmin's device reference pages, API level from the compatible-devices table: | Device | API | Screen | Touch | Watch app | Glance | -|---|---|---|---|---|---| +| --- | --- | --- | --- | --- | --- | | Forerunner 255S | 5.2 | 218×218 round, MIP 64 colours | no | 512 | 64 | | Forerunner 255 | 5.2 | 260×260 round, MIP | no | 512 | 64 | | fēnix 7 / 7S / 7X | 5.2 | 240 to 280 round, MIP | yes | 768 | 64 | @@ -225,7 +225,7 @@ Docker 29.9.1 with buildx is installed and running. Your user isn't in the `dock ## 13. Import pipeline candidates (decision D2) | Candidate | Pros | Cons | -|---|---|---| +| --- | --- | --- | | **A. Paste `otpauth://` lines into settings.** The watch parses them and clears the field. | No tools needed. | Secrets pass through the phone and Garmin in the clear. iOS may reject the `&` in every URI. Only a handful of entries fit per field. Needs the Store beta. | | **B. Offline converter to an encrypted blob** (recommended). The converter runs in Docker with no network and turns an Aegis export (plain or encrypted), `otpauth://` lists or Google migration exports into an encrypted blob. You paste the blob into settings and type a 12-digit transfer code on the watch once. | Only ciphertext reaches Garmin. Validation and warnings (for example, a code too big for your screen) happen before anything reaches the watch. Compact, about 70 characters per entry. The blob is encrypted, so any channel can carry it to your phone; the converter can also show it as QR codes for your phone's camera. | Needs a computer. Needs the Store beta. The transfer code is worth about 40 bits times the key-derivation cost: fine against bulk exposure, not against a determined attacker who also gets hold of the blob. | | **B′. Like B, with ECDH pairing instead of a transfer code** | No code to type, and full 128-bit security. | A one-time pairing step: you copy the watch's public key from the phone settings into the converter. Connect IQ's little-endian key format needs interoperability testing on a real watch. | @@ -251,9 +251,10 @@ Answered on 2026-10-18: - **D3 Manual-entry layout: S2, inbox plus manage form.** - **D4 Targets: API 5.0+ watches** with at least 512 KB for apps. No low-memory build. -Still open: +Also answered: your test watch is a Forerunner 70 (2026; API 6.0, 390×390 AMOLED, touch and buttons, 768 KB), and your phone is Android, so the iPhone problem with `&` and `\` in 3d doesn't affect you. You chose option 1 for D5 below. + +The options as they were presented: -- Which watch you'll test on, and whether your phone is Android or iPhone (the `&` and `\` problem in 3d affects iPhone only). - **D5 Docker access** (needs sudo, which you run): - Option 1: `sudo usermod -aG docker cirakg`, then log out and back in. Membership in the `docker` group is equivalent to root on this machine. - Option 2: rootless Docker, which needs the AUR package `docker-rootless-extras`. -- cgit v1.2.3