hap.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #pragma once
  2. #include <stdint.h>
  3. #include <stddef.h>
  4. #include <stdbool.h>
  5. #include "esp_err.h"
  6. /**
  7. * HAP (HomeKit Accessory Protocol) implementation for AirPlay 2
  8. * Handles pair-verify for transient pairing
  9. */
  10. // Key sizes
  11. #define HAP_ED25519_PUBLIC_KEY_SIZE 32
  12. #define HAP_ED25519_SECRET_KEY_SIZE 64
  13. #define HAP_X25519_KEY_SIZE 32
  14. #define HAP_CHACHA20_KEY_SIZE 32
  15. #define HAP_CHACHA20_NONCE_SIZE 12
  16. #define HAP_POLY1305_TAG_SIZE 16
  17. // Forward declaration
  18. struct srp_session;
  19. // Session state
  20. typedef struct {
  21. // Device long-term Ed25519 keypair
  22. uint8_t device_public_key[HAP_ED25519_PUBLIC_KEY_SIZE];
  23. uint8_t device_secret_key[HAP_ED25519_SECRET_KEY_SIZE];
  24. // Ephemeral X25519 keypair for this session
  25. uint8_t session_public_key[HAP_X25519_KEY_SIZE];
  26. uint8_t session_secret_key[HAP_X25519_KEY_SIZE];
  27. // Client's ephemeral public key
  28. uint8_t client_public_key[HAP_X25519_KEY_SIZE];
  29. // Shared secret from X25519
  30. uint8_t shared_secret[HAP_X25519_KEY_SIZE];
  31. // Derived session keys
  32. uint8_t encrypt_key[HAP_CHACHA20_KEY_SIZE];
  33. uint8_t decrypt_key[HAP_CHACHA20_KEY_SIZE];
  34. // Encryption nonces (counters)
  35. uint64_t encrypt_nonce;
  36. uint64_t decrypt_nonce;
  37. // Session state
  38. int pair_verify_state;
  39. int pair_setup_state;
  40. bool pair_setup_transient;
  41. bool session_established;
  42. // SRP session for pair-setup
  43. struct srp_session *srp;
  44. } hap_session_t;
  45. /**
  46. * Initialize HAP module
  47. * Generates or loads device Ed25519 keypair from NVS
  48. */
  49. esp_err_t hap_init(void);
  50. /**
  51. * Get device's Ed25519 public key (for mDNS pk field)
  52. */
  53. const uint8_t *hap_get_public_key(void);
  54. /**
  55. * Create a new HAP session for a client connection
  56. */
  57. hap_session_t *hap_session_create(void);
  58. /**
  59. * Free a HAP session
  60. */
  61. void hap_session_free(hap_session_t *session);
  62. /**
  63. * Handle pair-verify M1 message from client
  64. * @param session HAP session
  65. * @param input Input TLV data from client
  66. * @param input_len Length of input
  67. * @param output Output buffer for M2 response
  68. * @param output_capacity Capacity of output buffer
  69. * @param output_len Actual length of output
  70. * @return ESP_OK on success
  71. */
  72. esp_err_t hap_pair_verify_m1(hap_session_t *session, const uint8_t *input,
  73. size_t input_len, uint8_t *output,
  74. size_t output_capacity, size_t *output_len);
  75. /**
  76. * Handle pair-verify M3 message from client
  77. * @param session HAP session
  78. * @param input Input TLV data from client
  79. * @param input_len Length of input
  80. * @param output Output buffer for M4 response
  81. * @param output_capacity Capacity of output buffer
  82. * @param output_len Actual length of output
  83. * @return ESP_OK on success, session keys are derived
  84. */
  85. esp_err_t hap_pair_verify_m3(hap_session_t *session, const uint8_t *input,
  86. size_t input_len, uint8_t *output,
  87. size_t output_capacity, size_t *output_len);
  88. /**
  89. * Handle AirPlay 2 raw (non-TLV) pair-verify M1
  90. * Used when iOS sends raw 68-byte format instead of TLV
  91. */
  92. esp_err_t hap_pair_verify_m1_raw(hap_session_t *session, const uint8_t *input,
  93. size_t input_len, uint8_t *output,
  94. size_t output_capacity, size_t *output_len);
  95. /**
  96. * Handle AirPlay 2 raw (non-TLV) pair-verify M3
  97. */
  98. esp_err_t hap_pair_verify_m3_raw(hap_session_t *session, const uint8_t *input,
  99. size_t input_len, uint8_t *output,
  100. size_t output_capacity, size_t *output_len);
  101. /**
  102. * Encrypt data using session keys
  103. * @param session HAP session (must be established)
  104. * @param plaintext Input data
  105. * @param plaintext_len Length of input
  106. * @param ciphertext Output buffer (must have room for plaintext_len + 16 tag)
  107. * @param ciphertext_len Actual output length
  108. * @return ESP_OK on success
  109. */
  110. esp_err_t hap_encrypt(hap_session_t *session, const uint8_t *plaintext,
  111. size_t plaintext_len, uint8_t *ciphertext,
  112. size_t *ciphertext_len);
  113. /**
  114. * Decrypt data using session keys
  115. * @param session HAP session (must be established)
  116. * @param ciphertext Input data (includes 16 byte tag)
  117. * @param ciphertext_len Length of input
  118. * @param plaintext Output buffer
  119. * @param plaintext_len Actual output length
  120. * @return ESP_OK on success, ESP_ERR_INVALID_STATE if auth fails
  121. */
  122. esp_err_t hap_decrypt(hap_session_t *session, const uint8_t *ciphertext,
  123. size_t ciphertext_len, uint8_t *plaintext,
  124. size_t *plaintext_len);
  125. /**
  126. * Derive audio encryption key from pair-verify shared secret
  127. * Uses HKDF-SHA512 with AirPlay 2 audio-specific parameters
  128. * @param session HAP session (must be established)
  129. * @param audio_key Output buffer for audio key
  130. * @param key_len Length of audio key to generate (typically 16 or 32 bytes)
  131. * @return ESP_OK on success
  132. */
  133. esp_err_t hap_derive_audio_key(hap_session_t *session, uint8_t *audio_key,
  134. size_t key_len);
  135. /**
  136. * Handle pair-setup M1 (client initiates SRP)
  137. * @param session HAP session
  138. * @param input Input TLV (method, state, flags)
  139. * @param input_len Length of input
  140. * @param output Output buffer for M2 (salt, public key)
  141. * @param output_capacity Capacity of output buffer
  142. * @param output_len Actual output length
  143. * @return ESP_OK on success
  144. */
  145. esp_err_t hap_pair_setup_m1(hap_session_t *session, const uint8_t *input,
  146. size_t input_len, uint8_t *output,
  147. size_t output_capacity, size_t *output_len);
  148. /**
  149. * Handle pair-setup M3 (client sends A and proof)
  150. * @param session HAP session
  151. * @param input Input TLV (public key, proof)
  152. * @param input_len Length of input
  153. * @param output Output buffer for M4 (server proof)
  154. * @param output_capacity Capacity of output buffer
  155. * @param output_len Actual output length
  156. * @return ESP_OK on success
  157. */
  158. esp_err_t hap_pair_setup_m3(hap_session_t *session, const uint8_t *input,
  159. size_t input_len, uint8_t *output,
  160. size_t output_capacity, size_t *output_len);
  161. /**
  162. * Handle pair-setup M5 (client sends encrypted data)
  163. * @param session HAP session
  164. * @param input Input TLV (encrypted data)
  165. * @param input_len Length of input
  166. * @param output Output buffer for M6 (encrypted response)
  167. * @param output_capacity Capacity of output buffer
  168. * @param output_len Actual output length
  169. * @return ESP_OK on success
  170. */
  171. esp_err_t hap_pair_setup_m5(hap_session_t *session, const uint8_t *input,
  172. size_t input_len, uint8_t *output,
  173. size_t output_capacity, size_t *output_len);