// Copyright (c) 2011 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 "chaps/chaps_adaptor.h"

#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/synchronization/lock.h>

#include "chaps/chaps.h"
#include "chaps/chaps_interface.h"
#include "chaps/chaps_utility.h"
#include "chaps/token_manager_interface.h"

using base::AutoLock;
using base::FilePath;
using base::Lock;
using chromeos::SecureBlob;
using std::string;
using std::vector;

namespace chaps {

// Helper used when calling the ObjectAdaptor constructor.
static DBus::Connection& GetConnection() {
  static DBus::Connection connection = DBus::Connection::SystemBus();
#ifdef NO_DBUS_ACQUIRE_NAME
  connection.request_name(kChapsServiceName);
#else
  CHECK(connection.acquire_name(kChapsServiceName));
#endif
  return connection;
}

ChapsAdaptor::ChapsAdaptor(Lock* lock,
                           ChapsInterface* service,
                           TokenManagerInterface* token_manager)
    : DBus::ObjectAdaptor(GetConnection(),
                          DBus::Path(kChapsServicePath)),
      lock_(lock),
      service_(service),
      token_manager_(token_manager) {}

ChapsAdaptor::~ChapsAdaptor() {}

void ChapsAdaptor::OpenIsolate(
      const std::vector<uint8_t>& isolate_credential_in,
      std::vector<uint8_t>& isolate_credential_out,  // NOLINT - refs
      bool& new_isolate_created,  // NOLINT(runtime/references)
      bool& result) {  // NOLINT(runtime/references)
  VLOG(1) << "CALL: " << __func__;
  result = false;
  SecureBlob isolate_credential(isolate_credential_in.begin(),
                                isolate_credential_in.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential_in));
  if (token_manager_)
    result = token_manager_->OpenIsolate(&isolate_credential,
                                         &new_isolate_created);
  isolate_credential_out.swap(isolate_credential);
}

void ChapsAdaptor::OpenIsolate(
      const std::vector<uint8_t>& isolate_credential_in,
      std::vector<uint8_t>& isolate_credential_out,  // NOLINT - refs
      bool& new_isolate_created,  // NOLINT(runtime/references)
      bool& result,  // NOLINT(runtime/references)
      ::DBus::Error& /*error*/) {
  OpenIsolate(isolate_credential_in, isolate_credential_out,
              new_isolate_created, result);
}

void ChapsAdaptor::CloseIsolate(const vector<uint8_t>& isolate_credential) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  if (token_manager_)
    token_manager_->CloseIsolate(isolate_credential_blob);
}

void ChapsAdaptor::CloseIsolate(const vector<uint8_t>& isolate_credential,
                                ::DBus::Error& /*error*/) {
  CloseIsolate(isolate_credential);
}

void ChapsAdaptor::LoadToken(const vector<uint8_t>& isolate_credential,
                             const string& path,
                             const vector<uint8_t>& auth_data,
                             const string& label,
                             uint64_t& slot_id,  // NOLINT(runtime/references)
                             bool& result) {  // NOLINT(runtime/references)
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  SecureBlob auth_data_blob(auth_data.begin(), auth_data.end());
  if (token_manager_)
    result = token_manager_->LoadToken(isolate_credential_blob,
                                       FilePath(path),
                                       auth_data_blob,
                                       label,
                                       PreservedValue<uint64_t, int>(&slot_id));
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  ClearVector(const_cast<vector<uint8_t>*>(&auth_data));
}

void ChapsAdaptor::LoadToken(const vector<uint8_t>& isolate_credential,
                             const string& path,
                             const vector<uint8_t>& auth_data,
                             const string& label,
                             uint64_t& slot_id,  // NOLINT(runtime/references)
                             bool& result,  // NOLINT(runtime/references)
                             ::DBus::Error& /*error*/) {
  LoadToken(isolate_credential, path, auth_data, label, slot_id, result);
}

void ChapsAdaptor::UnloadToken(const vector<uint8_t>& isolate_credential,
                               const string& path) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  if (token_manager_)
    token_manager_->UnloadToken(isolate_credential_blob, FilePath(path));
}

void ChapsAdaptor::UnloadToken(const vector<uint8_t>& isolate_credential,
                               const string& path,
                               ::DBus::Error& /*error*/) {
  UnloadToken(isolate_credential, path);
}

void ChapsAdaptor::ChangeTokenAuthData(const string& path,
                                       const vector<uint8_t>& old_auth_data,
                                       const vector<uint8_t>& new_auth_data) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  if (token_manager_)
    token_manager_->ChangeTokenAuthData(
        FilePath(path),
        SecureBlob(old_auth_data.begin(), old_auth_data.end()),
        SecureBlob(new_auth_data.begin(), new_auth_data.end()));
  ClearVector(const_cast<vector<uint8_t>*>(&old_auth_data));
  ClearVector(const_cast<vector<uint8_t>*>(&new_auth_data));
}

void ChapsAdaptor::ChangeTokenAuthData(const string& path,
                                       const vector<uint8_t>& old_auth_data,
                                       const vector<uint8_t>& new_auth_data,
                                       ::DBus::Error& /*error*/) {
  ChangeTokenAuthData(path, old_auth_data, new_auth_data);
}

void ChapsAdaptor::GetTokenPath(const std::vector<uint8_t>& isolate_credential,
                                const uint64_t& slot_id,
                                std::string& path,  // NOLINT - refs
                                bool& result) {  // NOLINT(runtime/references)
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  if (token_manager_) {
    FilePath tmp;
    result = token_manager_->GetTokenPath(isolate_credential_blob,
                                          slot_id,
                                          &tmp);
    path = tmp.value();
  }
}

void ChapsAdaptor::GetTokenPath(const std::vector<uint8_t>& isolate_credential,
                                const uint64_t& slot_id,
                                std::string& path,  // NOLINT - refs
                                bool& result,  // NOLINT(runtime/references)
                                ::DBus::Error& /*error*/) {
  GetTokenPath(isolate_credential, slot_id, path, result);
}

void ChapsAdaptor::SetLogLevel(const int32_t& level) {
  logging::SetMinLogLevel(level);
}

void ChapsAdaptor::SetLogLevel(const int32_t& level,
                               ::DBus::Error& /*error*/) {
  SetLogLevel(level);
}

void ChapsAdaptor::GetSlotList(const vector<uint8_t>& isolate_credential,
                               const bool& token_present,
                               vector<uint64_t>& slot_list,  // NOLINT - refs
                               uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "token_present=" << token_present;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->GetSlotList(isolate_credential_blob, token_present,
                                 &slot_list);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "slot_list="
                               << PrintIntVector(slot_list);
}

void ChapsAdaptor::GetSlotList(const vector<uint8_t>& isolate_credential,
                               const bool& token_present,
                               vector<uint64_t>& slot_list,  // NOLINT - rfs
                               uint32_t& result,  // NOLINT(runtime/references)
                               ::DBus::Error& /*error*/) {
  GetSlotList(isolate_credential, token_present, slot_list, result);
}

void ChapsAdaptor::GetSlotInfo(const vector<uint8_t>& isolate_credential,
                               const uint64_t& slot_id,
                               vector<uint8_t>& slot_description,  // NOLINT - refs
                               vector<uint8_t>& manufacturer_id,  // NOLINT - refs
                               uint64_t& flags,  // NOLINT - refs
                               uint8_t& hardware_version_major,  // NOLINT - refs
                               uint8_t& hardware_version_minor,  // NOLINT - refs
                               uint8_t& firmware_version_major,  // NOLINT - refs
                               uint8_t& firmware_version_minor,  // NOLINT - refs
                               uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "slot_id=" << slot_id;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->GetSlotInfo(isolate_credential_blob,
                                 slot_id,
                                 &slot_description,
                                 &manufacturer_id,
                                 &flags,
                                 &hardware_version_major,
                                 &hardware_version_minor,
                                 &firmware_version_major,
                                 &firmware_version_minor);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "slot_description="
                               << ConvertByteVectorToString(slot_description);
}

void ChapsAdaptor::GetSlotInfo(const vector<uint8_t>& isolate_credential,
                               const uint64_t& slot_id,
                               vector<uint8_t>& slot_description,  // NOLINT - refs
                               vector<uint8_t>& manufacturer_id,  // NOLINT - refs
                               uint64_t& flags,  // NOLINT - refs
                               uint8_t& hardware_version_major,  // NOLINT - refs
                               uint8_t& hardware_version_minor,  // NOLINT - refs
                               uint8_t& firmware_version_major,  // NOLINT - refs
                               uint8_t& firmware_version_minor,  // NOLINT - refs
                               uint32_t& result,  // NOLINT - refs
                               ::DBus::Error& /*error*/) {
  GetSlotInfo(isolate_credential, slot_id, slot_description, manufacturer_id,
              flags, hardware_version_major, hardware_version_minor,
              firmware_version_major, firmware_version_minor,
              result);
}

