// 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/files/file_util.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/synchronization/lock.h>
#include <dbus/object_path.h>

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

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

namespace chaps {

ChapsAdaptor::ChapsAdaptor(scoped_refptr<dbus::Bus> bus,
                           Lock* lock,
                           ChapsInterface* service,
                           TokenManagerInterface* token_manager)
    : dbus_object_(nullptr, bus, dbus::ObjectPath(kChapsServicePath)),
      lock_(lock),
      service_(service),
      token_manager_(token_manager) {}

ChapsAdaptor::~ChapsAdaptor() {}

void ChapsAdaptor::RegisterAsync(
    const brillo::dbus_utils::AsyncEventSequencer::CompletionAction& cb) {
  brillo::dbus_utils::DBusInterface* interface =
      dbus_object_.AddOrGetInterface(kChapsInterface);
  interface->AddSimpleMethodHandler(kOpenIsolateMethod, base::Unretained(this),
                                    &ChapsAdaptor::OpenIsolate);
  interface->AddSimpleMethodHandler(kCloseIsolateMethod, base::Unretained(this),
                                    &ChapsAdaptor::CloseIsolate);
  interface->AddSimpleMethodHandler(kLoadTokenMethod, base::Unretained(this),
                                    &ChapsAdaptor::LoadToken);
  interface->AddSimpleMethodHandler(kUnloadTokenMethod, base::Unretained(this),
                                    &ChapsAdaptor::UnloadToken);
  interface->AddSimpleMethodHandler(kChangeTokenAuthDataMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::ChangeTokenAuthData);
  interface->AddSimpleMethodHandler(kGetTokenPathMethod, base::Unretained(this),
                                    &ChapsAdaptor::GetTokenPath);
  interface->AddSimpleMethodHandler(kSetLogLevelMethod, base::Unretained(this),
                                    &ChapsAdaptor::SetLogLevel);
  interface->AddSimpleMethodHandler(kGetSlotListMethod, base::Unretained(this),
                                    &ChapsAdaptor::GetSlotList);
  interface->AddSimpleMethodHandler(kGetSlotInfoMethod, base::Unretained(this),
                                    &ChapsAdaptor::GetSlotInfo);
  interface->AddSimpleMethodHandler(kGetTokenInfoMethod, base::Unretained(this),
                                    &ChapsAdaptor::GetTokenInfo);
  interface->AddSimpleMethodHandler(kGetMechanismListMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::GetMechanismList);
  interface->AddSimpleMethodHandler(kGetMechanismInfoMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::GetMechanismInfo);
  interface->AddSimpleMethodHandler(kInitTokenMethod, base::Unretained(this),
                                    &ChapsAdaptor::InitToken);
  interface->AddSimpleMethodHandler(kInitPINMethod, base::Unretained(this),
                                    &ChapsAdaptor::InitPIN);
  interface->AddSimpleMethodHandler(kSetPINMethod, base::Unretained(this),
                                    &ChapsAdaptor::SetPIN);
  interface->AddSimpleMethodHandler(kOpenSessionMethod, base::Unretained(this),
                                    &ChapsAdaptor::OpenSession);
  interface->AddSimpleMethodHandler(kCloseSessionMethod, base::Unretained(this),
                                    &ChapsAdaptor::CloseSession);
  interface->AddSimpleMethodHandler(kCloseAllSessionsMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::CloseAllSessions);
  interface->AddSimpleMethodHandler(kGetSessionInfoMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::GetSessionInfo);
  interface->AddSimpleMethodHandler(kGetOperationStateMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::GetOperationState);
  interface->AddSimpleMethodHandler(kSetOperationStateMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::SetOperationState);
  interface->AddSimpleMethodHandler(kLoginMethod, base::Unretained(this),
                                    &ChapsAdaptor::Login);
  interface->AddSimpleMethodHandler(kLogoutMethod, base::Unretained(this),
                                    &ChapsAdaptor::Logout);
  interface->AddSimpleMethodHandler(kCreateObjectMethod, base::Unretained(this),
                                    &ChapsAdaptor::CreateObject);
  interface->AddSimpleMethodHandler(kCopyObjectMethod, base::Unretained(this),
                                    &ChapsAdaptor::CopyObject);
  interface->AddSimpleMethodHandler(kDestroyObjectMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::DestroyObject);
  interface->AddSimpleMethodHandler(kGetObjectSizeMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::GetObjectSize);
  interface->AddSimpleMethodHandler(kGetAttributeValueMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::GetAttributeValue);
  interface->AddSimpleMethodHandler(kSetAttributeValueMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::SetAttributeValue);
  interface->AddSimpleMethodHandler(kFindObjectsInitMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::FindObjectsInit);
  interface->AddSimpleMethodHandler(kFindObjectsMethod, base::Unretained(this),
                                    &ChapsAdaptor::FindObjects);
  interface->AddSimpleMethodHandler(kFindObjectsFinalMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::FindObjectsFinal);
  interface->AddSimpleMethodHandler(kEncryptInitMethod, base::Unretained(this),
                                    &ChapsAdaptor::EncryptInit);
  interface->AddSimpleMethodHandler(kEncryptMethod, base::Unretained(this),
                                    &ChapsAdaptor::Encrypt);
  interface->AddSimpleMethodHandler(kEncryptUpdateMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::EncryptUpdate);
  interface->AddSimpleMethodHandler(kEncryptFinalMethod, base::Unretained(this),
                                    &ChapsAdaptor::EncryptFinal);
  interface->AddSimpleMethodHandler(kEncryptCancelMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::EncryptCancel);
  interface->AddSimpleMethodHandler(kDecryptInitMethod, base::Unretained(this),
                                    &ChapsAdaptor::DecryptInit);
  interface->AddSimpleMethodHandler(kDecryptMethod, base::Unretained(this),
                                    &ChapsAdaptor::Decrypt);
  interface->AddSimpleMethodHandler(kDecryptUpdateMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::DecryptUpdate);
  interface->AddSimpleMethodHandler(kDecryptFinalMethod, base::Unretained(this),
                                    &ChapsAdaptor::DecryptFinal);
  interface->AddSimpleMethodHandler(kDecryptCancelMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::DecryptCancel);
  interface->AddSimpleMethodHandler(kDigestInitMethod, base::Unretained(this),
                                    &ChapsAdaptor::DigestInit);
  interface->AddSimpleMethodHandler(kDigestMethod, base::Unretained(this),
                                    &ChapsAdaptor::Digest);
  interface->AddSimpleMethodHandler(kDigestUpdateMethod, base::Unretained(this),
                                    &ChapsAdaptor::DigestUpdate);
  interface->AddSimpleMethodHandler(kDigestKeyMethod, base::Unretained(this),
                                    &ChapsAdaptor::DigestKey);
  interface->AddSimpleMethodHandler(kDigestFinalMethod, base::Unretained(this),
                                    &ChapsAdaptor::DigestFinal);
  interface->AddSimpleMethodHandler(kDigestCancelMethod, base::Unretained(this),
                                    &ChapsAdaptor::DigestCancel);
  interface->AddSimpleMethodHandler(kSignInitMethod, base::Unretained(this),
                                    &ChapsAdaptor::SignInit);
  interface->AddSimpleMethodHandler(kSignMethod, base::Unretained(this),
                                    &ChapsAdaptor::Sign);
  interface->AddSimpleMethodHandler(kSignUpdateMethod, base::Unretained(this),
                                    &ChapsAdaptor::SignUpdate);
  interface->AddSimpleMethodHandler(kSignFinalMethod, base::Unretained(this),
                                    &ChapsAdaptor::SignFinal);
  interface->AddSimpleMethodHandler(kSignCancelMethod, base::Unretained(this),
                                    &ChapsAdaptor::SignCancel);
  interface->AddSimpleMethodHandler(kSignRecoverInitMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::SignRecoverInit);
  interface->AddSimpleMethodHandler(kSignRecoverMethod, base::Unretained(this),
                                    &ChapsAdaptor::SignRecover);
  interface->AddSimpleMethodHandler(kVerifyInitMethod, base::Unretained(this),
                                    &ChapsAdaptor::VerifyInit);
  interface->AddSimpleMethodHandler(kVerifyMethod, base::Unretained(this),
                                    &ChapsAdaptor::Verify);
  interface->AddSimpleMethodHandler(kVerifyUpdateMethod, base::Unretained(this),
                                    &ChapsAdaptor::VerifyUpdate);
  interface->AddSimpleMethodHandler(kVerifyFinalMethod, base::Unretained(this),
                                    &ChapsAdaptor::VerifyFinal);
  interface->AddSimpleMethodHandler(kVerifyCancelMethod, base::Unretained(this),
                                    &ChapsAdaptor::VerifyCancel);
  interface->AddSimpleMethodHandler(kVerifyRecoverInitMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::VerifyRecoverInit);
  interface->AddSimpleMethodHandler(kVerifyRecoverMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::VerifyRecover);
  interface->AddSimpleMethodHandler(kDigestEncryptUpdateMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::DigestEncryptUpdate);
  interface->AddSimpleMethodHandler(kDecryptDigestUpdateMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::DecryptDigestUpdate);
  interface->AddSimpleMethodHandler(kSignEncryptUpdateMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::SignEncryptUpdate);
  interface->AddSimpleMethodHandler(kDecryptVerifyUpdateMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::DecryptVerifyUpdate);
  interface->AddSimpleMethodHandler(kGenerateKeyMethod, base::Unretained(this),
                                    &ChapsAdaptor::GenerateKey);
  interface->AddSimpleMethodHandler(kGenerateKeyPairMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::GenerateKeyPair);
  interface->AddSimpleMethodHandler(kWrapKeyMethod, base::Unretained(this),
                                    &ChapsAdaptor::WrapKey);
  interface->AddSimpleMethodHandler(kUnwrapKeyMethod, base::Unretained(this),
                                    &ChapsAdaptor::UnwrapKey);
  interface->AddSimpleMethodHandler(kDeriveKeyMethod, base::Unretained(this),
                                    &ChapsAdaptor::DeriveKey);
  interface->AddSimpleMethodHandler(kSeedRandomMethod, base::Unretained(this),
                                    &ChapsAdaptor::SeedRandom);
  interface->AddSimpleMethodHandler(kGenerateRandomMethod,
                                    base::Unretained(this),
                                    &ChapsAdaptor::GenerateRandom);
  dbus_object_.RegisterAsync(cb);
}

void ChapsAdaptor::OpenIsolate(
    const brillo::SecureVector& isolate_credential_in,
    brillo::SecureVector* isolate_credential_out,
    bool* new_isolate_created,
    bool* result) {
  VLOG(1) << "CALL: " << __func__;
  *result = false;
  SecureBlob isolate_credential(isolate_credential_in.begin(),
                                isolate_credential_in.end());
  if (token_manager_)
    *result =
        token_manager_->OpenIsolate(&isolate_credential, new_isolate_created);
  isolate_credential_out->swap(isolate_credential);
}

void ChapsAdaptor::CloseIsolate(
    const brillo::SecureVector& isolate_credential) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());

  if (token_manager_)
    token_manager_->CloseIsolate(isolate_credential_blob);
}

