SDK สำหรับ TESAIoT Dev Kit
คู่มืออ้างอิง API และ Tutorial (MTB & µPython)
Loading...
Searching...
No Matches
bento_devmode.h
Go to the documentation of this file.
1/*******************************************************************************
2 * File Name: bento_devmode.h
3 *
4 * Description: Developer-mode unlock state for the Bento Desktop Buddy bridge.
5 * Gates bento.exec and other privileged verbs behind an
6 * HMAC-SHA256 challenge/response. See SPEC §5.5 + §7.3.
7 *
8 * Lifecycle:
9 * 1. Desktop sends bento.devmode.nonce → firmware returns a
10 * fresh 16-byte nonce (64-ms TTL per SPEC).
11 * 2. Desktop computes HMAC-SHA256(shared_secret, nonce) and
12 * sends bento.devmode.unlock.
13 * 3. Firmware verifies and sets the unlocked flag.
14 * 4. bento.devmode.lock clears the flag.
15 *
16 * Shared secret storage:
17 * Primary — OPTIGA Trust M arbitrary-data slot 0xE120
18 * Fallback — RAM-only, regenerated every boot (means desktop
19 * must re-provision after every reflash; see
20 * ISSUES.md ISSUE-006).
21 * v1 uses the RAM-only fallback unconditionally; OPTIGA
22 * persistence lands in a follow-up along with the proper
23 * first-pair provisioning UX (SPEC §7.3 steps 1-4).
24 *
25 ******************************************************************************/
26
27#ifndef BENTO_DEVMODE_H
28#define BENTO_DEVMODE_H
29
30#include <stdbool.h>
31#include <stddef.h>
32#include <stdint.h>
33
34#ifdef __cplusplus
35extern "C" {
36#endif
37
38#define BENTO_DEVMODE_NONCE_LEN (16u)
39#define BENTO_DEVMODE_SECRET_LEN (32u)
40#define BENTO_DEVMODE_HMAC_LEN (32u) /* SHA-256 output */
41#define BENTO_DEVMODE_NONCE_TTL_MS (60000u)
42
43/* Initialise the secret (RAM-only fallback — seeds from boot entropy +
44 * TickCount on first call). Idempotent. */
46
47/* Generate a fresh 16-byte nonce and return it via `nonce_out`. Overwrites
48 * any previous pending nonce (only one in-flight challenge). Sets the
49 * internal ttl clock. */
51
52/* Verify an HMAC-SHA256 hex string against the current pending nonce + the
53 * shared secret. Returns true on match AND ttl window unexpired, in which
54 * case the internal unlocked flag is set. Consumes the nonce on any call
55 * (one-shot, prevents replay). */
56bool bento_devmode_unlock(const char *hmac_hex, size_t hmac_hex_len);
57
58/* Manually clear the unlocked flag. */
60
61/* Query whether exec is currently permitted. */
63
64/* Expose the provisioning secret as a hex string for the first-pair
65 * emit-once flow (SPEC §7.3 step 2). Returns length written (64 hex chars
66 * + NUL) or 0 if the out buffer is too small. RAM-only fallback; the
67 * caller must NOT log this to UART. */
68size_t bento_devmode_secret_hex(char *out, size_t out_sz);
69
70/* Emit `{"evt":"bento.devmode.provision","secret":"<64 hex>"}` over BLE
71 * NUS once per boot so the desktop side can store the secret in its
72 * keychain. Without this emit the desktop holds a randomly-generated
73 * placeholder secret that will never match firmware-side state and
74 * every `bento.devmode.unlock` will return `not_permitted`. Wired into
75 * ble_nus_lazy.c's CONNECTED transition, paired with
76 * `bento_fw_emit_boot_complete()`. Internally guards with a static
77 * "already sent this boot" flag — multiple BLE connect/disconnect
78 * cycles within one boot will not re-send (the secret in firmware
79 * doesn't change without a reset). */
81
82/* First 4 bytes of SHA-256(secret) as 8 hex chars + NUL — safe to log,
83 * used to cross-check that desktop and firmware are operating on the
84 * same secret without leaking it. Matches the `secret_fp` tracing on
85 * the Rust side (`verbs/devmode.rs::unlock`). */
86size_t bento_devmode_secret_fp_hex(char *out, size_t out_sz);
87
88#ifdef __cplusplus
89}
90#endif
91
92#endif /* BENTO_DEVMODE_H */
#define BENTO_DEVMODE_NONCE_LEN
Definition bento_devmode.h:38
void bento_devmode_lock(void)
ล้าง flag ปลดล็อก
bool bento_devmode_is_unlocked(void)
บอกว่า verb ที่มีสิทธิ์พิเศษ (bento.exec) ได้รับอนุญาตอยู่ในขณะนั้นหรือไม่
void bento_devmode_nonce_issue(uint8_t nonce_out[BENTO_DEVMODE_NONCE_LEN])
เติม nonce ใหม่ขนาด 16 ไบต์ ทับตัวที่ค้างอยู่ทิ้ง และเริ่มนับนาฬิกา TTL
size_t bento_devmode_secret_hex(char *out, size_t out_sz)
secret ในรูป hex 64 อักขระ + NUL หรือคืน 0 เมื่อบัฟเฟอร์เล็กเกินไป ห้ามพิมพ์ค่านี้ลง UART
bool bento_devmode_unlock(const char *hmac_hex, size_t hmac_hex_len)
ตรวจสอบ HMAC เทียบกับ nonce ที่ค้างอยู่ และทำให้ nonce ใช้ไม่ได้อีกทุกครั้งที่ถูกเรียก (ใช้ได้ครั้งเด...
size_t bento_devmode_secret_fp_hex(char *out, size_t out_sz)
4 ไบต์แรกของ SHA-256(secret) ในรูป hex 8 อักขระ + NUL — พิมพ์ออกได้อย่างปลอดภัย
void bento_devmode_emit_provision(void)
ส่ง event provision หนึ่งครั้งต่อการบูตหนึ่งรอบ ตอนเปลี่ยนสถานะเป็น CONNECTED การส่งที่ล้มเหลวจะลองให...
void bento_devmode_init(void)
เป็น idempotent สร้าง secret ขนาด 32 ไบต์ใน RAM จุดเข้าสาธารณะของ devmode ทุกจุดเรียกฟังก์ชันนี้เอง