// Copyright 2018 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.

#include <algorithm>
#include <base/logging.h>
#include <base/strings/stringprintf.h>
#include <base/strings/string_number_conversions.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <hidapi/hidapi.h>
#include <memory>
#include <vector>

#include "u2fd/g2f_tools/g2f_client.h"

namespace {

hid_device* kDummyDevice = reinterpret_cast<hid_device*>(0xdeadbeef);

constexpr char kDummyDeviceName[] = "DummyDeviceName";

constexpr char kDummySingleResponse[] =
    "AABBCCDD860008DEADBEEF000000000000000000000000000000000000000000"
    "0000000000000000000000000000000000000000000000000000000000000000";

constexpr char kDummyLargeResponse[] =
    "AABBCCDD860050DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE"
    "DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE";

constexpr char kDummyLargeResponseCont[] =
    "AABBCCDD00DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE"
    "DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE";

constexpr size_t kRwBufSize = u2f::kU2fReportSize * 4;

int hid_open_called;
int hid_close_called;

unsigned char hid_write_data[kRwBufSize];
int hid_write_count;

unsigned char hid_read_data[kRwBufSize];
int hid_read_count;

bool hid_read_fail_timeout = false;

}  // namespace

hid_device* hid_open_path(const char* path) {
  EXPECT_THAT(path, ::testing::StrEq(kDummyDeviceName));
  hid_open_called++;
  return kDummyDevice;
}

void hid_close(hid_device* device) {
  EXPECT_EQ(device, kDummyDevice);
  hid_close_called++;
}

int hid_write(hid_device* device, const unsigned char* data, size_t length) {
  EXPECT_EQ(device, kDummyDevice);
  length = std::min(length, kRwBufSize - hid_write_count);
  memcpy(hid_write_data + hid_write_count, data, length);
  hid_write_count += length;
  return length;
}

int hid_read_timeout(hid_device* device,
                     unsigned char* data,
                     size_t length,
                     int milliseconds) {
  length = std::min(length, kRwBufSize - hid_read_count);
  if (hid_read_fail_timeout) {
    // sleep
  }
  EXPECT_EQ(device, kDummyDevice);
  memcpy(data, hid_read_data + hid_read_count, length);
  hid_read_count += length;
  return length;
}

const wchar_t* hid_error(hid_device* device) {
  return nullptr;
}

namespace g2f_client {
namespace {

using ::testing::_;
using ::testing::ByRef;
using ::testing::ContainerEq;
using ::testing::DoAll;
using ::testing::Each;
using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::InvokeWithoutArgs;
using ::testing::MatcherCast;
using ::testing::MatchesRegex;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::SetArgPointee;
using ::testing::StrEq;

static HidDevice::Cid kDummyCid = {{0xAA, 0xBB, 0xCC, 0xDD}};
static constexpr int kHidTimeoutMs = 100;

class G2fClientTest : public ::testing::Test {
 public:
  G2fClientTest() = default;
  G2fClientTest(const G2fClientTest&) = delete;
  G2fClientTest& operator=(const G2fClientTest&) = delete;

  ~G2fClientTest() override = default;

  void SetUp() override {
    hid_open_called = 0;
    hid_close_called = 0;
    memset(hid_write_data, 0, kRwBufSize);
    hid_write_count = 0;
    memset(hid_read_data, 0, kRwBufSize);
    hid_read_count = 0;
    hid_read_fail_timeout = false;
    device_.reset(new HidDevice(kDummyDeviceName));
  }