void ChapsAdaptor::LoadToken(const brillo::SecureVector& isolate_credential,
                             const string& path,
                             const brillo::SecureVector& auth_data,
                             const string& label,
                             uint64_t* slot_id,
                             bool* result) {
  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));
}

void ChapsAdaptor::UnloadToken(const brillo::SecureVector& isolate_credential,
                               const string& path) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());

  if (token_manager_)
    token_manager_->UnloadToken(isolate_credential_blob, FilePath(path));
}

void ChapsAdaptor::ChangeTokenAuthData(
    const string& path,
    const brillo::SecureVector& old_auth_data,
    const brillo::SecureVector& 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()));
}

void ChapsAdaptor::GetTokenPath(const brillo::SecureVector& isolate_credential,
                                uint64_t slot_id,
                                std::string* path,
                                bool* result) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());
  if (token_manager_) {
    FilePath tmp;
    *result =
        token_manager_->GetTokenPath(isolate_credential_blob, slot_id, &tmp);
    *path = tmp.value();
  }
}

void ChapsAdaptor::SetLogLevel(const int32_t& level) {
  logging::SetMinLogLevel(level);
  string level_str = base::IntToString(level);
  int writeResult = base::WriteFile(FilePath(kPersistentLogLevelPath),
                                    level_str.data(), level_str.length());
  VLOG_IF(2, writeResult < 0) << "Failed to save loglevel to file.";
}

