blob: dc5016ad3c0b8953a443333c251c21aa7a2e8fa9 [file] [log] [blame]
// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef HAMMERD_PAIR_UTILS_H_
#define HAMMERD_PAIR_UTILS_H_
#include <base/macros.h>
#include <gtest/gtest_prod.h>
#include "hammerd/curve25519.h"
#include "hammerd/dbus_wrapper.h"
#include "hammerd/update_fw.h"
namespace hammerd {
// The length of the HMAC nonce
constexpr size_t kHMACNonceLength = 16;
// The truncated length of the HMAC authenticator
constexpr size_t kHMACAuthenticatorLength = 16;
// Pair challenge (from host), note that the packet, with header, must fit
// in a single USB packet (64 bytes), so its maximum length is 50 bytes.
struct PairChallengeRequest {
uint8_t public_key[X25519_PUBLIC_VALUE_LEN]; // X22519 public key from host
uint8_t nonce[kHMACNonceLength]; // nonce to be used for HMAC
};
static_assert(sizeof(PairChallengeRequest) <= 50,
"size of PairChallengeRequest must be <= 50 bytes");
// Pair challenge response (from device).
struct PairChallengeResponse {
uint8_t status; // Returned status from EC
uint8_t public_key[X25519_PUBLIC_VALUE_LEN]; // X25519 public key from device
// Authentication output, the value should be:
// HMAC_SHA256(X25519(device_private, host_public), nonce)
uint8_t authenticator[kHMACAuthenticatorLength];
} __attribute__((packed));
enum class ChallengeStatus {
kChallengePassed,
kChallengeFailed,
kNeedInjectEntropy,
kConnectionError,
kUnknownError,
};
// The interface of pairing manager.
class PairManagerInterface {
public:
virtual ~PairManagerInterface() = default;
// Generates the challange request and sends to the hammer. Then verifies the
// challenge.
virtual ChallengeStatus PairChallenge(FirmwareUpdaterInterface* fw_updater,
DBusWrapperInterface* dbus_wrapper) = 0;
};
// The host for generating and verifying the challenge.
// In order to prevent the challenge reuse, PairManager does not store the
// request as data members.
class PairManager : public PairManagerInterface {
public:
PairManager() = default;
PairManager(const PairManager&) = delete;
PairManager& operator=(const PairManager&) = delete;
~PairManager() override = default;
ChallengeStatus PairChallenge(FirmwareUpdaterInterface* fw_updater,
DBusWrapperInterface* dbus_wrapper) override;
protected:
virtual void GenerateChallenge(PairChallengeRequest* request,
uint8_t* private_key);
bool VerifyChallenge(const PairChallengeRequest& request,
uint8_t* private_key,
const PairChallengeResponse& resp);
};
} // namespace hammerd
#endif // HAMMERD_PAIR_UTILS_H_