// Copyright (c) 2012 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_service.h"

#include <base/logging.h>

#include "chaps/attributes.h"
#include "chaps/chaps.h"
#include "chaps/chaps_utility.h"
#include "chaps/object.h"
#include "chaps/proto_conversion.h"
#include "chaps/session.h"
#include "chaps/slot_manager.h"

using brillo::SecureBlob;
using std::string;
using std::vector;

namespace chaps {

ChapsServiceImpl::ChapsServiceImpl(SlotManager* slot_manager)
    : slot_manager_(slot_manager) {
  CHECK(slot_manager);
}

uint32_t ChapsServiceImpl::GetSlotList(const SecureBlob& isolate_credential,
                                       bool token_present,
                                       vector<uint64_t>* slot_list) {
  if (!slot_list || slot_list->size() > 0)
    LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
  int num_slots = slot_manager_->GetSlotCount();
  for (int i = 0; i < num_slots; ++i) {
    if (slot_manager_->IsTokenAccessible(isolate_credential, i) &&
        (!token_present ||
         slot_manager_->IsTokenPresent(isolate_credential, i)))
      slot_list->push_back(i);
  }
  return CKR_OK;
}

uint32_t ChapsServiceImpl::GetSlotInfo(const SecureBlob& isolate_credential,
                                       uint64_t slot_id,
                                       SlotInfo* slot_info) {
  LOG_CK_RV_AND_RETURN_IF(!slot_info, CKR_ARGUMENTS_BAD);
  if (static_cast<int>(slot_id) >= slot_manager_->GetSlotCount() ||
      !slot_manager_->IsTokenAccessible(isolate_credential, slot_id))
    LOG_CK_RV_AND_RETURN(CKR_SLOT_ID_INVALID);
  CK_SLOT_INFO ck_slot_info;
  slot_manager_->GetSlotInfo(isolate_credential, slot_id, &ck_slot_info);
  *slot_info = SlotInfoToProto(&ck_slot_info);
  return CKR_OK;
}

uint32_t ChapsServiceImpl::GetTokenInfo(const SecureBlob& isolate_credential,
                                        uint64_t slot_id,
                                        TokenInfo* token_info) {
  LOG_CK_RV_AND_RETURN_IF(!token_info, CKR_ARGUMENTS_BAD);
  if (static_cast<int>(slot_id) >= slot_manager_->GetSlotCount() ||
      !slot_manager_->IsTokenAccessible(isolate_credential, slot_id))
    LOG_CK_RV_AND_RETURN(CKR_SLOT_ID_INVALID);
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->IsTokenPresent(isolate_credential, slot_id),
      CKR_TOKEN_NOT_PRESENT);
  CK_TOKEN_INFO ck_token_info;
  slot_manager_->GetTokenInfo(isolate_credential, slot_id, &ck_token_info);
  *token_info = TokenInfoToProto(&ck_token_info);
  return CKR_OK;
}

uint32_t ChapsServiceImpl::GetMechanismList(
    const SecureBlob& isolate_credential,
    uint64_t slot_id,
    vector<uint64_t>* mechanism_list) {
  LOG_CK_RV_AND_RETURN_IF(!mechanism_list || mechanism_list->size() > 0,
                          CKR_ARGUMENTS_BAD);
  if (static_cast<int>(slot_id) >= slot_manager_->GetSlotCount() ||
      !slot_manager_->IsTokenAccessible(isolate_credential, slot_id))
    LOG_CK_RV_AND_RETURN(CKR_SLOT_ID_INVALID);
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->IsTokenPresent(isolate_credential, slot_id),
      CKR_TOKEN_NOT_PRESENT);
  const MechanismMap* mechanism_info =
      slot_manager_->GetMechanismInfo(isolate_credential, slot_id);
  CHECK(mechanism_info);
  for (MechanismMapIterator it = mechanism_info->begin();
       it != mechanism_info->end(); ++it) {
    mechanism_list->push_back(it->first);
  }
  return CKR_OK;
}