void ChapsAdaptor::GetSlotList(const brillo::SecureVector& isolate_credential,
                               bool token_present,
                               vector<uint64_t>* slot_list,
                               uint32_t* result) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: "
          << "token_present=" << token_present;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());

  *result =
      service_->GetSlotList(isolate_credential_blob, token_present, slot_list);
  VLOG_IF(2, *result == CKR_OK) << "OUT: "
                                << "slot_list=" << PrintIntVector(*slot_list);
}

void ChapsAdaptor::GetSlotInfo(const brillo::SecureVector& isolate_credential,
                               uint64_t slot_id,
                               SlotInfo* slot_info,
                               uint32_t* result) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: "
          << "slot_id=" << slot_id;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());

  *result = service_->GetSlotInfo(isolate_credential_blob, slot_id, slot_info);
  VLOG_IF(2, *result == CKR_OK)
      << "OUT: "
      << "slot_description=" << slot_info->slot_description();
}

void ChapsAdaptor::GetTokenInfo(const brillo::SecureVector& isolate_credential,
                                uint64_t slot_id,
                                TokenInfo* token_info,
                                uint32_t* result) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: "
          << "slot_id=" << slot_id;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());

  *result =
      service_->GetTokenInfo(isolate_credential_blob, slot_id, token_info);
  VLOG_IF(2, *result == CKR_OK) << "OUT: "
                                << "label=" << token_info->label();
}