void ChapsAdaptor::GetTokenInfo(const vector<uint8_t>& isolate_credential,
                                const uint64_t& slot_id,
                                vector<uint8_t>& label,  // NOLINT - refs
                                vector<uint8_t>& manufacturer_id,  // NOLINT - refs
                                vector<uint8_t>& model,  // NOLINT - refs
                                vector<uint8_t>& serial_number,  // NOLINT - refs
                                uint64_t& flags,  // NOLINT - refs
                                uint64_t& max_session_count,  // NOLINT - refs
                                uint64_t& session_count,  // NOLINT - refs
                                uint64_t& max_session_count_rw,  // NOLINT - refs
                                uint64_t& session_count_rw,  // NOLINT - refs
                                uint64_t& max_pin_len,  // NOLINT - refs
                                uint64_t& min_pin_len,  // NOLINT - refs
                                uint64_t& total_public_memory,  // NOLINT - refs
                                uint64_t& free_public_memory,  // NOLINT - refs
                                uint64_t& total_private_memory,  // NOLINT - refs
                                uint64_t& free_private_memory,  // NOLINT - refs
                                uint8_t& hardware_version_major,  // NOLINT - refs
                                uint8_t& hardware_version_minor,  // NOLINT - refs
                                uint8_t& firmware_version_major,  // NOLINT - refs
                                uint8_t& firmware_version_minor,  // NOLINT - refs
                                uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "slot_id=" << slot_id;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->GetTokenInfo(isolate_credential_blob,
                                  slot_id,
                                  &label,
                                  &manufacturer_id,
                                  &model,
                                  &serial_number,
                                  &flags,
                                  &max_session_count,
                                  &session_count,
                                  &max_session_count_rw,
                                  &session_count_rw,
                                  &max_pin_len,
                                  &min_pin_len,
                                  &total_public_memory,
                                  &free_public_memory,
                                  &total_private_memory,
                                  &free_private_memory,
                                  &hardware_version_major,
                                  &hardware_version_minor,
                                  &firmware_version_major,
                                  &firmware_version_minor);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "label="
                               << ConvertByteVectorToString(label);
}

void ChapsAdaptor::GetTokenInfo(const vector<uint8_t>& isolate_credential,
                                const uint64_t& slot_id,
                                vector<uint8_t>& label,  // NOLINT - refs
                                vector<uint8_t>& manufacturer_id,  // NOLINT - refs
                                vector<uint8_t>& model,  // NOLINT - refs
                                vector<uint8_t>& serial_number,  // NOLINT - refs
                                uint64_t& flags,  // NOLINT - refs
                                uint64_t& max_session_count,  // NOLINT - refs
                                uint64_t& session_count,  // NOLINT - refs
                                uint64_t& max_session_count_rw,  // NOLINT - refs
                                uint64_t& session_count_rw,  // NOLINT - refs
                                uint64_t& max_pin_len,  // NOLINT - refs
                                uint64_t& min_pin_len,  // NOLINT - refs
                                uint64_t& total_public_memory,  // NOLINT - refs
                                uint64_t& free_public_memory,  // NOLINT - refs
                                uint64_t& total_private_memory,  // NOLINT - refs
                                uint64_t& free_private_memory,  // NOLINT - refs
                                uint8_t& hardware_version_major,  // NOLINT - refs
                                uint8_t& hardware_version_minor,  // NOLINT - refs
                                uint8_t& firmware_version_major,  // NOLINT - refs
                                uint8_t& firmware_version_minor,  // NOLINT - refs
                                uint32_t& result,  // NOLINT - refs
                                ::DBus::Error& /*error*/) {
  GetTokenInfo(isolate_credential, slot_id, label, manufacturer_id, model,
               serial_number, flags, max_session_count, session_count,
               max_session_count_rw, session_count_rw, max_pin_len, min_pin_len,
               total_public_memory, free_public_memory, total_private_memory,
               free_private_memory, hardware_version_major,
               hardware_version_minor, firmware_version_major,
               firmware_version_minor, result);
}

void ChapsAdaptor::GetMechanismList(const vector<uint8_t>& isolate_credential,
                                    const uint64_t& slot_id,
                                    vector<uint64_t>& mechanism_list,  // NOLINT - refs
                                    uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "slot_id=" << slot_id;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->GetMechanismList(isolate_credential_blob,
                                      slot_id,
                                      &mechanism_list);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "mechanism_list="
                               << PrintIntVector(mechanism_list);
}

void ChapsAdaptor::GetMechanismList(const vector<uint8_t>& isolate_credential,
                                    const uint64_t& slot_id,
                                    vector<uint64_t>& mechanism_list,  // NOLINT - refs
                                    uint32_t& result,  // NOLINT - refs
                                    ::DBus::Error& /*error*/) {
  GetMechanismList(isolate_credential, slot_id, mechanism_list, result);
}

void ChapsAdaptor::GetMechanismInfo(const vector<uint8_t>& isolate_credential,
                                    const uint64_t& slot_id,
                                    const uint64_t& mechanism_type,
                                    uint64_t& min_key_size,  // NOLINT - refs
                                    uint64_t& max_key_size,  // NOLINT - refs
                                    uint64_t& flags,  // NOLINT - refs
                                    uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "slot_id=" << slot_id;
  VLOG(2) << "IN: " << "mechanism_type=" << mechanism_type;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->GetMechanismInfo(isolate_credential_blob,
                                      slot_id,
                                      mechanism_type,
                                      &min_key_size,
                                      &max_key_size,
                                      &flags);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "min_key_size=" << min_key_size;
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "max_key_size=" << max_key_size;
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "flags=" << flags;
}

void ChapsAdaptor::GetMechanismInfo(const vector<uint8_t>& isolate_credential,
                                    const uint64_t& slot_id,
                                    const uint64_t& mechanism_type,
                                    uint64_t& min_key_size,  // NOLINT - refs
                                    uint64_t& max_key_size,  // NOLINT - refs
                                    uint64_t& flags,  // NOLINT - refs
                                    uint32_t& result,  // NOLINT - refs
                                    ::DBus::Error& /*error*/) {
  GetMechanismInfo(isolate_credential, slot_id, mechanism_type, min_key_size,
                   max_key_size, flags, result);
}

uint32_t ChapsAdaptor::InitToken(const vector<uint8_t>& isolate_credential,
                                 const uint64_t& slot_id,
                                 const bool& use_null_pin,
                                 const string& optional_so_pin,
                                 const vector<uint8_t>& new_token_label) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "slot_id=" << slot_id;
  VLOG(2) << "IN: " << "new_token_label="
                    << ConvertByteVectorToString(new_token_label);
  const string* tmp_pin = use_null_pin ? NULL : &optional_so_pin;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->InitToken(isolate_credential_blob,
                             slot_id,
                             tmp_pin,
                             new_token_label);
}

uint32_t ChapsAdaptor::InitToken(const vector<uint8_t>& isolate_credential,
                                 const uint64_t& slot_id,
                                 const bool& use_null_pin,
                                 const string& optional_so_pin,
                                 const vector<uint8_t>& new_token_label,
                                 ::DBus::Error& /*error*/) {
  return InitToken(isolate_credential, slot_id, use_null_pin, optional_so_pin,
                   new_token_label);
}

uint32_t ChapsAdaptor::InitPIN(const vector<uint8_t>& isolate_credential,
                               const uint64_t& session_id,
                               const bool& use_null_pin,
                               const string& optional_user_pin) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "use_null_pin=" << use_null_pin;
  const string* tmp_pin = use_null_pin ? NULL : &optional_user_pin;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->InitPIN(isolate_credential_blob,
                           session_id,
                           tmp_pin);
}

uint32_t ChapsAdaptor::InitPIN(const vector<uint8_t>& isolate_credential,
                               const uint64_t& session_id,
                               const bool& use_null_pin,
                               const string& optional_user_pin,
                               ::DBus::Error& /*error*/) {
  return InitPIN(isolate_credential, session_id, use_null_pin,
                 optional_user_pin);
}

uint32_t ChapsAdaptor::SetPIN(const vector<uint8_t>& isolate_credential,
                              const uint64_t& session_id,
                              const bool& use_null_old_pin,
                              const string& optional_old_pin,
                              const bool& use_null_new_pin,
                              const string& optional_new_pin) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "use_null_old_pin=" << use_null_old_pin;
  VLOG(2) << "IN: " << "use_null_new_pin=" << use_null_new_pin;
  const string* tmp_old_pin = use_null_old_pin ? NULL : &optional_old_pin;
  const string* tmp_new_pin = use_null_new_pin ? NULL : &optional_new_pin;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->SetPIN(isolate_credential_blob,
                          session_id,
                          tmp_old_pin,
                          tmp_new_pin);
}