 protected:
  std::unique_ptr<HidDevice> device_;
};

TEST_F(G2fClientTest, HidDeviceOpenClose) {
  // Sanity check.
  EXPECT_EQ(0, hid_open_called);
  EXPECT_EQ(0, hid_close_called);

  EXPECT_FALSE(device_->IsOpened());
  EXPECT_TRUE(device_->Open());
  EXPECT_TRUE(device_->IsOpened());

  EXPECT_EQ(1, hid_open_called);
  EXPECT_EQ(0, hid_close_called);

  // Does not open multiple times.
  EXPECT_TRUE(device_->Open());
  EXPECT_TRUE(device_->IsOpened());

  EXPECT_EQ(1, hid_open_called);
  EXPECT_EQ(0, hid_close_called);

  device_->Close();
  EXPECT_FALSE(device_->IsOpened());

  EXPECT_EQ(1, hid_open_called);
  EXPECT_EQ(1, hid_close_called);
}

TEST_F(G2fClientTest, HidDeviceSendWithoutOpen) {
  brillo::Blob payload;
  EXPECT_FALSE(device_->SendRequest(kDummyCid, 0, payload));
}

TEST_F(G2fClientTest, HidDeviceRecvWithoutOpen) {
  uint8_t cmd;
  brillo::Blob payload;
  EXPECT_FALSE(device_->RecvResponse(kDummyCid, &cmd, &payload, 0));
}

TEST_F(G2fClientTest, HidDeviceSend) {
  EXPECT_TRUE(device_->Open());

  brillo::Blob payload{0xDD, 0xFF};
  EXPECT_TRUE(device_->SendRequest(kDummyCid, 0xAB, payload));

  EXPECT_THAT(base::HexEncode(hid_write_data, hid_write_count),
              MatchesRegex(".*"
                           "AABBCCDD.*"  // Cid
                           "AB.*"        // Command
                           "DDFF.*"));   // Payload
}

TEST_F(G2fClientTest, HidDeviceSendMultipleFrames) {
  EXPECT_TRUE(device_->Open());

  brillo::Blob payload;
  for (int i = 0; i < u2f::kU2fReportSize * 2; i++) {
    payload.push_back(i);
  }
  EXPECT_TRUE(device_->SendRequest(kDummyCid, 0xAB, payload));

  EXPECT_THAT(base::HexEncode(hid_write_data, hid_write_count),
              MatchesRegex(".*"
                           "AABBCCDD.*"  // Cid
                           "AB.*"        // Command
                           "010203.*"    // Payload
                           // Second frame:
                           "AABBCCDD.*"   // Cid
                           "01.*"         // Cont
                           "747576.*"));  // Payload
}

TEST_F(G2fClientTest, HidDeviceSendTooLarge) {
  EXPECT_TRUE(device_->Open());

  brillo::Blob payload(UINT16_MAX + 1, 0);
  EXPECT_FALSE(device_->SendRequest(kDummyCid, 0xAB, payload));
}

TEST_F(G2fClientTest, HidDeviceSendWriteFails) {
  EXPECT_TRUE(device_->Open());

  // Pretend the whole buffer has been read already;
  // subsequent reads will fail.
  hid_write_count = sizeof(hid_write_data);

  brillo::Blob payload(10, 0);
  EXPECT_FALSE(device_->SendRequest(kDummyCid, 0xAB, payload));
}

namespace {

void HexStringToBuffer(const char* str, unsigned char** dest) {
  std::vector<uint8_t> bytes;
  CHECK(base::HexStringToBytes(str, &bytes));
  std::copy(bytes.begin(), bytes.end(), *dest);
  *dest += bytes.size();
}

}  // namespace

TEST_F(G2fClientTest, HidDeviceRecvResponse) {
  unsigned char* dest = hid_read_data;
  HexStringToBuffer(kDummySingleResponse, &dest);

  uint8_t cmd;
  brillo::Blob payload;

  EXPECT_TRUE(device_->Open());
  EXPECT_TRUE(device_->RecvResponse(kDummyCid, &cmd, &payload, kHidTimeoutMs));

  EXPECT_THAT(payload, ElementsAre(0xDE, 0xAD, 0xBE, 0xEF, 0, 0, 0, 0));
}

TEST_F(G2fClientTest, HidDeviceRecvResponseMultiPart) {
  unsigned char* dest = hid_read_data;
  HexStringToBuffer(kDummyLargeResponse, &dest);
  HexStringToBuffer(kDummyLargeResponseCont, &dest);

  uint8_t cmd;
  brillo::Blob payload;

  EXPECT_TRUE(device_->Open());
  EXPECT_TRUE(device_->RecvResponse(kDummyCid, &cmd, &payload, kHidTimeoutMs));

  EXPECT_EQ(0x50, payload.size());
  EXPECT_THAT(payload, Each(0xDE));
}

TEST_F(G2fClientTest, HidDeviceRecvResponseUnexpectedInit) {
  unsigned char* dest = hid_read_data;
  HexStringToBuffer(kDummyLargeResponse, &dest);
  HexStringToBuffer(kDummyLargeResponse, &dest);

  uint8_t cmd;
  brillo::Blob payload;

  EXPECT_TRUE(device_->Open());
  EXPECT_FALSE(device_->RecvResponse(kDummyCid, &cmd, &payload, kHidTimeoutMs));
}

TEST_F(G2fClientTest, HidDeviceRecvResponseUnexpectedCont) {
  unsigned char* dest = hid_read_data;
  HexStringToBuffer(kDummyLargeResponseCont, &dest);

  uint8_t cmd;
  brillo::Blob payload;

  EXPECT_TRUE(device_->Open());
  EXPECT_FALSE(device_->RecvResponse(kDummyCid, &cmd, &payload, kHidTimeoutMs));
}

TEST_F(G2fClientTest, HidDeviceRecvResponseUnexpectedChannel) {
  unsigned char* dest = hid_read_data;
  HexStringToBuffer(kDummySingleResponse, &dest);

  uint8_t cmd;
  brillo::Blob payload;

  EXPECT_TRUE(device_->Open());
  EXPECT_FALSE(device_->RecvResponse({0xFF, 0xFF, 0xFF, 0xFF}, &cmd, &payload,
                                     kHidTimeoutMs));
}

TEST_F(G2fClientTest, HidDeviceRecvResponseUnexpectedSeq) {
  unsigned char* dest = hid_read_data;
  HexStringToBuffer(kDummyLargeResponse, &dest);
  HexStringToBuffer(kDummyLargeResponseCont, &dest);

  hid_read_data[4] = 7;

  uint8_t cmd;
  brillo::Blob payload;

  EXPECT_TRUE(device_->Open());
  EXPECT_FALSE(device_->RecvResponse(kDummyCid, &cmd, &payload, kHidTimeoutMs));
}

TEST_F(G2fClientTest, HidDeviceRecvResponseReadFail) {
  // Simulate having read all data; subsequent reads will fail.
  hid_read_count = sizeof(hid_read_data);

  uint8_t cmd;
  brillo::Blob payload;

  EXPECT_TRUE(device_->Open());
  EXPECT_FALSE(device_->RecvResponse(kDummyCid, &cmd, &payload, kHidTimeoutMs));
}

class MockHidDevice : public HidDevice {
 public:
  MockHidDevice() : HidDevice("unused") {}
  MOCK_METHOD(bool, IsOpened, (), (const, override));
  MOCK_METHOD(bool, Open, (), (override));
  MOCK_METHOD(void, Close, (), (override));
  MOCK_METHOD(bool,
              SendRequest,
              (const Cid&, uint8_t, const brillo::Blob&),
              (override));
  MOCK_METHOD(bool,
              RecvResponse,
              (const Cid&, uint8_t*, brillo::Blob*, int),
              (override));
};

class U2FHidTest : public ::testing::Test {
 public:
  U2FHidTest() : hid_(&device_) {}
  U2FHidTest(const U2FHidTest&) = delete;
  U2FHidTest& operator=(const U2FHidTest&) = delete;