void ChapsAdaptor::GetMechanismList(
    const brillo::SecureVector& isolate_credential,
    uint64_t slot_id,
    vector<uint64_t>* mechanism_list,
    uint32_t* result) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: "
          << "slot_id=" << slot_id;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());

  *result = service_->GetMechanismList(isolate_credential_blob, slot_id,
                                       mechanism_list);
  VLOG_IF(2, *result == CKR_OK)
      << "OUT: "
      << "mechanism_list=" << PrintIntVector(*mechanism_list);
}

void ChapsAdaptor::GetMechanismInfo(
    const brillo::SecureVector& isolate_credential,
    uint64_t slot_id,
    uint64_t mechanism_type,
    MechanismInfo* mechanism_info,
    uint32_t* result) {
  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());

  *result = service_->GetMechanismInfo(isolate_credential_blob, slot_id,
                                       mechanism_type, mechanism_info);
  VLOG_IF(2, *result == CKR_OK)
      << "OUT: "
      << "min_key_size=" << mechanism_info->min_key_size();
  VLOG_IF(2, *result == CKR_OK)
      << "OUT: "
      << "max_key_size=" << mechanism_info->max_key_size();
  VLOG_IF(2, *result == CKR_OK) << "OUT: "
                                << "flags=" << mechanism_info->flags();
}

uint32_t ChapsAdaptor::InitToken(const brillo::SecureVector& isolate_credential,
                                 uint64_t slot_id,
                                 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());

  return service_->InitToken(isolate_credential_blob, slot_id, tmp_pin,
                             new_token_label);
}

uint32_t ChapsAdaptor::InitPIN(const brillo::SecureVector& isolate_credential,
                               uint64_t session_id,
                               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());

  return service_->InitPIN(isolate_credential_blob, session_id, tmp_pin);
}

uint32_t ChapsAdaptor::SetPIN(const brillo::SecureVector& isolate_credential,
                              uint64_t session_id,
                              bool use_null_old_pin,
                              const string& optional_old_pin,
                              bool use_null_new_pin,
                              const string& optional_new_pin) {
  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());

  return service_->SetPIN(isolate_credential_blob, session_id, tmp_old_pin,
                          tmp_new_pin);
}