uint32_t ChapsAdaptor::SetPIN(const vector<uint8_t>& isolate_credential,
                              const uint64_t& session_id,
                              const bool& use_null_old_pin,
                              const string& optional_old_pin,
                              const bool& use_null_new_pin,
                              const string& optional_new_pin,
                              ::DBus::Error& /*error*/) {
  return SetPIN(isolate_credential, session_id, use_null_old_pin,
                optional_old_pin, use_null_new_pin,  optional_new_pin);
}

void ChapsAdaptor::OpenSession(const vector<uint8_t>& isolate_credential,
                               const uint64_t& slot_id,
                               const uint64_t& flags,
                               uint64_t& session_id,  // NOLINT - refs
                               uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "slot_id=" << slot_id;
  VLOG(2) << "IN: " << "flags=" << flags;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->OpenSession(isolate_credential_blob,
                                 slot_id,
                                 flags,
                                 &session_id);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "session_id=" << session_id;
}

void ChapsAdaptor::OpenSession(const vector<uint8_t>& isolate_credential,
                               const uint64_t& slot_id,
                               const uint64_t& flags,
                               uint64_t& session_id,  // NOLINT - refs
                               uint32_t& result,  // NOLINT - refs
                               ::DBus::Error& /*error*/) {
  OpenSession(isolate_credential, slot_id, flags, session_id, result);
}

uint32_t ChapsAdaptor::CloseSession(const vector<uint8_t>& isolate_credential,
                                    const uint64_t& session_id) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->CloseSession(isolate_credential_blob,
                                session_id);
}

uint32_t ChapsAdaptor::CloseSession(const vector<uint8_t>& isolate_credential,
                                    const uint64_t& session_id,
                                    ::DBus::Error& /*error*/) {
  return CloseSession(isolate_credential, session_id);
}

uint32_t ChapsAdaptor::CloseAllSessions(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& slot_id) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "slot_id=" << slot_id;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->CloseAllSessions(
      isolate_credential_blob,
      slot_id);
}

uint32_t ChapsAdaptor::CloseAllSessions(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& slot_id,
    ::DBus::Error& /*error*/) {
  return CloseAllSessions(isolate_credential, slot_id);
}

void ChapsAdaptor::GetSessionInfo(const vector<uint8_t>& isolate_credential,
                                  const uint64_t& session_id,
                                  uint64_t& slot_id,  // NOLINT - refs
                                  uint64_t& state,  // NOLINT - refs
                                  uint64_t& flags,  // NOLINT - refs
                                  uint64_t& device_error,  // NOLINT - refs
                                  uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->GetSessionInfo(isolate_credential_blob,
                                    session_id,
                                    &slot_id,
                                    &state,
                                    &flags,
                                    &device_error);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "slot_id=" << slot_id;
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "state=" << state;
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "flags=" << flags;
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "device_error=" << device_error;
}

void ChapsAdaptor::GetSessionInfo(const vector<uint8_t>& isolate_credential,
                                  const uint64_t& session_id,
                                  uint64_t& slot_id,  // NOLINT - refs
                                  uint64_t& state,  // NOLINT - refs
                                  uint64_t& flags,  // NOLINT - refs
                                  uint64_t& device_error,  // NOLINT - refs
                                  uint32_t& result,  // NOLINT - refs
                                  ::DBus::Error& /*error*/) {
  GetSessionInfo(isolate_credential, session_id, slot_id, state, flags,
                 device_error, result);
}

void ChapsAdaptor::GetOperationState(const vector<uint8_t>& isolate_credential,
                                     const uint64_t& session_id,
                                     vector<uint8_t>& operation_state,  // NOLINT - refs
                                     uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->GetOperationState(isolate_credential_blob,
                                       session_id,
                                       &operation_state);
}

void ChapsAdaptor::GetOperationState(const vector<uint8_t>& isolate_credential,
                                     const uint64_t& session_id,
                                     vector<uint8_t>& operation_state,  // NOLINT - refs
                                     uint32_t& result,  // NOLINT - refs
                                     ::DBus::Error& /*error*/) {
  GetOperationState(isolate_credential, session_id, operation_state, result);
}

uint32_t ChapsAdaptor::SetOperationState(
      const vector<uint8_t>& isolate_credential,
      const uint64_t& session_id,
      const vector<uint8_t>& operation_state,
      const uint64_t& encryption_key_handle,
      const uint64_t& authentication_key_handle) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->SetOperationState(isolate_credential_blob,
                                     session_id,
                                     operation_state,
                                     encryption_key_handle,
                                     authentication_key_handle);
}

uint32_t ChapsAdaptor::SetOperationState(
      const vector<uint8_t>& isolate_credential,
      const uint64_t& session_id,
      const vector<uint8_t>& operation_state,
      const uint64_t& encryption_key_handle,
      const uint64_t& authentication_key_handle,
      ::DBus::Error& /*error*/) {
  return SetOperationState(isolate_credential, session_id, operation_state,
                           encryption_key_handle, authentication_key_handle);
}

uint32_t ChapsAdaptor::Login(const vector<uint8_t>& isolate_credential,
                             const uint64_t& session_id,
                             const uint64_t& user_type,
                             const bool& use_null_pin,
                             const string& optional_pin) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "user_type=" << user_type;
  VLOG(2) << "IN: " << "use_null_pin=" << use_null_pin;
  const string* pin = use_null_pin ? NULL : &optional_pin;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->Login(isolate_credential_blob,
                         session_id,
                         user_type,
                         pin);
}

uint32_t ChapsAdaptor::Login(const vector<uint8_t>& isolate_credential,
                             const uint64_t& session_id,
                             const uint64_t& user_type,
                             const bool& use_null_pin,
                             const string& optional_pin,
                             ::DBus::Error& /*error*/) {
  return Login(isolate_credential, session_id, user_type, use_null_pin,
               optional_pin);
}

uint32_t ChapsAdaptor::Logout(const vector<uint8_t>& isolate_credential,
                              const uint64_t& session_id) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->Logout(isolate_credential_blob,
                          session_id);
}

uint32_t ChapsAdaptor::Logout(const vector<uint8_t>& isolate_credential,
                              const uint64_t& session_id,
                              ::DBus::Error& /*error*/) {
  return Logout(isolate_credential, session_id);
}

void ChapsAdaptor::CreateObject(
      const vector<uint8_t>& isolate_credential,
      const uint64_t& session_id,
      const vector<uint8_t>& attributes,
      uint64_t& new_object_handle,  // NOLINT(runtime/references)
      uint32_t& result) {  // NOLINT(runtime/references)
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "attributes=" << PrintAttributes(attributes, true);
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->CreateObject(isolate_credential_blob,
                                  session_id,
                                  attributes,
                                  &new_object_handle);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "new_object_handle="
                               << new_object_handle;
}

void ChapsAdaptor::CreateObject(
      const vector<uint8_t>& isolate_credential,
      const uint64_t& session_id,
      const vector<uint8_t>& attributes,
      uint64_t& new_object_handle,  // NOLINT(runtime/references)
      uint32_t& result,  // NOLINT(runtime/references)
      ::DBus::Error& /*error*/) {
  CreateObject(isolate_credential, session_id, attributes, new_object_handle,
               result);
}

void ChapsAdaptor::CopyObject(
      const vector<uint8_t>& isolate_credential,
      const uint64_t& session_id,
      const uint64_t& object_handle,
      const vector<uint8_t>& attributes,
      uint64_t& new_object_handle,  // NOLINT(runtime/references)
      uint32_t& result) {  // NOLINT(runtime/references)
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "object_handle=" << object_handle;
  VLOG(2) << "IN: " << "attributes=" << PrintAttributes(attributes, true);
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->CopyObject(isolate_credential_blob,
                                session_id,
                                object_handle,
                                attributes,
                                &new_object_handle);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "new_object_handle="
                               << new_object_handle;
}

void ChapsAdaptor::CopyObject(
      const vector<uint8_t>& isolate_credential,
      const uint64_t& session_id,
      const uint64_t& object_handle,
      const vector<uint8_t>& attributes,
      uint64_t& new_object_handle,  // NOLINT(runtime/references)
      uint32_t& result,  // NOLINT(runtime/references)
      ::DBus::Error& /*error*/) {
  CopyObject(isolate_credential, session_id, object_handle, attributes,
             new_object_handle, result);
}

uint32_t ChapsAdaptor::DestroyObject(const vector<uint8_t>& isolate_credential,
                                     const uint64_t& session_id,
                                     const uint64_t& object_handle) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "object_handle=" << object_handle;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->DestroyObject(isolate_credential_blob,
                                 session_id,
                                 object_handle);
}

uint32_t ChapsAdaptor::DestroyObject(const vector<uint8_t>& isolate_credential,
                                     const uint64_t& session_id,
                                     const uint64_t& object_handle,
                                     ::DBus::Error& /*error*/) {
  return DestroyObject(isolate_credential, session_id, object_handle);
}