uint32_t ChapsServiceImpl::GetMechanismInfo(
    const SecureBlob& isolate_credential,
    uint64_t slot_id,
    uint64_t mechanism_type,
    MechanismInfo* mechanism_info) {
  LOG_CK_RV_AND_RETURN_IF(!mechanism_info, CKR_ARGUMENTS_BAD);
  if (static_cast<int>(slot_id) >= slot_manager_->GetSlotCount() ||
      !slot_manager_->IsTokenAccessible(isolate_credential, slot_id))
    LOG_CK_RV_AND_RETURN(CKR_SLOT_ID_INVALID);
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->IsTokenPresent(isolate_credential, slot_id),
      CKR_TOKEN_NOT_PRESENT);
  const MechanismMap* mechanism_map =
      slot_manager_->GetMechanismInfo(isolate_credential, slot_id);
  CHECK(mechanism_info);
  MechanismMapIterator it = mechanism_map->find(mechanism_type);
  LOG_CK_RV_AND_RETURN_IF(it == mechanism_map->end(), CKR_MECHANISM_INVALID);
  *mechanism_info = MechanismInfoToProto(&it->second);
  return CKR_OK;
}

uint32_t ChapsServiceImpl::InitToken(const SecureBlob& isolate_credential,
                                     uint64_t slot_id,
                                     const string* so_pin,
                                     const vector<uint8_t>& label) {
  LOG_CK_RV_AND_RETURN_IF(label.size() != chaps::kTokenLabelSize,
                          CKR_ARGUMENTS_BAD);
  if (static_cast<int>(slot_id) >= slot_manager_->GetSlotCount() ||
      !slot_manager_->IsTokenAccessible(isolate_credential, slot_id))
    LOG_CK_RV_AND_RETURN(CKR_SLOT_ID_INVALID);
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->IsTokenPresent(isolate_credential, slot_id),
      CKR_TOKEN_NOT_PRESENT);
  // We have no notion of a security officer role and no notion of initializing
  // a token via this interface.  CKR_FUNCTION_NOT_SUPPORTED could be an option
  // here but reporting an incorrect pin is more likely to be handled gracefully
  // by the caller.
  LOG_CK_RV_AND_RETURN(CKR_PIN_INCORRECT);
}

uint32_t ChapsServiceImpl::InitPIN(const SecureBlob& isolate_credential,
                                   uint64_t session_id,
                                   const string* pin) {
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  // Authentication is not handled via this interface.  Since this function can
  // only be called in the "R/W SO Functions" state and we don't support this
  // state, CKR_USER_NOT_LOGGED_IN is the appropriate response.
  LOG_CK_RV_AND_RETURN(CKR_USER_NOT_LOGGED_IN);
}

uint32_t ChapsServiceImpl::SetPIN(const SecureBlob& isolate_credential,
                                  uint64_t session_id,
                                  const string* old_pin,
                                  const string* new_pin) {
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  // Authentication is not handled via this interface.  We do not support
  // changing a pin or password of any kind.
  LOG_CK_RV_AND_RETURN(CKR_PIN_INVALID);
}

uint32_t ChapsServiceImpl::OpenSession(const SecureBlob& isolate_credential,
                                       uint64_t slot_id,
                                       uint64_t flags,
                                       uint64_t* session_id) {
  LOG_CK_RV_AND_RETURN_IF(!session_id, CKR_ARGUMENTS_BAD);
  if (static_cast<int>(slot_id) >= slot_manager_->GetSlotCount() ||
      !slot_manager_->IsTokenAccessible(isolate_credential, slot_id))
    LOG_CK_RV_AND_RETURN(CKR_SLOT_ID_INVALID);
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->IsTokenPresent(isolate_credential, slot_id),
      CKR_TOKEN_NOT_PRESENT);
  LOG_CK_RV_AND_RETURN_IF(0 == (flags & CKF_SERIAL_SESSION),
                          CKR_SESSION_PARALLEL_NOT_SUPPORTED);
  *session_id = slot_manager_->OpenSession(isolate_credential, slot_id,
                                           (flags & CKF_RW_SESSION) == 0);
  return CKR_OK;
}

