Challenge-Response API
The challenge-response API lets a device authenticate a peer that holds its
master key. It is enabled with CONFIG_HUBBLE_CHALLENGE.
- group Challenge-Response APIs
Hubble Challenge-Response APIs.
Lets the device authenticate a peer that holds its master key, for example the Hubble Cloud or a service acting on its behalf.
The application picks a nonce and builds a challenge from it with hubble_challenge_get, then sends the challenge to the peer over any transport. The challenge carries the device’s current EID in plain bytes, so the peer can look up the device and its key the same way it resolves an advertisement. The peer computes the response and sends it back, and the application checks it with hubble_challenge_response_check.
Challenge layout (HUBBLE_CHALLENGE_SIZE bytes):
| offset | size | field | |--------+------+---------------------------------------------| | 0 | 1 | version (HUBBLE_CHALLENGE_VERSION) | | 1 | 4 | EID, same bytes as the BLE advertisement | | 5 | 16 | nonce supplied by the application |
The response (HUBBLE_CHALLENGE_RESPONSE_SIZE bytes) is derived with the NIST SP 800-108 counter mode KDF, AES-CMAC as PRF, the same function the SDK uses for its other derived keys and values:
challenge_key = KDF(master_key, "ChallengeKey", decimal(time_counter), key_len) response = KDF(challenge_key, "Response", challenge, 16)where time_counter is the counter the EID was derived from.
The SDK keeps no state between the two calls. Replay protection is the application’s job: the nonce must be unpredictable, and a response must be accepted at most once for a given nonce.
Defines
-
HUBBLE_CHALLENGE_VERSION
Version of the challenge format.
-
HUBBLE_CHALLENGE_NONCE_SIZE
Size of the nonce carried in the challenge in bytes.
-
HUBBLE_CHALLENGE_SIZE
Size of a challenge in bytes.
-
HUBBLE_CHALLENGE_RESPONSE_SIZE
Size of a challenge response in bytes.
Functions
-
int hubble_challenge_get(const uint8_t *nonce, size_t nonce_len, uint8_t *challenge, size_t *len)
Build a challenge from a nonce.
Writes the challenge for the current time counter: version, current EID and
nonce.- Parameters:
nonce – Nonce chosen by the application, it should come from a cryptographically secure random number generator.
nonce_len – Length of
noncein bytes, must be HUBBLE_CHALLENGE_NONCE_SIZE.challenge – Output buffer of at least HUBBLE_CHALLENGE_SIZE bytes.
len – in: Size of
challengein bytes. out: Number of bytes written.
- Return values:
0 – Challenge built.
-EINVAL – A pointer is NULL,
nonce_lenis wrong,lenis too small or no key is set.<0 – Negative errno from the time counter or the crypto provider.
-
int hubble_challenge_response_check(const uint8_t *challenge, size_t challenge_len, const uint8_t *response, size_t response_len)
Check the response to a challenge.
Compares
responsewith the value expected forchallenge. The challenge must have been built by hubble_challenge_get in the current EID rotation period.- Parameters:
challenge – Challenge sent to the peer.
challenge_len – Length of
challengein bytes, must be HUBBLE_CHALLENGE_SIZE.response – Response received from the peer.
response_len – Length of
responsein bytes, must be HUBBLE_CHALLENGE_RESPONSE_SIZE.
- Return values:
0 – The response matches, the peer holds the device key.
-EINVAL – A pointer is NULL, a length is wrong, the challenge version is unknown or no key is set.
-ETIMEDOUT – The EID rotated since the challenge was built, build a new one.
-EACCES – The response does not match.
<0 – Negative errno from the time counter or the crypto provider.
-
HUBBLE_CHALLENGE_VERSION