void ChapsAdaptor::OpenSession(const brillo::SecureVector& isolate_credential,
                               uint64_t slot_id,
                               uint64_t flags,
                               uint64_t* session_id,
                               uint32_t* result) {
  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());

  *result = service_->OpenSession(isolate_credential_blob, slot_id, flags,
                                  session_id);
  VLOG_IF(2, *result == CKR_OK) << "OUT: "
                                << "session_id=" << session_id;
}

uint32_t ChapsAdaptor::CloseSession(
    const brillo::SecureVector& isolate_credential, uint64_t session_id) {
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: "
          << "session_id=" << session_id;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());

  return service_->CloseSession(isolate_credential_blob, session_id);
}

uint32_t ChapsAdaptor::CloseAllSessions(
    const brillo::SecureVector& isolate_credential, uint64_t slot_id) {
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: "
          << "slot_id=" << slot_id;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());

  return service_->CloseAllSessions(isolate_credential_blob, slot_id);
}

void ChapsAdaptor::GetSessionInfo(
    const brillo::SecureVector& isolate_credential,
    uint64_t session_id,
    SessionInfo* session_info,
    uint32_t* result) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  VLOG(2) << "IN: "
          << "session_id=" << session_id;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());

  *result = service_->GetSessionInfo(isolate_credential_blob, session_id,
                                     session_info);
  VLOG_IF(2, *result == CKR_OK) << "OUT: "
                                << "slot_id=" << session_info->slot_id();
  VLOG_IF(2, *result == CKR_OK) << "OUT: "
                                << "state=" << session_info->state();
  VLOG_IF(2, *result == CKR_OK) << "OUT: "
                                << "flags=" << session_info->flags();
  VLOG_IF(2, *result == CKR_OK)
      << "OUT: "
      << "device_error=" << session_info->device_error();
}

void ChapsAdaptor::GetOperationState(
    const brillo::SecureVector& isolate_credential,
    uint64_t session_id,
    vector<uint8_t>* operation_state,
    uint32_t* result) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());

  *result = service_->GetOperationState(isolate_credential_blob, session_id,
                                        operation_state);
}

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

  return service_->SetOperationState(isolate_credential_blob, session_id,
                                     operation_state, encryption_key_handle,
                                     authentication_key_handle);
}

uint32_t ChapsAdaptor::Login(const brillo::SecureVector& isolate_credential,
                             uint64_t session_id,
                             uint64_t user_type,
                             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());

  return service_->Login(isolate_credential_blob, session_id, user_type, pin);
}

uint32_t ChapsAdaptor::Logout(const brillo::SecureVector& isolate_credential,
                              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());

  return service_->Logout(isolate_credential_blob, session_id);
}

void ChapsAdaptor::CreateObject(const brillo::SecureVector& isolate_credential,
                                uint64_t session_id,
                                const vector<uint8_t>& attributes,
                                uint64_t* new_object_handle,
                                uint32_t* result) {
  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());

  *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::CopyObject(const brillo::SecureVector& isolate_credential,
                              uint64_t session_id,
                              uint64_t object_handle,
                              const vector<uint8_t>& attributes,
                              uint64_t* new_object_handle,
                              uint32_t* result) {
  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());

  *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;
}

uint32_t ChapsAdaptor::DestroyObject(
    const brillo::SecureVector& isolate_credential,
    uint64_t session_id,
    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());

  return service_->DestroyObject(isolate_credential_blob, session_id,
                                 object_handle);
}

void ChapsAdaptor::GetObjectSize(const brillo::SecureVector& isolate_credential,
                                 uint64_t session_id,
                                 uint64_t object_handle,
                                 uint64_t* object_size,
                                 uint32_t* result) {
  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());

  *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::GetAttributeValue(
    const brillo::SecureVector& isolate_credential,
    uint64_t session_id,
    uint64_t object_handle,
    const vector<uint8_t>& attributes_in,
    vector<uint8_t>* attributes_out,
    uint32_t* result) {
  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());

  *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);
}

uint32_t ChapsAdaptor::SetAttributeValue(
    const brillo::SecureVector& isolate_credential,
    uint64_t session_id,
    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());

  return service_->SetAttributeValue(isolate_credential_blob, session_id,
                                     object_handle, attributes);
}