uint32_t ChapsServiceImpl::CloseSession(const SecureBlob& isolate_credential,
                                        uint64_t session_id) {
  if (!slot_manager_->CloseSession(isolate_credential, session_id))
    LOG_CK_RV_AND_RETURN(CKR_SESSION_HANDLE_INVALID);
  return CKR_OK;
}

uint32_t ChapsServiceImpl::CloseAllSessions(
    const SecureBlob& isolate_credential, uint64_t slot_id) {
  if (static_cast<int>(slot_id) >= slot_manager_->GetSlotCount() ||
      !slot_manager_->IsTokenAccessible(isolate_credential, slot_id))
    LOG_CK_RV_AND_RETURN(CKR_SLOT_ID_INVALID);
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->IsTokenPresent(isolate_credential, slot_id),
      CKR_TOKEN_NOT_PRESENT);
  slot_manager_->CloseAllSessions(isolate_credential, slot_id);
  return CKR_OK;
}

uint32_t ChapsServiceImpl::GetSessionInfo(const SecureBlob& isolate_credential,
                                          uint64_t session_id,
                                          SessionInfo* session_info) {
  LOG_CK_RV_AND_RETURN_IF(!session_info, CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  session_info->set_slot_id(static_cast<uint64_t>(session->GetSlot()));
  session_info->set_state(static_cast<uint64_t>(session->GetState()));
  uint64_t flags;
  flags = CKF_SERIAL_SESSION;
  if (!session->IsReadOnly())
    flags |= CKF_RW_SESSION;
  session_info->set_flags(flags);
  session_info->set_device_error(0);
  return CKR_OK;
}

uint32_t ChapsServiceImpl::GetOperationState(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    vector<uint8_t>* operation_state) {
  LOG_CK_RV_AND_RETURN_IF(!operation_state, CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  LOG_CK_RV_AND_RETURN_IF(!session->IsOperationActive(kEncrypt) &&
                              !session->IsOperationActive(kDecrypt) &&
                              !session->IsOperationActive(kDigest) &&
                              !session->IsOperationActive(kSign) &&
                              !session->IsOperationActive(kVerify),
                          CKR_OPERATION_NOT_INITIALIZED);
  // There is an active operation but we'll still refuse to give out state.
  LOG_CK_RV_AND_RETURN(CKR_STATE_UNSAVEABLE);
}

uint32_t ChapsServiceImpl::SetOperationState(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    const vector<uint8_t>& operation_state,
    uint64_t encryption_key_handle,
    uint64_t authentication_key_handle) {
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  // We don't give out operation state so there's no way this is valid.
  LOG_CK_RV_AND_RETURN(CKR_SAVED_STATE_INVALID);
}

uint32_t ChapsServiceImpl::Login(const SecureBlob& isolate_credential,
                                 uint64_t session_id,
                                 uint64_t user_type,
                                 const string* pin) {
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  // We have no notion of a security officer role.
  LOG_CK_RV_AND_RETURN_IF(user_type == CKU_SO, CKR_PIN_INCORRECT);
  LOG_CK_RV_AND_RETURN_IF(
      user_type != CKU_USER && user_type != CKU_CONTEXT_SPECIFIC,
      CKR_USER_TYPE_INVALID);
  // For backwards compatibility we'll accept the hard-coded pin previously used
  // with openCryptoki.  We'll also accept a protected authentication path
  // operation (i.e. a null pin).
  const string legacy_pin("111111");
  LOG_CK_RV_AND_RETURN_IF(pin && *pin != legacy_pin, CKR_PIN_INCORRECT);
  // After successful C_Login, applications will expect private objects to be
  // available for queries. Don't block waiting for them to become available,
  // return the appropriate error immediately instead.
  LOG_CK_RV_AND_RETURN_IF(!session->IsPrivateLoaded(),
                          CKR_WOULD_BLOCK_FOR_PRIVATE_OBJECTS);
  // We could use CKR_USER_ALREADY_LOGGED_IN but that will cause some
  // applications to close all sessions and start from scratch which is
  // unnecessary.
  return CKR_OK;
}

uint32_t ChapsServiceImpl::Logout(const SecureBlob& isolate_credential,
                                  uint64_t session_id) {
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  return CKR_OK;
}

uint32_t ChapsServiceImpl::CreateObject(const SecureBlob& isolate_credential,
                                        uint64_t session_id,
                                        const vector<uint8_t>& attributes,
                                        uint64_t* new_object_handle) {
  LOG_CK_RV_AND_RETURN_IF(!new_object_handle, CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  Attributes parsed_attributes;
  LOG_CK_RV_AND_RETURN_IF(!parsed_attributes.Parse(attributes),
                          CKR_TEMPLATE_INCONSISTENT);
  return session->CreateObject(
      parsed_attributes.attributes(), parsed_attributes.num_attributes(),
      PreservedValue<uint64_t, int>(new_object_handle));
}

uint32_t ChapsServiceImpl::CopyObject(const SecureBlob& isolate_credential,
                                      uint64_t session_id,
                                      uint64_t object_handle,
                                      const vector<uint8_t>& attributes,
                                      uint64_t* new_object_handle) {
  LOG_CK_RV_AND_RETURN_IF(!new_object_handle, CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  Attributes parsed_attributes;
  LOG_CK_RV_AND_RETURN_IF(!parsed_attributes.Parse(attributes),
                          CKR_TEMPLATE_INCONSISTENT);
  return session->CopyObject(parsed_attributes.attributes(),
                             parsed_attributes.num_attributes(), object_handle,
                             PreservedValue<uint64_t, int>(new_object_handle));
}

uint32_t ChapsServiceImpl::DestroyObject(const SecureBlob& isolate_credential,
                                         uint64_t session_id,
                                         uint64_t object_handle) {
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  return session->DestroyObject(object_handle);
}

uint32_t ChapsServiceImpl::GetObjectSize(const SecureBlob& isolate_credential,
                                         uint64_t session_id,
                                         uint64_t object_handle,
                                         uint64_t* object_size) {
  LOG_CK_RV_AND_RETURN_IF(!object_size, CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  const Object* object = NULL;
  LOG_CK_RV_AND_RETURN_IF(!session->GetObject(object_handle, &object),
                          CKR_OBJECT_HANDLE_INVALID);
  CHECK(object);
  *object_size = object->GetSize();
  return CKR_OK;
}

uint32_t ChapsServiceImpl::GetAttributeValue(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t object_handle,
    const vector<uint8_t>& attributes_in,
    vector<uint8_t>* attributes_out) {
  LOG_CK_RV_AND_RETURN_IF(!attributes_out, CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  const Object* object = NULL;
  LOG_CK_RV_AND_RETURN_IF(!session->GetObject(object_handle, &object),
                          CKR_OBJECT_HANDLE_INVALID);
  CHECK(object);
  Attributes tmp;
  LOG_CK_RV_AND_RETURN_IF(!tmp.Parse(attributes_in), CKR_TEMPLATE_INCONSISTENT);
  CK_RV result = object->GetAttributes(tmp.attributes(), tmp.num_attributes());
  if (result == CKR_OK || result == CKR_ATTRIBUTE_SENSITIVE ||
      result == CKR_ATTRIBUTE_TYPE_INVALID || result == CKR_BUFFER_TOO_SMALL) {
    LOG_CK_RV_AND_RETURN_IF(!tmp.Serialize(attributes_out),
                            CKR_FUNCTION_FAILED);
  }
  return result;
}

uint32_t ChapsServiceImpl::SetAttributeValue(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t object_handle,
    const vector<uint8_t>& attributes) {
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  Object* object = NULL;
  LOG_CK_RV_AND_RETURN_IF(!session->GetModifiableObject(object_handle, &object),
                          CKR_OBJECT_HANDLE_INVALID);
  CHECK(object);
  Attributes tmp;
  LOG_CK_RV_AND_RETURN_IF(!tmp.Parse(attributes), CKR_TEMPLATE_INCONSISTENT);
  CK_RV result = object->SetAttributes(tmp.attributes(), tmp.num_attributes());
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  result = session->FlushModifiableObject(object);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceImpl::FindObjectsInit(const SecureBlob& isolate_credential,
                                           uint64_t session_id,
                                           const vector<uint8_t>& attributes) {
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  Attributes tmp;
  LOG_CK_RV_AND_RETURN_IF(!tmp.Parse(attributes), CKR_TEMPLATE_INCONSISTENT);
  return session->FindObjectsInit(tmp.attributes(), tmp.num_attributes());
}

uint32_t ChapsServiceImpl::FindObjects(const SecureBlob& isolate_credential,
                                       uint64_t session_id,
                                       uint64_t max_object_count,
                                       vector<uint64_t>* object_list) {
  if (!object_list || object_list->size() > 0)
    LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  vector<int> tmp;
  CK_RV result = session->FindObjects(max_object_count, &tmp);
  if (result == CKR_OK) {
    for (size_t i = 0; i < tmp.size(); ++i) {
      object_list->push_back(static_cast<uint64_t>(tmp[i]));
    }
  }
  return result;
}

uint32_t ChapsServiceImpl::FindObjectsFinal(
    const SecureBlob& isolate_credential, uint64_t session_id) {
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  return session->FindObjectsFinal();
}

uint32_t ChapsServiceImpl::EncryptInit(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    uint64_t key_handle) {
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  const Object* key = NULL;
  LOG_CK_RV_AND_RETURN_IF(!session->GetObject(key_handle, &key),
                          CKR_KEY_HANDLE_INVALID);
  CHECK(key);
  return session->OperationInit(kEncrypt, mechanism_type,
                                ConvertByteVectorToString(mechanism_parameter),
                                key);
}

uint32_t ChapsServiceImpl::Encrypt(const SecureBlob& 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) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  *actual_out_length = max_out_length;
  return session->OperationSinglePart(
      kEncrypt, ConvertByteVectorToString(data_in),
      PreservedValue<uint64_t, int>(actual_out_length),
      PreservedByteVector(data_out));
}

uint32_t ChapsServiceImpl::EncryptUpdate(const SecureBlob& 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) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  *actual_out_length = max_out_length;
  return session->OperationUpdate(
      kEncrypt, ConvertByteVectorToString(data_in),
      PreservedValue<uint64_t, int>(actual_out_length),
      PreservedByteVector(data_out));
}

uint32_t ChapsServiceImpl::EncryptFinal(const SecureBlob& isolate_credential,
                                        uint64_t session_id,
                                        uint64_t max_out_length,
                                        uint64_t* actual_out_length,
                                        vector<uint8_t>* data_out) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  *actual_out_length = max_out_length;
  return session->OperationFinal(
      kEncrypt, PreservedValue<uint64_t, int>(actual_out_length),
      PreservedByteVector(data_out));
}

void ChapsServiceImpl::EncryptCancel(const SecureBlob& isolate_credential,
                                     uint64_t session_id) {
  Session* session = NULL;
  if (!slot_manager_->GetSession(isolate_credential, session_id, &session))
    return;
  CHECK(session);
  session->OperationCancel(kEncrypt);
}

uint32_t ChapsServiceImpl::DecryptInit(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    uint64_t key_handle) {
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  const Object* key = NULL;
  LOG_CK_RV_AND_RETURN_IF(!session->GetObject(key_handle, &key),
                          CKR_KEY_HANDLE_INVALID);
  CHECK(key);
  return session->OperationInit(kDecrypt, mechanism_type,
                                ConvertByteVectorToString(mechanism_parameter),
                                key);
}

uint32_t ChapsServiceImpl::Decrypt(const SecureBlob& 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) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  *actual_out_length = max_out_length;
  return session->OperationSinglePart(
      kDecrypt, ConvertByteVectorToString(data_in),
      PreservedValue<uint64_t, int>(actual_out_length),
      PreservedByteVector(data_out));
}

uint32_t ChapsServiceImpl::DecryptUpdate(const SecureBlob& 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) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  *actual_out_length = max_out_length;
  return session->OperationUpdate(
      kDecrypt, ConvertByteVectorToString(data_in),
      PreservedValue<uint64_t, int>(actual_out_length),
      PreservedByteVector(data_out));
}

uint32_t ChapsServiceImpl::DecryptFinal(const SecureBlob& isolate_credential,
                                        uint64_t session_id,
                                        uint64_t max_out_length,
                                        uint64_t* actual_out_length,
                                        vector<uint8_t>* data_out) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  *actual_out_length = max_out_length;
  return session->OperationFinal(
      kDecrypt, PreservedValue<uint64_t, int>(actual_out_length),
      PreservedByteVector(data_out));
}

void ChapsServiceImpl::DecryptCancel(const SecureBlob& isolate_credential,
                                     uint64_t session_id) {
  Session* session = NULL;
  if (!slot_manager_->GetSession(isolate_credential, session_id, &session))
    return;
  CHECK(session);
  session->OperationCancel(kDecrypt);
}

uint32_t ChapsServiceImpl::DigestInit(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter) {
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  return session->OperationInit(kDigest, mechanism_type,
                                ConvertByteVectorToString(mechanism_parameter),
                                NULL);
}

uint32_t ChapsServiceImpl::Digest(const SecureBlob& 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) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !digest, CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  *actual_out_length = max_out_length;
  return session->OperationSinglePart(
      kDigest, ConvertByteVectorToString(data_in),
      PreservedValue<uint64_t, int>(actual_out_length),
      PreservedByteVector(digest));
}