  ~U2FHidTest() override = default;

 protected:
  void ExpectInit(bool copy_nonce,
                  const char* cid,
                  const char* version,
                  const char* caps);

  void ExpectDefaultInit() { ExpectInit(true, "AABBCCDD", "00000000", "00"); }

  void ExpectMsg(U2FHid::CommandCode cmd, bool echo_req);

  MockHidDevice device_;
  U2FHid hid_;

  U2FHid::Command request;
  U2FHid::Command response;
  brillo::Blob nonce;
};

MATCHER(IsBroadcastCid, "Matches the broadcast cid.") {
  return arg.raw[0] == 0xFF && arg.raw[1] == 0xFF && arg.raw[2] == 0xFF &&
         arg.raw[3] == 0xFF;
}

MATCHER_P(EqCommandCode, value, "Matches the specified command code") {
  return arg == static_cast<uint8_t>(value);
}

ACTION_P4(PrepareInitResponse, copy_nonce, req, resp, str) {
  if (copy_nonce)
    *resp = *req;
  std::vector<uint8_t> bytes;
  LOG(ERROR) << str;
  CHECK(base::HexStringToBytes(str, &bytes));
  std::copy(bytes.begin(), bytes.end(), std::back_inserter(*resp));
}

void U2FHidTest::ExpectInit(bool copy_nonce,
                            const char* cid,
                            const char* version,
                            const char* caps) {
  EXPECT_CALL(device_, Open()).WillOnce(Return(true));

  std::string resp = base::StringPrintf("%s%s%s", cid, version, caps);

  EXPECT_CALL(device_,
              SendRequest(IsBroadcastCid(),
                          EqCommandCode(U2FHid::CommandCode::kInit), _))
      .WillOnce(DoAll(SaveArg<2>(&request.payload),
                      PrepareInitResponse(copy_nonce, &request.payload,
                                          &response.payload, resp),
                      Return(true)));

  EXPECT_CALL(device_, RecvResponse(_, _, _, _))
      .WillOnce(DoAll(
          SetArgPointee<1>(static_cast<uint8_t>(U2FHid::CommandCode::kInit)),
          SetArgPointee<2>(ByRef(response.payload)), Return(true)));
}

void U2FHidTest::ExpectMsg(U2FHid::CommandCode cmd, bool echo_req) {
  EXPECT_CALL(device_, Open()).WillOnce(Return(true));

  EXPECT_CALL(device_, SendRequest(_, EqCommandCode(cmd), _))
      .WillOnce(DoAll(SaveArg<2>(&request.payload),
                      InvokeWithoutArgs([this, echo_req]() {
                        if (echo_req)
                          response.payload = request.payload;
                        else
                          response.payload.clear();
                      }),
                      Return(true)));

  EXPECT_CALL(device_, RecvResponse(_, _, _, _))
      .WillOnce(DoAll(SetArgPointee<1>(static_cast<uint8_t>(cmd)),
                      SetArgPointee<2>(ByRef(response.payload)), Return(true)));
}

TEST_F(U2FHidTest, Init) {
  ExpectInit(true,        // Copy nonce
             "AABBCCDD",  // Cid
             "00000000",  // Version
             "DE");       // Caps
  EXPECT_TRUE(hid_.Init(false));
  EXPECT_TRUE(hid_.Initialized());
  EXPECT_EQ(00, hid_.GetVersion().protocol);
  EXPECT_EQ(0xDE, hid_.GetCaps());

  // Calling again does not re-initialize.
  EXPECT_TRUE(hid_.Init(false));
  EXPECT_TRUE(hid_.Initialized());

  ExpectInit(true,        // Copy nonce
             "AABBCCDD",  // Cid
             "DEADBEEF",  // Version
             "AF");       // Caps

  // Force re-initialization
  EXPECT_TRUE(hid_.Init(true));
  EXPECT_TRUE(hid_.Initialized());
  EXPECT_EQ(0xEF, hid_.GetVersion().build);
  EXPECT_EQ(0xAF, hid_.GetCaps());
}

TEST_F(U2FHidTest, InitBadResponseSize) {
  ExpectInit(true,        // Copy nonce
             "AABBCCDD",  // Cid
             "00",        // Version - too short!
             "DE");       // Caps
  EXPECT_FALSE(hid_.Init(false));
  EXPECT_FALSE(hid_.Initialized());
}

TEST_F(U2FHidTest, InitBadNonce) {
  ExpectInit(false,              // Copy nonce
             "0000000000000000"  // Incorrect nonce (prepend to cid)
             "AABBCCDD",         // Cid
             "00000000",         // Version - too short!
             "DE");              // Caps
  EXPECT_FALSE(hid_.Init(false));
  EXPECT_FALSE(hid_.Initialized());
}

TEST_F(U2FHidTest, InitSendError) {
  EXPECT_CALL(device_, Open()).WillOnce(Return(true));
  EXPECT_CALL(device_, SendRequest(_, _, _)).WillOnce(Return(false));

  EXPECT_FALSE(hid_.Init(false));
  EXPECT_FALSE(hid_.Initialized());
}

TEST_F(U2FHidTest, InitRecvError) {
  EXPECT_CALL(device_, Open()).WillOnce(Return(true));
  EXPECT_CALL(device_,
              SendRequest(IsBroadcastCid(),
                          EqCommandCode(U2FHid::CommandCode::kInit), _))
      .WillOnce(Return(true));
  EXPECT_CALL(device_, RecvResponse(_, _, _, _)).WillOnce(Return(false));

  EXPECT_FALSE(hid_.Init(false));
  EXPECT_FALSE(hid_.Initialized());
}

TEST_F(U2FHidTest, Lock) {
  ExpectDefaultInit();
  EXPECT_TRUE(hid_.Init(false));

  ExpectMsg(U2FHid::CommandCode::kLock, false);
  EXPECT_TRUE(hid_.Lock(10));
}

TEST_F(U2FHidTest, Msg) {
  brillo::Blob request = {1, 2, 3, 4, 5};
  brillo::Blob response;

  ExpectDefaultInit();
  EXPECT_TRUE(hid_.Init(false));

  ExpectMsg(U2FHid::CommandCode::kMsg, true);
  EXPECT_TRUE(hid_.Msg(request, &response));
  EXPECT_THAT(response, ContainerEq(request));
}

TEST_F(U2FHidTest, Ping) {
  ExpectDefaultInit();
  EXPECT_TRUE(hid_.Init(false));

  ExpectMsg(U2FHid::CommandCode::kPing, true);
  EXPECT_TRUE(hid_.Ping(10));
}

TEST_F(U2FHidTest, Wink) {
  ExpectDefaultInit();
  EXPECT_TRUE(hid_.Init(false));

  ExpectMsg(U2FHid::CommandCode::kWink, true);
  EXPECT_TRUE(hid_.Wink());
}

class MockU2FHid : public U2FHid {
 public:
  MockU2FHid() : U2FHid(nullptr) {}
  MOCK_METHOD(bool, Msg, (const brillo::Blob&, brillo::Blob*), (override));
};

class U2FTest : public ::testing::Test {
 public:
  U2FTest() : u2f_(&u2f_hid_) {}
  U2FTest(const U2FTest&) = delete;
  U2FTest& operator=(const U2FTest&) = delete;

