49 lines
include/update_auth.h
Declares UpdateAuthenticator, the challenge size constants, and the HMAC interface.
// UpdateAuthenticator: HMAC-based challenge-response gate for firmware updates.
#pragma once
#include <cstddef>
#include <cstdint>
#include <optional>
#include <vector>
 
// kChallengeSize: number of random bytes in each issued challenge nonce.
static constexpr std::size_t kChallengeSize  = 16;
 
// kResponseSize: expected size of the HMAC-SHA256 response in bytes.
// The client computes HMAC-SHA256(secret, challenge) and sends all 32 bytes.
// A response shorter or longer than this must be rejected.
static constexpr std::size_t kResponseSize   = 32;
 
// Authenticates firmware update requests via HMAC challenge-response.
// The shared secret is loaded at construction and never leaves the instance.
class UpdateAuthenticator {
public:
  // Parameters:
  //   secret - shared HMAC key known to both daemon and authorised update client
  // Returns: new UpdateAuthenticator ready to issue challenges
  explicit UpdateAuthenticator(std::vector<uint8_t> secret);
 
  // Issues a fresh challenge nonce to begin an authentication round.
  // The nonce must be cryptographically unpredictable to prevent pre-computation.
  // Parameters: none
  // Returns: kChallengeSize-byte nonce; the same nonce is expected in the next verify call
  std::vector<uint8_t> issueChallenge();
 
  // Verifies a challenge-response from the update client.
  // Parameters:
  //   response - HMAC-SHA256 response supplied by the client; must be exactly kResponseSize bytes
  // Returns: true if response matches HMAC-SHA256(secret, lastChallenge) over all kResponseSize bytes
  bool verifyResponse(const std::vector<uint8_t>& response);
 
  // Returns true if a challenge has been issued but not yet verified.
  bool hasPendingChallenge() const { return lastChallenge_.has_value(); }
 
private:
  std::vector<uint8_t>              secret_;        // shared HMAC key
  std::optional<std::vector<uint8_t>> lastChallenge_; // nonce issued in the current round
 
  // Computes HMAC-SHA256(secret_, challenge) and returns all 32 bytes.
  // Parameters:
  //   challenge - the issued nonce
  // Returns: 32-byte HMAC digest
  std::vector<uint8_t> computeHmac(const std::vector<uint8_t>& challenge) const;
};