uint32_t ChapsServiceImpl::DigestUpdate(const SecureBlob& isolate_credential,
                                        uint64_t session_id,
                                        const vector<uint8_t>& data_in) {
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  return session->OperationUpdate(kDigest, ConvertByteVectorToString(data_in),
                                  NULL, NULL);
}

uint32_t ChapsServiceImpl::DigestKey(const SecureBlob& isolate_credential,
                                     uint64_t session_id,
                                     uint64_t key_handle) {
  // We don't give out key digests.
  LOG_CK_RV_AND_RETURN(CKR_KEY_INDIGESTIBLE);
}

uint32_t ChapsServiceImpl::DigestFinal(const SecureBlob& isolate_credential,
                                       uint64_t session_id,
                                       uint64_t max_out_length,
                                       uint64_t* actual_out_length,
                                       vector<uint8_t>* digest) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !digest, CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  *actual_out_length = max_out_length;
  return session->OperationFinal(
      kDigest, PreservedValue<uint64_t, int>(actual_out_length),
      PreservedByteVector(digest));
}

void ChapsServiceImpl::DigestCancel(const SecureBlob& isolate_credential,
                                    uint64_t session_id) {
  Session* session = NULL;
  if (!slot_manager_->GetSession(isolate_credential, session_id, &session))
    return;
  CHECK(session);
  session->OperationCancel(kDigest);
}