void ChapsAdaptor::GetObjectSize(const vector<uint8_t>& isolate_credential,
                                 const uint64_t& session_id,
                                 const uint64_t& object_handle,
                                 uint64_t& object_size,  // NOLINT - refs
                                 uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "object_handle=" << object_handle;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->GetObjectSize(isolate_credential_blob,
                                   session_id,
                                   object_handle,
                                   &object_size);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "object_size=" << object_size;
}

void ChapsAdaptor::GetObjectSize(const vector<uint8_t>& isolate_credential,
                                 const uint64_t& session_id,
                                 const uint64_t& object_handle,
                                 uint64_t& object_size,  // NOLINT - refs
                                 uint32_t& result,  // NOLINT - refs
                                 ::DBus::Error& /*error*/) {
  GetObjectSize(isolate_credential, session_id, object_handle, object_size,
                result);
}

void ChapsAdaptor::GetAttributeValue(const vector<uint8_t>& isolate_credential,
                                     const uint64_t& session_id,
                                     const uint64_t& object_handle,
                                     const vector<uint8_t>& attributes_in,
                                     vector<uint8_t>& attributes_out,  // NOLINT - refs
                                     uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "object_handle=" << object_handle;
  VLOG(2) << "IN: " << "attributes_in="
                    << PrintAttributes(attributes_in, false);
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->GetAttributeValue(isolate_credential_blob,
                                       session_id,
                                       object_handle,
                                       attributes_in,
                                       &attributes_out);
  VLOG_IF(2, result == CKR_OK || result == CKR_ATTRIBUTE_TYPE_INVALID)
      << "OUT: " << "attributes_out=" << PrintAttributes(attributes_out, true);
}

void ChapsAdaptor::GetAttributeValue(const vector<uint8_t>& isolate_credential,
                                     const uint64_t& session_id,
                                     const uint64_t& object_handle,
                                     const vector<uint8_t>& attributes_in,
                                     vector<uint8_t>& attributes_out,  // NOLINT - refs
                                     uint32_t& result,  // NOLINT - refs
                                     ::DBus::Error& /*error*/) {
  GetAttributeValue(isolate_credential, session_id, object_handle,
                    attributes_in, attributes_out, result);
}

uint32_t ChapsAdaptor::SetAttributeValue(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    const uint64_t& object_handle,
    const vector<uint8_t>& attributes) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "object_handle=" << object_handle;
  VLOG(2) << "IN: " << "attributes=" << PrintAttributes(attributes, true);
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->SetAttributeValue(isolate_credential_blob,
                                     session_id,
                                     object_handle,
                                     attributes);
}

uint32_t ChapsAdaptor::SetAttributeValue(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    const uint64_t& object_handle,
    const vector<uint8_t>& attributes,
    ::DBus::Error& /*error*/) {
  return SetAttributeValue(isolate_credential, session_id, object_handle,
                           attributes);
}

uint32_t ChapsAdaptor::FindObjectsInit(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    const vector<uint8_t>& attributes) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "attributes=" << PrintAttributes(attributes, true);
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->FindObjectsInit(isolate_credential_blob,
                                   session_id,
                                   attributes);
}

uint32_t ChapsAdaptor::FindObjectsInit(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    const vector<uint8_t>& attributes,
    ::DBus::Error& /*error*/) {
  return FindObjectsInit(isolate_credential, session_id, attributes);
}

void ChapsAdaptor::FindObjects(const vector<uint8_t>& isolate_credential,
                               const uint64_t& session_id,
                               const uint64_t& max_object_count,
                               vector<uint64_t>& object_list,  // NOLINT - refs
                               uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "max_object_count=" << max_object_count;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->FindObjects(isolate_credential_blob,
                                 session_id,
                                 max_object_count,
                                 &object_list);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "object_list="
                               << PrintIntVector(object_list);
}

void ChapsAdaptor::FindObjects(const vector<uint8_t>& isolate_credential,
                               const uint64_t& session_id,
                               const uint64_t& max_object_count,
                               vector<uint64_t>& object_list,  // NOLINT - refs
                               uint32_t& result,  // NOLINT - refs
                               ::DBus::Error& /*error*/) {
  FindObjects(isolate_credential, session_id, max_object_count, object_list,
              result);
}

uint32_t ChapsAdaptor::FindObjectsFinal(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->FindObjectsFinal(isolate_credential_blob, session_id);
}

uint32_t ChapsAdaptor::FindObjectsFinal(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    ::DBus::Error& /*error*/) {
  return FindObjectsFinal(isolate_credential, session_id);
}

uint32_t ChapsAdaptor::EncryptInit(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    const uint64_t& mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    const uint64_t& key_handle) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "mechanism_type=" << mechanism_type;
  VLOG(2) << "IN: " << "mechanism_parameter="
          << PrintIntVector(mechanism_parameter);
  VLOG(2) << "IN: " << "key_handle=" << key_handle;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->EncryptInit(isolate_credential_blob,
                               session_id,
                               mechanism_type,
                               mechanism_parameter,
                               key_handle);
}

uint32_t ChapsAdaptor::EncryptInit(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    const uint64_t& mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    const uint64_t& key_handle,
    ::DBus::Error& /*error*/) {
  return EncryptInit(isolate_credential, session_id, mechanism_type,
                     mechanism_parameter, key_handle);
}

void ChapsAdaptor::Encrypt(const vector<uint8_t>& isolate_credential,
                           const uint64_t& session_id,
                           const vector<uint8_t>& data_in,
                           const uint64_t& max_out_length,
                           uint64_t& actual_out_length,  // NOLINT - refs
                           vector<uint8_t>& data_out,  // NOLINT - refs
                           uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "max_out_length=" << max_out_length;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->Encrypt(isolate_credential_blob,
                             session_id,
                             data_in,
                             max_out_length,
                             &actual_out_length,
                             &data_out);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "actual_out_length="
                               << actual_out_length;
}

void ChapsAdaptor::Encrypt(const vector<uint8_t>& isolate_credential,
                           const uint64_t& session_id,
                           const vector<uint8_t>& data_in,
                           const uint64_t& max_out_length,
                           uint64_t& actual_out_length,  // NOLINT - refs
                           vector<uint8_t>& data_out,  // NOLINT - refs
                           uint32_t& result,  // NOLINT - refs
                           ::DBus::Error& /*error*/) {
  Encrypt(isolate_credential, session_id, data_in, max_out_length,
          actual_out_length, data_out, result);
}

void ChapsAdaptor::EncryptUpdate(const vector<uint8_t>& isolate_credential,
                                 const uint64_t& session_id,
                                 const vector<uint8_t>& data_in,
                                 const uint64_t& max_out_length,
                                 uint64_t& actual_out_length,  // NOLINT - refs
                                 vector<uint8_t>& data_out,  // NOLINT - refs
                                 uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "max_out_length=" << max_out_length;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->EncryptUpdate(isolate_credential_blob,
                                   session_id,
                                   data_in,
                                   max_out_length,
                                   &actual_out_length,
                                   &data_out);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "actual_out_length="
                               << actual_out_length;
}

void ChapsAdaptor::EncryptUpdate(const vector<uint8_t>& isolate_credential,
                                 const uint64_t& session_id,
                                 const vector<uint8_t>& data_in,
                                 const uint64_t& max_out_length,
                                 uint64_t& actual_out_length,  // NOLINT - refs
                                 vector<uint8_t>& data_out,  // NOLINT - refs
                                 uint32_t& result,  // NOLINT - refs
                                 ::DBus::Error& /*error*/) {
  EncryptUpdate(isolate_credential, session_id, data_in, max_out_length,
                actual_out_length, data_out, result);
}

void ChapsAdaptor::EncryptFinal(const vector<uint8_t>& isolate_credential,
                                const uint64_t& session_id,
                                const uint64_t& max_out_length,
                                uint64_t& actual_out_length,  // NOLINT - refs
                                vector<uint8_t>& data_out,  // NOLINT - refs
                                uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "max_out_length=" << max_out_length;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->EncryptFinal(isolate_credential_blob,
                                  session_id,
                                  max_out_length,
                                  &actual_out_length,
                                  &data_out);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "actual_out_length="
                               << actual_out_length;
}

void ChapsAdaptor::EncryptFinal(const vector<uint8_t>& isolate_credential,
                                const uint64_t& session_id,
                                const uint64_t& max_out_length,
                                uint64_t& actual_out_length,  // NOLINT - refs
                                vector<uint8_t>& data_out,  // NOLINT - refs
                                uint32_t& result,  // NOLINT - refs
                                ::DBus::Error& /*error*/) {
  EncryptFinal(isolate_credential, session_id, max_out_length,
               actual_out_length, data_out, result);
}

void ChapsAdaptor::EncryptCancel(const vector<uint8_t>& isolate_credential,
                                 const uint64_t& session_id) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  service_->EncryptCancel(isolate_credential_blob, session_id);
}

