- event_recorder.c: add SET DRAWBOXENABLE 0/1 BLE command (runtime toggle, INI-persistent); expose g_dwDrawBoxEnable extern - kdp2_host_stream.c: guard draw-box and seg-overlay rendering behind g_dwDrawBoxEnable so SET DRAWBOXENABLE 0 cleanly suppresses both - handshake.c: derive key from runtime VMF_NNM_Get_Kn_Number() instead of compile-time constant; each board gets a unique handshake key - kp_firmware.c: remove startup handshake key print (key is now per-board, fixed expected value is no longer meaningful) - move base64.h / sha256.h / handshake.h from src/host_stream/ to include/host_stream/ (proper include path for shared headers)
72 lines
2.5 KiB
C
72 lines
2.5 KiB
C
/*
|
|
* handshake.h — BLE Challenge-Response Authentication Protocol
|
|
*
|
|
* Protocol flow:
|
|
* 1. Device sends: {"response_type":"handshake_challenge","content":{"challenge":"<base64(R)>"}}
|
|
* 2. iPad computes: SHA256(R || Key) and replies with base64 of the digest
|
|
* 3. Device verifies and sends: {"response_type":"handshake_confirm","content":{"status":"success"|"failed"}}
|
|
*
|
|
* Key derivation: SHA256("29C310F5") → first 16 bytes XOR 0x5A
|
|
*/
|
|
#ifndef HANDSHAKE_H
|
|
#define HANDSHAKE_H
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
|
|
#define HANDSHAKE_KEY_LEN 16
|
|
#define HANDSHAKE_R_LEN 16
|
|
#define HANDSHAKE_TIMEOUT_SEC 5
|
|
|
|
typedef enum {
|
|
HS_STATE_IDLE = 0,
|
|
HS_STATE_WAIT_RESPONSE,
|
|
HS_STATE_SUCCESS,
|
|
HS_STATE_FAILED
|
|
} handshake_state_t;
|
|
|
|
typedef struct {
|
|
handshake_state_t state;
|
|
uint8_t key[HANDSHAKE_KEY_LEN];
|
|
uint8_t R[HANDSHAKE_R_LEN];
|
|
} handshake_ctx_t;
|
|
|
|
/* Derive the 16-byte handshake key: SHA256(HANDSHAKE_KN_STR)[0..15] XOR 0x5A */
|
|
void handshake_derive_key(uint8_t out_key[HANDSHAKE_KEY_LEN]);
|
|
|
|
/* Print key bytes to stdout as space-separated hex (e.g., "58 48 c8 ff ...") */
|
|
void handshake_print_key(const uint8_t key[HANDSHAKE_KEY_LEN]);
|
|
|
|
/* Initialise ctx: derive key, set state=IDLE, zero R */
|
|
void handshake_init(handshake_ctx_t *ctx);
|
|
|
|
/* Generate random R, set state=WAIT_RESPONSE, write JSON to out_json_buf.
|
|
* Returns 0 on success, -1 on error. */
|
|
int handshake_build_challenge(handshake_ctx_t *ctx,
|
|
char *out_json_buf, size_t buf_size);
|
|
|
|
/* Validate iPad response JSON (must contain "response" field with base64 value).
|
|
* Returns 1: success (state→SUCCESS)
|
|
* 0: wrong answer (state→FAILED)
|
|
* -1: malformed JSON
|
|
* -2: timeout */
|
|
int handshake_process_response(handshake_ctx_t *ctx, const char *json_str);
|
|
|
|
/* Build confirm JSON. success=1 → {"status":"success"}; success=0 → {"status":"failed","reason":"..."}
|
|
* reason_str may be NULL (defaults to "invalid_response").
|
|
* Returns 0. */
|
|
int handshake_build_confirm(handshake_ctx_t *ctx, int success,
|
|
const char *reason_str,
|
|
char *out_json_buf, size_t buf_size);
|
|
|
|
/* Reset state to IDLE, zero R (key is retained) */
|
|
void handshake_reset(handshake_ctx_t *ctx);
|
|
|
|
/* Return current state */
|
|
handshake_state_t handshake_get_state(const handshake_ctx_t *ctx);
|
|
|
|
/* Return 1 if WAIT_RESPONSE and timeout expired, else 0 */
|
|
int handshake_check_timeout(handshake_ctx_t *ctx);
|
|
|
|
#endif /* HANDSHAKE_H */
|