uint32_t ChapsServiceImpl::SignInit(const SecureBlob& isolate_credential,
                                    uint64_t session_id,
                                    uint64_t mechanism_type,
                                    const vector<uint8_t>& mechanism_parameter,
                                    uint64_t key_handle) {
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  const Object* key = NULL;
  LOG_CK_RV_AND_RETURN_IF(!session->GetObject(key_handle, &key),
                          CKR_KEY_HANDLE_INVALID);
  CHECK(key);
  return session->OperationInit(kSign, mechanism_type,
                                ConvertByteVectorToString(mechanism_parameter),
                                key);
}

uint32_t ChapsServiceImpl::Sign(const SecureBlob& 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) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !signature, CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  *actual_out_length = max_out_length;
  return session->OperationSinglePart(
      kSign, ConvertByteVectorToString(data),
      PreservedValue<uint64_t, int>(actual_out_length),
      PreservedByteVector(signature));
}

uint32_t ChapsServiceImpl::SignUpdate(const SecureBlob& isolate_credential,
                                      uint64_t session_id,
                                      const vector<uint8_t>& data_part) {
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  return session->OperationUpdate(kSign, ConvertByteVectorToString(data_part),
                                  NULL, NULL);
}

uint32_t ChapsServiceImpl::SignFinal(const SecureBlob& isolate_credential,
                                     uint64_t session_id,
                                     uint64_t max_out_length,
                                     uint64_t* actual_out_length,
                                     vector<uint8_t>* signature) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !signature, CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  *actual_out_length = max_out_length;
  return session->OperationFinal(
      kSign, PreservedValue<uint64_t, int>(actual_out_length),
      PreservedByteVector(signature));
}