void ChapsAdaptor::EncryptCancel(const vector<uint8_t>& isolate_credential,
                                 const uint64_t& session_id,
                                 ::DBus::Error& /*error*/) {
  EncryptCancel(isolate_credential, session_id);
}

uint32_t ChapsAdaptor::DecryptInit(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    const uint64_t& mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    const uint64_t& key_handle) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "mechanism_type=" << mechanism_type;
  VLOG(2) << "IN: " << "mechanism_parameter="
          << PrintIntVector(mechanism_parameter);
  VLOG(2) << "IN: " << "key_handle=" << key_handle;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->DecryptInit(isolate_credential_blob,
                               session_id,
                               mechanism_type,
                               mechanism_parameter,
                               key_handle);
}

uint32_t ChapsAdaptor::DecryptInit(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    const uint64_t& mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    const uint64_t& key_handle,
    ::DBus::Error& /*error*/) {
  return DecryptInit(isolate_credential, session_id, mechanism_type,
                     mechanism_parameter, key_handle);
}

void ChapsAdaptor::Decrypt(const vector<uint8_t>& isolate_credential,
                           const uint64_t& session_id,
                           const vector<uint8_t>& data_in,
                           const uint64_t& max_out_length,
                           uint64_t& actual_out_length,  // NOLINT - refs
                           vector<uint8_t>& data_out,  // NOLINT - refs
                           uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "max_out_length=" << max_out_length;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->Decrypt(isolate_credential_blob,
                             session_id,
                             data_in,
                             max_out_length,
                             &actual_out_length,
                             &data_out);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "actual_out_length="
                               << actual_out_length;
}

void ChapsAdaptor::Decrypt(const vector<uint8_t>& isolate_credential,
                           const uint64_t& session_id,
                           const vector<uint8_t>& data_in,
                           const uint64_t& max_out_length,
                           uint64_t& actual_out_length,  // NOLINT - refs
                           vector<uint8_t>& data_out,  // NOLINT - refs
                           uint32_t& result,  // NOLINT - refs
                           ::DBus::Error& /*error*/) {
  Decrypt(isolate_credential, session_id, data_in, max_out_length,
          actual_out_length, data_out, result);
}

void ChapsAdaptor::DecryptUpdate(const vector<uint8_t>& isolate_credential,
                                 const uint64_t& session_id,
                                 const vector<uint8_t>& data_in,
                                 const uint64_t& max_out_length,
                                 uint64_t& actual_out_length,  // NOLINT - refs
                                 vector<uint8_t>& data_out,  // NOLINT - refs
                                 uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "max_out_length=" << max_out_length;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->DecryptUpdate(isolate_credential_blob,
                                   session_id,
                                   data_in,
                                   max_out_length,
                                   &actual_out_length,
                                   &data_out);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "actual_out_length="
                               << actual_out_length;
}

void ChapsAdaptor::DecryptUpdate(const vector<uint8_t>& isolate_credential,
                                 const uint64_t& session_id,
                                 const vector<uint8_t>& data_in,
                                 const uint64_t& max_out_length,
                                 uint64_t& actual_out_length,  // NOLINT - refs
                                 vector<uint8_t>& data_out,  // NOLINT - refs
                                 uint32_t& result,  // NOLINT - refs
                                 ::DBus::Error& /*error*/) {
  DecryptUpdate(isolate_credential, session_id, data_in, max_out_length,
                actual_out_length, data_out, result);
}

void ChapsAdaptor::DecryptFinal(const vector<uint8_t>& isolate_credential,
                                const uint64_t& session_id,
                                const uint64_t& max_out_length,
                                uint64_t& actual_out_length,  // NOLINT - refs
                                vector<uint8_t>& data_out,  // NOLINT - refs
                                uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "max_out_length=" << max_out_length;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->DecryptFinal(isolate_credential_blob,
                                  session_id,
                                  max_out_length,
                                  &actual_out_length,
                                  &data_out);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "actual_out_length="
                               << actual_out_length;
}

void ChapsAdaptor::DecryptFinal(const vector<uint8_t>& isolate_credential,
                                const uint64_t& session_id,
                                const uint64_t& max_out_length,
                                uint64_t& actual_out_length,  // NOLINT - refs
                                vector<uint8_t>& data_out,  // NOLINT - refs
                                uint32_t& result,  // NOLINT - refs
                                ::DBus::Error& /*error*/) {
  DecryptFinal(isolate_credential, session_id, max_out_length,
               actual_out_length, data_out, result);
}

void ChapsAdaptor::DecryptCancel(const vector<uint8_t>& isolate_credential,
                                 const uint64_t& session_id) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  service_->DecryptCancel(isolate_credential_blob, session_id);
}

void ChapsAdaptor::DecryptCancel(const vector<uint8_t>& isolate_credential,
                                 const uint64_t& session_id,
                                 ::DBus::Error& /*error*/) {
  DecryptCancel(isolate_credential, session_id);
}

uint32_t ChapsAdaptor::DigestInit(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    const uint64_t& mechanism_type,
    const vector<uint8_t>& mechanism_parameter) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "mechanism_type=" << mechanism_type;
  VLOG(2) << "IN: " << "mechanism_parameter="
          << PrintIntVector(mechanism_parameter);
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->DigestInit(isolate_credential_blob,
                              session_id,
                              mechanism_type,
                              mechanism_parameter);
}

uint32_t ChapsAdaptor::DigestInit(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    const uint64_t& mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    ::DBus::Error& /*error*/) {
  return DigestInit(isolate_credential, session_id, mechanism_type,
                    mechanism_parameter);
}

void ChapsAdaptor::Digest(const vector<uint8_t>& isolate_credential,
                          const uint64_t& session_id,
                          const vector<uint8_t>& data_in,
                          const uint64_t& max_out_length,
                          uint64_t& actual_out_length,  // NOLINT - refs
                          vector<uint8_t>& digest,  // NOLINT - refs
                          uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "max_out_length=" << max_out_length;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->Digest(isolate_credential_blob,
                            session_id,
                            data_in,
                            max_out_length,
                            &actual_out_length,
                            &digest);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "actual_out_length="
                               << actual_out_length;
}

void ChapsAdaptor::Digest(const vector<uint8_t>& isolate_credential,
                          const uint64_t& session_id,
                          const vector<uint8_t>& data_in,
                          const uint64_t& max_out_length,
                          uint64_t& actual_out_length,  // NOLINT - refs
                          vector<uint8_t>& digest,  // NOLINT - refs
                          uint32_t& result,  // NOLINT - refs
                          ::DBus::Error& /*error*/) {
  Digest(isolate_credential, session_id, data_in, max_out_length,
         actual_out_length, digest, result);
}

uint32_t ChapsAdaptor::DigestUpdate(const vector<uint8_t>& isolate_credential,
                                    const uint64_t& session_id,
                                    const vector<uint8_t>& data_in) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->DigestUpdate(isolate_credential_blob,
                                session_id,
                                data_in);
}

uint32_t ChapsAdaptor::DigestUpdate(const vector<uint8_t>& isolate_credential,
                                    const uint64_t& session_id,
                                    const vector<uint8_t>& data_in,
                                    ::DBus::Error& /*error*/) {
  return DigestUpdate(isolate_credential, session_id, data_in);
}

uint32_t ChapsAdaptor::DigestKey(const vector<uint8_t>& isolate_credential,
                                 const uint64_t& session_id,
                                 const uint64_t& key_handle) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "key_handle=" << key_handle;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->DigestKey(isolate_credential_blob,
                             session_id,
                             key_handle);
}

uint32_t ChapsAdaptor::DigestKey(const vector<uint8_t>& isolate_credential,
                                 const uint64_t& session_id,
                                 const uint64_t& key_handle,
                                 ::DBus::Error& /*error*/) {
  return DigestKey(isolate_credential, session_id, key_handle);
}


void ChapsAdaptor::DigestFinal(const vector<uint8_t>& isolate_credential,
                               const uint64_t& session_id,
                               const uint64_t& max_out_length,
                               uint64_t& actual_out_length,  // NOLINT - refs
                               vector<uint8_t>& digest,  // NOLINT - refs
                               uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "max_out_length=" << max_out_length;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->DigestFinal(isolate_credential_blob,
                                 session_id,
                                 max_out_length,
                                 &actual_out_length,
                                 &digest);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "actual_out_length="
                               << actual_out_length;
}

void ChapsAdaptor::DigestFinal(const vector<uint8_t>& isolate_credential,
                               const uint64_t& session_id,
                               const uint64_t& max_out_length,
                               uint64_t& actual_out_length,  // NOLINT - refs
                               vector<uint8_t>& digest,  // NOLINT - refs
                               uint32_t& result,  // NOLINT - refs
                               ::DBus::Error& /*error*/) {
  DigestFinal(isolate_credential, session_id, max_out_length, actual_out_length,
              digest, result);
}