  ~U2FTest() override = default;

 protected:
  void RunRegisterExpectFail() {
    const brillo::Blob challenge(32, 0xaa);
    const brillo::Blob application(32, 0xbb);

    brillo::Blob public_key;
    brillo::Blob key_handle;
    brillo::Blob cert;

    EXPECT_FALSE(u2f_.Register(-1,  // Default P1
                               challenge, application,
                               false,  // G2F
                               &public_key, &key_handle, &cert));
  }

  void RunAuthenticateExpectFail() {
    const brillo::Blob challenge(32, 0xaa);
    const brillo::Blob application(32, 0xbb);
    const brillo::Blob key_handle(27, 0xde);

    bool presence_verified = false;
    brillo::Blob counter;
    brillo::Blob signature;

    EXPECT_FALSE(u2f_.Authenticate(-1,  // Default P1
                                   challenge, application, key_handle,
                                   &presence_verified, &counter, &signature));
  }

  MockU2FHid u2f_hid_;
  U2F u2f_;
};

TEST_F(U2FTest, RegisterSuccess) {
  const brillo::Blob expected_public_key(65, 0x65);
  const brillo::Blob expected_key_handle(13, 0xde);
  const brillo::Blob expected_cert(29, 0xfc);
  // See section 4.3 of U2F Raw Message Format spec
  // for details.
  brillo::Blob response = {
      0x05,  // Reserved (legacy reasons)
  };
  // Public key, fixed size.
  U2F::AppendBlob(expected_public_key, &response);
  // Key handle, variable size.
  response.push_back(expected_key_handle.size());
  U2F::AppendBlob(expected_key_handle, &response);
  // Cert and signature, variable size.
  U2F::AppendBlob(expected_cert, &response);
  // Status code: SW_NO_ERROR
  response.push_back(0x90);  // Sw1
  response.push_back(0x00);  // Sw2

  EXPECT_CALL(u2f_hid_, Msg(_, _))
      .WillOnce(DoAll(SetArgPointee<1>(response), Return(true)));

  const brillo::Blob challenge(32, 0xaa);
  const brillo::Blob application(32, 0xbb);

  brillo::Blob public_key;
  brillo::Blob key_handle;
  brillo::Blob cert;

  EXPECT_TRUE(u2f_.Register(-1,  // Default P1
                            challenge, application,
                            false,  // G2F
                            &public_key, &key_handle, &cert));

  EXPECT_THAT(public_key, ContainerEq(expected_public_key));
  EXPECT_THAT(key_handle, ContainerEq(expected_key_handle));
  EXPECT_THAT(cert, ContainerEq(expected_cert));
}

TEST_F(U2FTest, RegisterMsgFails) {
  EXPECT_CALL(u2f_hid_, Msg(_, _)).WillOnce(Return(false));

  RunRegisterExpectFail();
}

TEST_F(U2FTest, RegisterBadStatus) {
  brillo::Blob response = {
      // Dummy data, unused.
      0xDE, 0xAD, 0xBE, 0xEF,
      // Status code: SW_WRONG_DATA
      0x6A,  // SW1
      0x80,  // SW2
  };

  EXPECT_CALL(u2f_hid_, Msg(_, _))
      .WillOnce(DoAll(SetArgPointee<1>(response), Return(true)));

  RunRegisterExpectFail();
}

TEST_F(U2FTest, RegisterShortResponse) {
  // See section 4.3 of U2F Raw Message Format spec
  // for details.
  brillo::Blob response = {
      0x05,  // Reserved (legacy reasons)
      // Rest of response should go here (intentionally missing).
      // Status code: SW_NO_ERROR
      0x90,  // SW1
      0x00,  // SW2
  };

  EXPECT_CALL(u2f_hid_, Msg(_, _))
      .WillOnce(DoAll(SetArgPointee<1>(response), Return(true)));

  RunRegisterExpectFail();
}

TEST_F(U2FTest, AuthenticateSuccess) {
  brillo::Blob response = {0x01,                    // Presence verified
                           0x01, 0x02, 0x03, 0x04,  // Counter
                           0xde, 0xad, 0xbe, 0xef,  // Signature
                           0x90, 0x00};             // Status code: SW_NO_ERROR

  EXPECT_CALL(u2f_hid_, Msg(_, _))
      .WillOnce(DoAll(SetArgPointee<1>(response), Return(true)));

  const brillo::Blob challenge(32, 0xaa);
  const brillo::Blob application(32, 0xbb);
  const brillo::Blob key_handle(27, 0xde);

  bool presence_verified = false;
  brillo::Blob counter;
  brillo::Blob signature;

  EXPECT_TRUE(u2f_.Authenticate(-1,  // Default P1
                                challenge, application, key_handle,
                                &presence_verified, &counter, &signature));

  EXPECT_TRUE(presence_verified);
  EXPECT_THAT(counter, ElementsAre(1, 2, 3, 4));
  EXPECT_THAT(signature, ElementsAre(0xde, 0xad, 0xbe, 0xef));
}

TEST_F(U2FTest, AuthenticateMsgFail) {
  EXPECT_CALL(u2f_hid_, Msg(_, _)).WillOnce(Return(false));

  RunAuthenticateExpectFail();
}

TEST_F(U2FTest, AuthenticateBadStatus) {
  brillo::Blob response = {0x01,                    // Presence verified
                           0x01, 0x02, 0x03, 0x04,  // Counter
                           0xde, 0xad, 0xbe, 0xef,  // Signature
                           0x6A, 0x80};  // Status code: U2F_SW_NO_ERROR

  EXPECT_CALL(u2f_hid_, Msg(_, _))
      .WillOnce(DoAll(SetArgPointee<1>(response), Return(true)));

  RunAuthenticateExpectFail();
}

TEST_F(U2FTest, AuthenticateShortReponse) {
  brillo::Blob response = {0x01,         // Presence verified
                                         // Remainder of response should go here
                                         // (intentionally left blank)
                           0x90, 0x00};  // Status code: SW_NO_ERROR

  EXPECT_CALL(u2f_hid_, Msg(_, _))
      .WillOnce(DoAll(SetArgPointee<1>(response), Return(true)));

  RunAuthenticateExpectFail();
}

}  // namespace
}  // namespace g2f_client