void ChapsServiceImpl::SignCancel(const SecureBlob& isolate_credential,
                                  uint64_t session_id) {
  Session* session = NULL;
  if (!slot_manager_->GetSession(isolate_credential, session_id, &session))
    return;
  CHECK(session);
  session->OperationCancel(kSign);
}

uint32_t ChapsServiceImpl::SignRecoverInit(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    uint64_t key_handle) {
  LOG_CK_RV_AND_RETURN(CKR_FUNCTION_NOT_SUPPORTED);
}

uint32_t ChapsServiceImpl::SignRecover(const SecureBlob& 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) {
  LOG_CK_RV_AND_RETURN(CKR_FUNCTION_NOT_SUPPORTED);
}

uint32_t ChapsServiceImpl::VerifyInit(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    uint64_t key_handle) {
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  const Object* key = NULL;
  LOG_CK_RV_AND_RETURN_IF(!session->GetObject(key_handle, &key),
                          CKR_KEY_HANDLE_INVALID);
  CHECK(key);
  return session->OperationInit(kVerify, mechanism_type,
                                ConvertByteVectorToString(mechanism_parameter),
                                key);
}

uint32_t ChapsServiceImpl::Verify(const SecureBlob& isolate_credential,
                                  uint64_t session_id,
                                  const vector<uint8_t>& data,
                                  const vector<uint8_t>& signature) {
  CK_RV result = VerifyUpdate(isolate_credential, session_id, data);
  if (result == CKR_OK)
    result = VerifyFinal(isolate_credential, session_id, signature);
  return result;
}