void ChapsAdaptor::DigestCancel(const vector<uint8_t>& isolate_credential,
                                const uint64_t& session_id) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  service_->DigestCancel(isolate_credential_blob, session_id);
}

void ChapsAdaptor::DigestCancel(const vector<uint8_t>& isolate_credential,
                                const uint64_t& session_id,
                                ::DBus::Error& /*error*/) {
  DigestCancel(isolate_credential, session_id);
}

uint32_t ChapsAdaptor::SignInit(const vector<uint8_t>& isolate_credential,
                                const uint64_t& session_id,
                                const uint64_t& mechanism_type,
                                const vector<uint8_t>& mechanism_parameter,
                                const uint64_t& key_handle) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "mechanism_type=" << mechanism_type;
  VLOG(2) << "IN: " << "mechanism_parameter="
          << PrintIntVector(mechanism_parameter);
  VLOG(2) << "IN: " << "key_handle=" << key_handle;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->SignInit(isolate_credential_blob,
                            session_id,
                            mechanism_type,
                            mechanism_parameter,
                            key_handle);
}

uint32_t ChapsAdaptor::SignInit(const vector<uint8_t>& isolate_credential,
                                const uint64_t& session_id,
                                const uint64_t& mechanism_type,
                                const vector<uint8_t>& mechanism_parameter,
                                const uint64_t& key_handle,
                                ::DBus::Error& /*error*/) {
  return SignInit(isolate_credential, session_id, mechanism_type,
                  mechanism_parameter, key_handle);
}

void ChapsAdaptor::Sign(const vector<uint8_t>& isolate_credential,
                        const uint64_t& session_id,
                        const vector<uint8_t>& data,
                        const uint64_t& max_out_length,
                        uint64_t& actual_out_length,  // NOLINT - refs
                        vector<uint8_t>& signature,  // NOLINT - refs
                        uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "max_out_length=" << max_out_length;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->Sign(isolate_credential_blob,
                          session_id,
                          data,
                          max_out_length,
                          &actual_out_length,
                          &signature);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "actual_out_length="
                               << actual_out_length;
}

void ChapsAdaptor::Sign(const vector<uint8_t>& isolate_credential,
                        const uint64_t& session_id,
                        const vector<uint8_t>& data,
                        const uint64_t& max_out_length,
                        uint64_t& actual_out_length,  // NOLINT - refs
                        vector<uint8_t>& signature,  // NOLINT - refs
                        uint32_t& result,  // NOLINT - refs
                        ::DBus::Error& /*error*/) {
  Sign(isolate_credential, session_id, data, max_out_length, actual_out_length,
       signature, result);
}

uint32_t ChapsAdaptor::SignUpdate(const vector<uint8_t>& isolate_credential,
                                  const uint64_t& session_id,
                                  const vector<uint8_t>& data_part) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->SignUpdate(isolate_credential_blob,
                              session_id,
                              data_part);
}

uint32_t ChapsAdaptor::SignUpdate(const vector<uint8_t>& isolate_credential,
                                  const uint64_t& session_id,
                                  const vector<uint8_t>& data_part,
                                  ::DBus::Error& /*error*/) {
  return SignUpdate(isolate_credential, session_id, data_part);
}

void ChapsAdaptor::SignFinal(const vector<uint8_t>& isolate_credential,
                             const uint64_t& session_id,
                             const uint64_t& max_out_length,
                             uint64_t& actual_out_length,  // NOLINT - refs
                             vector<uint8_t>& signature,  // NOLINT - refs
                             uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "max_out_length=" << max_out_length;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->SignFinal(isolate_credential_blob,
                               session_id,
                               max_out_length,
                               &actual_out_length,
                               &signature);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "actual_out_length="
                               << actual_out_length;
}

void ChapsAdaptor::SignFinal(const vector<uint8_t>& isolate_credential,
                             const uint64_t& session_id,
                             const uint64_t& max_out_length,
                             uint64_t& actual_out_length,  // NOLINT - refs
                             vector<uint8_t>& signature,  // NOLINT - refs
                             uint32_t& result,  // NOLINT - refs
                             ::DBus::Error& /*error*/) {
  SignFinal(isolate_credential, session_id, max_out_length, actual_out_length,
            signature, result);
}

void ChapsAdaptor::SignCancel(const vector<uint8_t>& isolate_credential,
                              const uint64_t& session_id) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  service_->SignCancel(isolate_credential_blob, session_id);
}

void ChapsAdaptor::SignCancel(const vector<uint8_t>& isolate_credential,
                              const uint64_t& session_id,
                              ::DBus::Error& /*error*/) {
  SignCancel(isolate_credential, session_id);
}

uint32_t ChapsAdaptor::SignRecoverInit(
      const vector<uint8_t>& isolate_credential,
      const uint64_t& session_id,
      const uint64_t& mechanism_type,
      const vector<uint8_t>& mechanism_parameter,
      const uint64_t& key_handle) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "mechanism_type=" << mechanism_type;
  VLOG(2) << "IN: " << "mechanism_parameter="
          << PrintIntVector(mechanism_parameter);
  VLOG(2) << "IN: " << "key_handle=" << key_handle;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->SignRecoverInit(isolate_credential_blob,
                                   session_id,
                                   mechanism_type,
                                   mechanism_parameter,
                                   key_handle);
}

uint32_t ChapsAdaptor::SignRecoverInit(
      const vector<uint8_t>& isolate_credential,
      const uint64_t& session_id,
      const uint64_t& mechanism_type,
      const vector<uint8_t>& mechanism_parameter,
      const uint64_t& key_handle,
      ::DBus::Error& /*error*/) {
  return SignRecoverInit(isolate_credential, session_id, mechanism_type,
                         mechanism_parameter, key_handle);
}

void ChapsAdaptor::SignRecover(const vector<uint8_t>& isolate_credential,
                               const uint64_t& session_id,
                               const vector<uint8_t>& data,
                               const uint64_t& max_out_length,
                               uint64_t& actual_out_length,  // NOLINT - refs
                               vector<uint8_t>& signature,  // NOLINT - refs
                               uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "max_out_length=" << max_out_length;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->SignRecover(isolate_credential_blob,
                                 session_id,
                                 data,
                                 max_out_length,
                                 &actual_out_length,
                                 &signature);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "actual_out_length="
                               << actual_out_length;
}

void ChapsAdaptor::SignRecover(const vector<uint8_t>& isolate_credential,
                               const uint64_t& session_id,
                               const vector<uint8_t>& data,
                               const uint64_t& max_out_length,
                               uint64_t& actual_out_length,  // NOLINT - refs
                               vector<uint8_t>& signature,  // NOLINT - refs
                               uint32_t& result,  // NOLINT - refs
                               ::DBus::Error& /*error*/) {
  SignRecover(isolate_credential, session_id, data, max_out_length,
              actual_out_length, signature, result);
}

uint32_t ChapsAdaptor::VerifyInit(const vector<uint8_t>& isolate_credential,
                                  const uint64_t& session_id,
                                  const uint64_t& mechanism_type,
                                  const vector<uint8_t>& mechanism_parameter,
                                  const uint64_t& key_handle) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "mechanism_type=" << mechanism_type;
  VLOG(2) << "IN: " << "mechanism_parameter="
          << PrintIntVector(mechanism_parameter);
  VLOG(2) << "IN: " << "key_handle=" << key_handle;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->VerifyInit(isolate_credential_blob,
                              session_id,
                              mechanism_type,
                              mechanism_parameter,
                              key_handle);
}

uint32_t ChapsAdaptor::VerifyInit(const vector<uint8_t>& isolate_credential,
                                  const uint64_t& session_id,
                                  const uint64_t& mechanism_type,
                                  const vector<uint8_t>& mechanism_parameter,
                                  const uint64_t& key_handle,
                                  ::DBus::Error& /*error*/) {
  return VerifyInit(isolate_credential, session_id, mechanism_type,
                    mechanism_parameter, key_handle);
}

uint32_t ChapsAdaptor::Verify(const vector<uint8_t>& isolate_credential,
                              const uint64_t& session_id,
                              const vector<uint8_t>& data,
                              const vector<uint8_t>& signature) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->Verify(isolate_credential_blob,
                          session_id,
                          data,
                          signature);
}

uint32_t ChapsAdaptor::Verify(const vector<uint8_t>& isolate_credential,
                              const uint64_t& session_id,
                              const vector<uint8_t>& data,
                              const vector<uint8_t>& signature,
                              ::DBus::Error& /*error*/) {
  return Verify(isolate_credential, session_id, data, signature);
}

uint32_t ChapsAdaptor::VerifyUpdate(const vector<uint8_t>& isolate_credential,
                                    const uint64_t& session_id,
                                    const vector<uint8_t>& data_part) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->VerifyUpdate(isolate_credential_blob,
                                session_id,
                                data_part);
}