uint32_t ChapsAdaptor::FindObjectsInit(
    const brillo::SecureVector& isolate_credential,
    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());

  return service_->FindObjectsInit(isolate_credential_blob, session_id,
                                   attributes);
}

void ChapsAdaptor::FindObjects(const brillo::SecureVector& isolate_credential,
                               uint64_t session_id,
                               uint64_t max_object_count,
                               vector<uint64_t>* object_list,
                               uint32_t* result) {
  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());

  *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);
}

uint32_t ChapsAdaptor::FindObjectsFinal(
    const brillo::SecureVector& isolate_credential, 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());

  return service_->FindObjectsFinal(isolate_credential_blob, session_id);
}

uint32_t ChapsAdaptor::EncryptInit(
    const brillo::SecureVector& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    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());

  return service_->EncryptInit(isolate_credential_blob, session_id,
                               mechanism_type, mechanism_parameter, key_handle);
}

void ChapsAdaptor::Encrypt(const brillo::SecureVector& isolate_credential,
                           uint64_t session_id,
                           const vector<uint8_t>& data_in,
                           uint64_t max_out_length,
                           uint64_t* actual_out_length,
                           vector<uint8_t>* data_out,
                           uint32_t* result) {
  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());

  *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::EncryptUpdate(const brillo::SecureVector& isolate_credential,
                                 uint64_t session_id,
                                 const vector<uint8_t>& data_in,
                                 uint64_t max_out_length,
                                 uint64_t* actual_out_length,
                                 vector<uint8_t>* data_out,
                                 uint32_t* result) {
  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());

  *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::EncryptFinal(const brillo::SecureVector& isolate_credential,
                                uint64_t session_id,
                                uint64_t max_out_length,
                                uint64_t* actual_out_length,
                                vector<uint8_t>* data_out,
                                uint32_t* result) {
  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());

  *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::EncryptCancel(const brillo::SecureVector& isolate_credential,
                                 uint64_t session_id) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());

  service_->EncryptCancel(isolate_credential_blob, session_id);
}

uint32_t ChapsAdaptor::DecryptInit(
    const brillo::SecureVector& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    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());

  return service_->DecryptInit(isolate_credential_blob, session_id,
                               mechanism_type, mechanism_parameter, key_handle);
}

void ChapsAdaptor::Decrypt(const brillo::SecureVector& isolate_credential,
                           uint64_t session_id,
                           const vector<uint8_t>& data_in,
                           uint64_t max_out_length,
                           uint64_t* actual_out_length,
                           vector<uint8_t>* data_out,
                           uint32_t* result) {
  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());

  *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::DecryptUpdate(const brillo::SecureVector& isolate_credential,
                                 uint64_t session_id,
                                 const vector<uint8_t>& data_in,
                                 uint64_t max_out_length,
                                 uint64_t* actual_out_length,
                                 vector<uint8_t>* data_out,
                                 uint32_t* result) {
  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());

  *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::DecryptFinal(const brillo::SecureVector& isolate_credential,
                                uint64_t session_id,
                                uint64_t max_out_length,
                                uint64_t* actual_out_length,
                                vector<uint8_t>* data_out,
                                uint32_t* result) {
  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());

  *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::DecryptCancel(const brillo::SecureVector& isolate_credential,
                                 uint64_t session_id) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());

  service_->DecryptCancel(isolate_credential_blob, session_id);
}

uint32_t ChapsAdaptor::DigestInit(
    const brillo::SecureVector& isolate_credential,
    uint64_t session_id,
    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());

  return service_->DigestInit(isolate_credential_blob, session_id,
                              mechanism_type, mechanism_parameter);
}

void ChapsAdaptor::Digest(const brillo::SecureVector& isolate_credential,
                          uint64_t session_id,
                          const vector<uint8_t>& data_in,
                          uint64_t max_out_length,
                          uint64_t* actual_out_length,
                          vector<uint8_t>* digest,
                          uint32_t* result) {
  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());

  *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;
}