uint32_t ChapsServiceImpl::VerifyUpdate(const SecureBlob& isolate_credential,
                                        uint64_t session_id,
                                        const vector<uint8_t>& data_part) {
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  return session->OperationUpdate(kVerify, ConvertByteVectorToString(data_part),
                                  NULL, NULL);
}

uint32_t ChapsServiceImpl::VerifyFinal(const SecureBlob& isolate_credential,
                                       uint64_t session_id,
                                       const vector<uint8_t>& signature) {
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  return session->VerifyFinal(ConvertByteVectorToString(signature));
}

void ChapsServiceImpl::VerifyCancel(const SecureBlob& isolate_credential,
                                    uint64_t session_id) {
  Session* session = NULL;
  if (!slot_manager_->GetSession(isolate_credential, session_id, &session))
    return;
  CHECK(session);
  session->OperationCancel(kVerify);
}

uint32_t ChapsServiceImpl::VerifyRecoverInit(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    uint64_t key_handle) {
  LOG_CK_RV_AND_RETURN(CKR_FUNCTION_NOT_SUPPORTED);
}

uint32_t ChapsServiceImpl::VerifyRecover(const SecureBlob& 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) {
  LOG_CK_RV_AND_RETURN(CKR_FUNCTION_NOT_SUPPORTED);
}

uint32_t ChapsServiceImpl::DigestEncryptUpdate(
    const SecureBlob& 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) {
  LOG_CK_RV_AND_RETURN(CKR_FUNCTION_NOT_SUPPORTED);
}