uint32_t ChapsAdaptor::VerifyUpdate(const vector<uint8_t>& isolate_credential,
                                    const uint64_t& session_id,
                                    const vector<uint8_t>& data_part,
                                    ::DBus::Error& /*error*/) {
  return VerifyUpdate(isolate_credential, session_id, data_part);
}

uint32_t ChapsAdaptor::VerifyFinal(const vector<uint8_t>& isolate_credential,
                                   const uint64_t& session_id,
                                   const vector<uint8_t>& signature) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->VerifyFinal(isolate_credential_blob,
                               session_id,
                               signature);
}

uint32_t ChapsAdaptor::VerifyFinal(const vector<uint8_t>& isolate_credential,
                                   const uint64_t& session_id,
                                   const vector<uint8_t>& signature,
                                   ::DBus::Error& /*error*/) {
  return VerifyFinal(isolate_credential, session_id, signature);
}

void ChapsAdaptor::VerifyCancel(const vector<uint8_t>& isolate_credential,
                                const uint64_t& session_id) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  service_->VerifyCancel(isolate_credential_blob, session_id);
}

void ChapsAdaptor::VerifyCancel(const vector<uint8_t>& isolate_credential,
                                const uint64_t& session_id,
                                ::DBus::Error& /*error*/) {
  VerifyCancel(isolate_credential, session_id);
}


uint32_t ChapsAdaptor::VerifyRecoverInit(
      const vector<uint8_t>& isolate_credential,
      const uint64_t& session_id,
      const uint64_t& mechanism_type,
      const vector<uint8_t>& mechanism_parameter,
      const uint64_t& key_handle) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "mechanism_type=" << mechanism_type;
  VLOG(2) << "IN: " << "mechanism_parameter="
          << PrintIntVector(mechanism_parameter);
  VLOG(2) << "IN: " << "key_handle=" << key_handle;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->VerifyRecoverInit(isolate_credential_blob,
                                     session_id,
                                     mechanism_type,
                                     mechanism_parameter,
                                     key_handle);
}

uint32_t ChapsAdaptor::VerifyRecoverInit(
      const vector<uint8_t>& isolate_credential,
      const uint64_t& session_id,
      const uint64_t& mechanism_type,
      const vector<uint8_t>& mechanism_parameter,
      const uint64_t& key_handle,
      ::DBus::Error& /*error*/) {
  return VerifyRecoverInit(isolate_credential, session_id, mechanism_type,
                           mechanism_parameter, key_handle);
}

void ChapsAdaptor::VerifyRecover(const vector<uint8_t>& isolate_credential,
                                 const uint64_t& session_id,
                                 const vector<uint8_t>& signature,
                                 const uint64_t& max_out_length,
                                 uint64_t& actual_out_length,  // NOLINT - refs
                                 vector<uint8_t>& data,  // NOLINT - refs
                                 uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "max_out_length=" << max_out_length;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->VerifyRecover(isolate_credential_blob,
                                   session_id,
                                   signature,
                                   max_out_length,
                                   &actual_out_length,
                                   &data);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "actual_out_length="
                               << actual_out_length;
}

void ChapsAdaptor::VerifyRecover(const vector<uint8_t>& isolate_credential,
                                 const uint64_t& session_id,
                                 const vector<uint8_t>& signature,
                                 const uint64_t& max_out_length,
                                 uint64_t& actual_out_length,  // NOLINT - refs
                                 vector<uint8_t>& data,  // NOLINT - refs
                                 uint32_t& result,  // NOLINT - refs
                                 ::DBus::Error& /*error*/) {
  VerifyRecover(isolate_credential, session_id, signature, max_out_length,
                actual_out_length, data, result);
}

void ChapsAdaptor::DigestEncryptUpdate(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    const vector<uint8_t>& data_in,
    const uint64_t& max_out_length,
    uint64_t& actual_out_length,  // NOLINT - refs
    vector<uint8_t>& data_out,  // NOLINT - refs
    uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "max_out_length=" << max_out_length;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->DigestEncryptUpdate(isolate_credential_blob,
                                         session_id,
                                         data_in,
                                         max_out_length,
                                         &actual_out_length,
                                         &data_out);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "actual_out_length="
                               << actual_out_length;
}

void ChapsAdaptor::DigestEncryptUpdate(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    const vector<uint8_t>& data_in,
    const uint64_t& max_out_length,
    uint64_t& actual_out_length,  // NOLINT - refs
    vector<uint8_t>& data_out,  // NOLINT - refs
    uint32_t& result,  // NOLINT - refs
    ::DBus::Error& /*error*/) {
  DigestEncryptUpdate(isolate_credential, session_id, data_in, max_out_length,
                      actual_out_length, data_out, result);
}

void ChapsAdaptor::DecryptDigestUpdate(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    const vector<uint8_t>& data_in,
    const uint64_t& max_out_length,
    uint64_t& actual_out_length,  // NOLINT - refs
    vector<uint8_t>& data_out,  // NOLINT - refs
    uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "max_out_length=" << max_out_length;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->DecryptDigestUpdate(isolate_credential_blob,
                                         session_id,
                                         data_in,
                                         max_out_length,
                                         &actual_out_length,
                                         &data_out);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "actual_out_length="
                               << actual_out_length;
}

void ChapsAdaptor::DecryptDigestUpdate(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    const vector<uint8_t>& data_in,
    const uint64_t& max_out_length,
    uint64_t& actual_out_length,  // NOLINT - refs
    vector<uint8_t>& data_out,  // NOLINT - refs
    uint32_t& result,  // NOLINT - refs
    ::DBus::Error& /*error*/) {
  DecryptDigestUpdate(isolate_credential, session_id, data_in, max_out_length,
                      actual_out_length, data_out, result);
}

void ChapsAdaptor::SignEncryptUpdate(const vector<uint8_t>& isolate_credential,
                                     const uint64_t& session_id,
                                     const vector<uint8_t>& data_in,
                                     const uint64_t& max_out_length,
                                     uint64_t& actual_out_length,  // NOLINT - refs
                                     vector<uint8_t>& data_out,  // NOLINT - refs
                                     uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "max_out_length=" << max_out_length;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->SignEncryptUpdate(isolate_credential_blob,
                                       session_id,
                                       data_in,
                                       max_out_length,
                                       &actual_out_length,
                                       &data_out);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "actual_out_length="
                               << actual_out_length;
}

void ChapsAdaptor::SignEncryptUpdate(const vector<uint8_t>& isolate_credential,
                                     const uint64_t& session_id,
                                     const vector<uint8_t>& data_in,
                                     const uint64_t& max_out_length,
                                     uint64_t& actual_out_length,  // NOLINT - refs
                                     vector<uint8_t>& data_out,  // NOLINT - refs
                                     uint32_t& result,  // NOLINT - refs
                                     ::DBus::Error& /*error*/) {
  SignEncryptUpdate(isolate_credential, session_id, data_in, max_out_length,
                    actual_out_length, data_out, result);
}

void ChapsAdaptor::DecryptVerifyUpdate(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    const vector<uint8_t>& data_in,
    const uint64_t& max_out_length,
    uint64_t& actual_out_length,  // NOLINT - refs
    vector<uint8_t>& data_out,  // NOLINT - refs
    uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "max_out_length=" << max_out_length;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->DecryptVerifyUpdate(isolate_credential_blob,
                                         session_id,
                                         data_in,
                                         max_out_length,
                                         &actual_out_length,
                                         &data_out);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "actual_out_length="
                               << actual_out_length;
}

void ChapsAdaptor::DecryptVerifyUpdate(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    const vector<uint8_t>& data_in,
    const uint64_t& max_out_length,
    uint64_t& actual_out_length,  // NOLINT - refs
    vector<uint8_t>& data_out,  // NOLINT - refs
    uint32_t& result,  // NOLINT - refs
    ::DBus::Error& /*error*/) {
  DecryptVerifyUpdate(isolate_credential, session_id, data_in, max_out_length,
                      actual_out_length, data_out, result);
}

void ChapsAdaptor::GenerateKey(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    const uint64_t& mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    const vector<uint8_t>& attributes,
    uint64_t& key_handle,  // NOLINT - refs
    uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "mechanism_type=" << mechanism_type;
  VLOG(2) << "IN: " << "mechanism_parameter="
          << PrintIntVector(mechanism_parameter);
  VLOG(2) << "IN: " << "attributes=" << PrintAttributes(attributes, true);
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->GenerateKey(isolate_credential_blob,
                                 session_id,
                                 mechanism_type,
                                 mechanism_parameter,
                                 attributes,
                                 &key_handle);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "key_handle=" << key_handle;
}

void ChapsAdaptor::GenerateKey(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    const uint64_t& mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    const vector<uint8_t>& attributes,
    uint64_t& key_handle,  // NOLINT - refs
    uint32_t& result,  // NOLINT - refs
    ::DBus::Error& /*error*/) {
  GenerateKey(isolate_credential, session_id, mechanism_type,
              mechanism_parameter, attributes, key_handle, result);
}