uint32_t ChapsAdaptor::DigestUpdate(
    const brillo::SecureVector& isolate_credential,
    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());

  return service_->DigestUpdate(isolate_credential_blob, session_id, data_in);
}

uint32_t ChapsAdaptor::DigestKey(const brillo::SecureVector& isolate_credential,
                                 uint64_t session_id,
                                 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());

  return service_->DigestKey(isolate_credential_blob, session_id, key_handle);
}

void ChapsAdaptor::DigestFinal(const brillo::SecureVector& isolate_credential,
                               uint64_t session_id,
                               uint64_t max_out_length,
                               uint64_t* actual_out_length,
                               vector<uint8_t>* digest,
                               uint32_t* result) {
  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());

  *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::DigestCancel(const brillo::SecureVector& isolate_credential,
                                uint64_t session_id) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());

  service_->DigestCancel(isolate_credential_blob, session_id);
}

uint32_t ChapsAdaptor::SignInit(const brillo::SecureVector& isolate_credential,
                                uint64_t session_id,
                                uint64_t mechanism_type,
                                const vector<uint8_t>& mechanism_parameter,
                                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());

  return service_->SignInit(isolate_credential_blob, session_id, mechanism_type,
                            mechanism_parameter, key_handle);
}

void ChapsAdaptor::Sign(const brillo::SecureVector& isolate_credential,
                        uint64_t session_id,
                        const vector<uint8_t>& data,
                        uint64_t max_out_length,
                        uint64_t* actual_out_length,
                        vector<uint8_t>* signature,
                        uint32_t* result) {
  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());

  *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;
}

uint32_t ChapsAdaptor::SignUpdate(
    const brillo::SecureVector& isolate_credential,
    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());

  return service_->SignUpdate(isolate_credential_blob, session_id, data_part);
}

void ChapsAdaptor::SignFinal(const brillo::SecureVector& isolate_credential,
                             uint64_t session_id,
                             uint64_t max_out_length,
                             uint64_t* actual_out_length,
                             vector<uint8_t>* signature,
                             uint32_t* result) {
  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());

  *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::SignCancel(const brillo::SecureVector& isolate_credential,
                              uint64_t session_id) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());

  service_->SignCancel(isolate_credential_blob, session_id);
}

uint32_t ChapsAdaptor::SignRecoverInit(
    const brillo::SecureVector& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    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());

  return service_->SignRecoverInit(isolate_credential_blob, session_id,
                                   mechanism_type, mechanism_parameter,
                                   key_handle);
}

void ChapsAdaptor::SignRecover(const brillo::SecureVector& isolate_credential,
                               uint64_t session_id,
                               const vector<uint8_t>& data,
                               uint64_t max_out_length,
                               uint64_t* actual_out_length,
                               vector<uint8_t>* signature,
                               uint32_t* result) {
  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());

  *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;
}

uint32_t ChapsAdaptor::VerifyInit(
    const brillo::SecureVector& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    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());

  return service_->VerifyInit(isolate_credential_blob, session_id,
                              mechanism_type, mechanism_parameter, key_handle);
}

uint32_t ChapsAdaptor::Verify(const brillo::SecureVector& isolate_credential,
                              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());

  return service_->Verify(isolate_credential_blob, session_id, data, signature);
}

uint32_t ChapsAdaptor::VerifyUpdate(
    const brillo::SecureVector& isolate_credential,
    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());

  return service_->VerifyUpdate(isolate_credential_blob, session_id, data_part);
}

uint32_t ChapsAdaptor::VerifyFinal(
    const brillo::SecureVector& isolate_credential,
    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());

  return service_->VerifyFinal(isolate_credential_blob, session_id, signature);
}

void ChapsAdaptor::VerifyCancel(const brillo::SecureVector& isolate_credential,
                                uint64_t session_id) {
  AutoLock lock(*lock_);
  VLOG(1) << "CALL: " << __func__;
  SecureBlob isolate_credential_blob(isolate_credential.begin(),
                                     isolate_credential.end());

  service_->VerifyCancel(isolate_credential_blob, session_id);
}