uint32_t ChapsServiceImpl::DecryptDigestUpdate(
    const SecureBlob& 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) {
  LOG_CK_RV_AND_RETURN(CKR_FUNCTION_NOT_SUPPORTED);
}

uint32_t ChapsServiceImpl::SignEncryptUpdate(
    const SecureBlob& 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) {
  LOG_CK_RV_AND_RETURN(CKR_FUNCTION_NOT_SUPPORTED);
}

uint32_t ChapsServiceImpl::DecryptVerifyUpdate(
    const SecureBlob& 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) {
  LOG_CK_RV_AND_RETURN(CKR_FUNCTION_NOT_SUPPORTED);
}

uint32_t ChapsServiceImpl::GenerateKey(
    const SecureBlob& 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) {
  LOG_CK_RV_AND_RETURN_IF(!key_handle, CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  Attributes tmp;
  LOG_CK_RV_AND_RETURN_IF(!tmp.Parse(attributes), CKR_TEMPLATE_INCONSISTENT);
  return session->GenerateKey(mechanism_type,
                              ConvertByteVectorToString(mechanism_parameter),
                              tmp.attributes(), tmp.num_attributes(),
                              PreservedValue<uint64_t, int>(key_handle));
}

uint32_t ChapsServiceImpl::GenerateKeyPair(
    const SecureBlob& 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) {
  LOG_CK_RV_AND_RETURN_IF(!public_key_handle || !private_key_handle,
                          CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  Attributes tmp_public;
  LOG_CK_RV_AND_RETURN_IF(!tmp_public.Parse(public_attributes),
                          CKR_TEMPLATE_INCONSISTENT);
  Attributes tmp_private;
  LOG_CK_RV_AND_RETURN_IF(!tmp_private.Parse(private_attributes),
                          CKR_TEMPLATE_INCONSISTENT);
  return session->GenerateKeyPair(
      mechanism_type, ConvertByteVectorToString(mechanism_parameter),
      tmp_public.attributes(), tmp_public.num_attributes(),
      tmp_private.attributes(), tmp_private.num_attributes(),
      PreservedValue<uint64_t, int>(public_key_handle),
      PreservedValue<uint64_t, int>(private_key_handle));
}

uint32_t ChapsServiceImpl::WrapKey(const SecureBlob& 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) {
  LOG_CK_RV_AND_RETURN(CKR_FUNCTION_NOT_SUPPORTED);
}

uint32_t ChapsServiceImpl::UnwrapKey(const SecureBlob& 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) {
  LOG_CK_RV_AND_RETURN(CKR_FUNCTION_NOT_SUPPORTED);
}

uint32_t ChapsServiceImpl::DeriveKey(const SecureBlob& 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) {
  LOG_CK_RV_AND_RETURN(CKR_FUNCTION_NOT_SUPPORTED);
}

uint32_t ChapsServiceImpl::SeedRandom(const SecureBlob& isolate_credential,
                                      uint64_t session_id,
                                      const vector<uint8_t>& seed) {
  LOG_CK_RV_AND_RETURN_IF(seed.size() == 0, CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  session->SeedRandom(ConvertByteVectorToString(seed));
  return CKR_OK;
}

uint32_t ChapsServiceImpl::GenerateRandom(const SecureBlob& isolate_credential,
                                          uint64_t session_id,
                                          uint64_t num_bytes,
                                          vector<uint8_t>* random_data) {
  LOG_CK_RV_AND_RETURN_IF(!random_data || num_bytes == 0, CKR_ARGUMENTS_BAD);
  Session* session = NULL;
  LOG_CK_RV_AND_RETURN_IF(
      !slot_manager_->GetSession(isolate_credential, session_id, &session),
      CKR_SESSION_HANDLE_INVALID);
  CHECK(session);
  session->GenerateRandom(num_bytes, PreservedByteVector(random_data));
  return CKR_OK;
}

}  // namespace chaps