void ChapsAdaptor::GenerateKeyPair(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    const uint64_t& mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    const vector<uint8_t>& public_attributes,
    const vector<uint8_t>& private_attributes,
    uint64_t& public_key_handle,  // NOLINT - refs
    uint64_t& private_key_handle,  // NOLINT - refs
    uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "mechanism_type=" << mechanism_type;
  VLOG(2) << "IN: " << "mechanism_parameter="
          << PrintIntVector(mechanism_parameter);
  VLOG(2) << "IN: " << "public_attributes="
          << PrintAttributes(public_attributes, true);
  VLOG(2) << "IN: " << "private_attributes="
          << PrintAttributes(private_attributes, true);
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->GenerateKeyPair(isolate_credential_blob,
                                     session_id,
                                     mechanism_type,
                                     mechanism_parameter,
                                     public_attributes,
                                     private_attributes,
                                     &public_key_handle,
                                     &private_key_handle);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "public_key_handle="
                               << public_key_handle;
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "private_key_handle="
                               << private_key_handle;
}

void ChapsAdaptor::GenerateKeyPair(
    const vector<uint8_t>& isolate_credential,
    const uint64_t& session_id,
    const uint64_t& mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    const vector<uint8_t>& public_attributes,
    const vector<uint8_t>& private_attributes,
    uint64_t& public_key_handle,  // NOLINT - refs
    uint64_t& private_key_handle,  // NOLINT - refs
    uint32_t& result,  // NOLINT - refs
    ::DBus::Error& /*error*/) {
  GenerateKeyPair(isolate_credential, session_id, mechanism_type,
                  mechanism_parameter, public_attributes, private_attributes,
                  public_key_handle, private_key_handle, result);
}

void ChapsAdaptor::WrapKey(const vector<uint8_t>& isolate_credential,
                           const uint64_t& session_id,
                           const uint64_t& mechanism_type,
                           const vector<uint8_t>& mechanism_parameter,
                           const uint64_t& wrapping_key_handle,
                           const uint64_t& key_handle,
                           const uint64_t& max_out_length,
                           uint64_t& actual_out_length,  // NOLINT - refs
                           vector<uint8_t>& wrapped_key,  // NOLINT - refs
                           uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "mechanism_type=" << mechanism_type;
  VLOG(2) << "IN: " << "mechanism_parameter="
          << PrintIntVector(mechanism_parameter);
  VLOG(2) << "IN: " << "wrapping_key_handle=" << wrapping_key_handle;
  VLOG(2) << "IN: " << "key_handle=" << key_handle;
  VLOG(2) << "IN: " << "max_out_length=" << max_out_length;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->WrapKey(isolate_credential_blob,
                             session_id,
                             mechanism_type,
                             mechanism_parameter,
                             wrapping_key_handle,
                             key_handle,
                             max_out_length,
                             &actual_out_length,
                             &wrapped_key);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "actual_out_length="
                               << actual_out_length;
}

void ChapsAdaptor::WrapKey(const vector<uint8_t>& isolate_credential,
                           const uint64_t& session_id,
                           const uint64_t& mechanism_type,
                           const vector<uint8_t>& mechanism_parameter,
                           const uint64_t& wrapping_key_handle,
                           const uint64_t& key_handle,
                           const uint64_t& max_out_length,
                           uint64_t& actual_out_length,  // NOLINT - refs
                           vector<uint8_t>& wrapped_key,  // NOLINT - refs
                           uint32_t& result,  // NOLINT - refs
                           ::DBus::Error& /*error*/) {
  WrapKey(isolate_credential, session_id, mechanism_type, mechanism_parameter,
          wrapping_key_handle, key_handle,  max_out_length, actual_out_length,
          wrapped_key, result);
}

void ChapsAdaptor::UnwrapKey(const vector<uint8_t>& isolate_credential,
                             const uint64_t& session_id,
                             const uint64_t& mechanism_type,
                             const vector<uint8_t>& mechanism_parameter,
                             const uint64_t& wrapping_key_handle,
                             const vector<uint8_t>& wrapped_key,
                             const vector<uint8_t>& attributes,
                             uint64_t& key_handle,  // NOLINT - refs
                             uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "mechanism_type=" << mechanism_type;
  VLOG(2) << "IN: " << "mechanism_parameter="
          << PrintIntVector(mechanism_parameter);
  VLOG(2) << "IN: " << "wrapping_key_handle=" << wrapping_key_handle;
  VLOG(2) << "IN: " << "attributes=" << PrintAttributes(attributes, true);
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->UnwrapKey(isolate_credential_blob,
                               session_id,
                               mechanism_type,
                               mechanism_parameter,
                               wrapping_key_handle,
                               wrapped_key,
                               attributes,
                               &key_handle);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "key_handle=" << key_handle;
}

void ChapsAdaptor::UnwrapKey(const vector<uint8_t>& isolate_credential,
                             const uint64_t& session_id,
                             const uint64_t& mechanism_type,
                             const vector<uint8_t>& mechanism_parameter,
                             const uint64_t& wrapping_key_handle,
                             const vector<uint8_t>& wrapped_key,
                             const vector<uint8_t>& attributes,
                             uint64_t& key_handle,  // NOLINT - refs
                             uint32_t& result,  // NOLINT - refs
                             ::DBus::Error& /*error*/) {
  UnwrapKey(isolate_credential, session_id, mechanism_type, mechanism_parameter,
            wrapping_key_handle, wrapped_key, attributes, key_handle, result);
}

void ChapsAdaptor::DeriveKey(const vector<uint8_t>& isolate_credential,
                             const uint64_t& session_id,
                             const uint64_t& mechanism_type,
                             const vector<uint8_t>& mechanism_parameter,
                             const uint64_t& base_key_handle,
                             const vector<uint8_t>& attributes,
                             uint64_t& key_handle,  // NOLINT - refs
                             uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "mechanism_type=" << mechanism_type;
  VLOG(2) << "IN: " << "mechanism_parameter="
          << PrintIntVector(mechanism_parameter);
  VLOG(2) << "IN: " << "base_key_handle=" << base_key_handle;
  VLOG(2) << "IN: " << "attributes=" << PrintAttributes(attributes, true);
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->DeriveKey(isolate_credential_blob,
                               session_id,
                               mechanism_type,
                               mechanism_parameter,
                               base_key_handle,
                               attributes,
                               &key_handle);
  VLOG_IF(2, result == CKR_OK) << "OUT: " << "key_handle=" << key_handle;
}

void ChapsAdaptor::DeriveKey(const vector<uint8_t>& isolate_credential,
                             const uint64_t& session_id,
                             const uint64_t& mechanism_type,
                             const vector<uint8_t>& mechanism_parameter,
                             const uint64_t& base_key_handle,
                             const vector<uint8_t>& attributes,
                             uint64_t& key_handle,  // NOLINT - refs
                             uint32_t& result,  // NOLINT - refs
                             ::DBus::Error& /*error*/) {
  DeriveKey(isolate_credential, session_id, mechanism_type, mechanism_parameter,
            base_key_handle, attributes, key_handle, result);
}

uint32_t ChapsAdaptor::SeedRandom(const vector<uint8_t>& isolate_credential,
                                  const uint64_t& session_id,
                                  const vector<uint8_t>& seed) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "num_bytes=" << seed.size();
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  return service_->SeedRandom(isolate_credential_blob,
                              session_id,
                              seed);
}

uint32_t ChapsAdaptor::SeedRandom(const vector<uint8_t>& isolate_credential,
                                  const uint64_t& session_id,
                                  const vector<uint8_t>& seed,
                                  ::DBus::Error& /*error*/) {
  return SeedRandom(isolate_credential, session_id, seed);
}

void ChapsAdaptor::GenerateRandom(const vector<uint8_t>& isolate_credential,
                                  const uint64_t& session_id,
                                  const uint64_t& num_bytes,
                                  vector<uint8_t>& random_data,  // NOLINT - refs
                                  uint32_t& result) {  // NOLINT - refs
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: " << "session_id=" << session_id;
  VLOG(2) << "IN: " << "num_bytes=" << num_bytes;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  ClearVector(const_cast<vector<uint8_t>*>(&isolate_credential));
  result = service_->GenerateRandom(isolate_credential_blob,
                                    session_id,
                                    num_bytes,
                                    &random_data);
}

void ChapsAdaptor::GenerateRandom(const vector<uint8_t>& isolate_credential,
                                  const uint64_t& session_id,
                                  const uint64_t& num_bytes,
                                  vector<uint8_t>& random_data,  // NOLINT - refs
                                  uint32_t& result,  // NOLINT - refs
                                  ::DBus::Error& /*error*/) {
  GenerateRandom(isolate_credential, session_id, num_bytes, random_data,
                 result);
}

}  // namespace chaps