uint32_t ChapsAdaptor::VerifyRecoverInit(
    const brillo::SecureVector& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    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());

  return service_->VerifyRecoverInit(isolate_credential_blob, session_id,
                                     mechanism_type, mechanism_parameter,
                                     key_handle);
}

void ChapsAdaptor::VerifyRecover(const brillo::SecureVector& isolate_credential,
                                 uint64_t session_id,
                                 const vector<uint8_t>& signature,
                                 uint64_t max_out_length,
                                 uint64_t* actual_out_length,
                                 vector<uint8_t>* data,
                                 uint32_t* result) {
  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());

  *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::DigestEncryptUpdate(
    const brillo::SecureVector& isolate_credential,
    uint64_t session_id,
    const vector<uint8_t>& data_in,
    uint64_t max_out_length,
    uint64_t* actual_out_length,
    vector<uint8_t>* data_out,
    uint32_t* result) {
  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());

  *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::DecryptDigestUpdate(
    const brillo::SecureVector& isolate_credential,
    uint64_t session_id,
    const vector<uint8_t>& data_in,
    uint64_t max_out_length,
    uint64_t* actual_out_length,
    vector<uint8_t>* data_out,
    uint32_t* result) {
  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());

  *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::SignEncryptUpdate(
    const brillo::SecureVector& isolate_credential,
    uint64_t session_id,
    const vector<uint8_t>& data_in,
    uint64_t max_out_length,
    uint64_t* actual_out_length,
    vector<uint8_t>* data_out,
    uint32_t* result) {
  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());

  *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::DecryptVerifyUpdate(
    const brillo::SecureVector& isolate_credential,
    uint64_t session_id,
    const vector<uint8_t>& data_in,
    uint64_t max_out_length,
    uint64_t* actual_out_length,
    vector<uint8_t>* data_out,
    uint32_t* result) {
  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());

  *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::GenerateKey(const brillo::SecureVector& isolate_credential,
                               uint64_t session_id,
                               uint64_t mechanism_type,
                               const vector<uint8_t>& mechanism_parameter,
                               const vector<uint8_t>& attributes,
                               uint64_t* key_handle,
                               uint32_t* result) {
  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());

  *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::GenerateKeyPair(
    const brillo::SecureVector& isolate_credential,
    uint64_t session_id,
    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,
    uint64_t* private_key_handle,
    uint32_t* result) {
  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());

  *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::WrapKey(const brillo::SecureVector& isolate_credential,
                           uint64_t session_id,
                           uint64_t mechanism_type,
                           const vector<uint8_t>& mechanism_parameter,
                           uint64_t wrapping_key_handle,
                           uint64_t key_handle,
                           uint64_t max_out_length,
                           uint64_t* actual_out_length,
                           vector<uint8_t>* wrapped_key,
                           uint32_t* result) {
  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());

  *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::UnwrapKey(const brillo::SecureVector& isolate_credential,
                             uint64_t session_id,
                             uint64_t mechanism_type,
                             const vector<uint8_t>& mechanism_parameter,
                             uint64_t wrapping_key_handle,
                             const vector<uint8_t>& wrapped_key,
                             const vector<uint8_t>& attributes,
                             uint64_t* key_handle,
                             uint32_t* result) {
  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());

  *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::DeriveKey(const brillo::SecureVector& isolate_credential,
                             uint64_t session_id,
                             uint64_t mechanism_type,
                             const vector<uint8_t>& mechanism_parameter,
                             uint64_t base_key_handle,
                             const vector<uint8_t>& attributes,
                             uint64_t* key_handle,
                             uint32_t* result) {
  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());

  *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;
}

uint32_t ChapsAdaptor::SeedRandom(
    const brillo::SecureVector& isolate_credential,
    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());

  return service_->SeedRandom(isolate_credential_blob, session_id, seed);
}

void ChapsAdaptor::GenerateRandom(
    const brillo::SecureVector& isolate_credential,
    uint64_t session_id,
    uint64_t num_bytes,
    vector<uint8_t>* random_data,
    uint32_t* result) {
  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());

  *result = service_->GenerateRandom(isolate_credential_blob, session_id,
                                     num_bytes, random_data);
}

}  // namespace chaps
