blob: 309fdb1095895b5331340a0bdd0fdec8c7bc3ee9 [file] [log] [blame]
/*
* Copyright 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "trusty_keymaster.h"
#include "secure_storage_manager.h"
#include <lib/keybox/client/keybox.h>
#include <uapi/err.h>
#include <memory>
namespace keymaster {
GetVersion2Response TrustyKeymaster::GetVersion2(
const GetVersion2Request& req) {
switch (req.max_message_version) {
case 3:
context_->SetKmVersion(KmVersion::KEYMASTER_4);
break;
case 4:
context_->SetKmVersion(KmVersion::KEYMINT_3);
break;
default:
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
// In a fuzzing build, if the fuzzer sends invalid messages we should
// log an error and continue, to allow the fuzzer to explore more of the
// code.
LOG_E("HAL sent invalid message version %d, struggling on as fuzzing build",
req.max_message_version);
context_->SetKmVersion((req.max_message_version & 0x01)
? KmVersion::KEYMINT_3
: KmVersion::KEYMASTER_4);
#else
// By default, if the HAL service is sending invalid messages then the
// safest thing to do is to terminate.
LOG_E("HAL sent invalid message version %d, crashing",
req.max_message_version);
abort();
#endif
}
return AndroidKeymaster::GetVersion2(req);
}
long TrustyKeymaster::GetAuthTokenKey(keymaster_key_blob_t* key) {
keymaster_error_t error = context_->GetAuthTokenKey(key);
if (error != KM_ERROR_OK)
return ERR_GENERIC;
return NO_ERROR;
}
std::unique_ptr<cppbor::Map> TrustyKeymaster::GetDeviceInfo() {
return context_->GetDeviceIds();
}
void TrustyKeymaster::SetBootParams(const SetBootParamsRequest& request,
SetBootParamsResponse* response) {
if (response == nullptr)
return;
response->error = context_->SetBootParams(
request.os_version, request.os_patchlevel,
request.verified_boot_key, request.verified_boot_state,
request.device_locked, request.verified_boot_hash);
}
AttestationKeySlot keymaster_algorithm_to_key_slot(
keymaster_algorithm_t algorithm) {
switch (algorithm) {
case KM_ALGORITHM_RSA:
return AttestationKeySlot::kRsa;
case KM_ALGORITHM_EC:
return AttestationKeySlot::kEcdsa;
default:
return AttestationKeySlot::kInvalid;
}
}
void TrustyKeymaster::SetAttestationKey(const SetAttestationKeyRequest& request,
SetAttestationKeyResponse* response) {
if (response == nullptr)
return;
SecureStorageManager* ss_manager = SecureStorageManager::get_instance();
if (ss_manager == nullptr) {
response->error = KM_ERROR_SECURE_HW_COMMUNICATION_FAILED;
return;
}
size_t key_size = request.key_data.buffer_size();
const uint8_t* key = request.key_data.begin();
AttestationKeySlot key_slot;
key_slot = keymaster_algorithm_to_key_slot(request.algorithm);
if (key_slot == AttestationKeySlot::kInvalid) {
response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
return;
}
if (key_size == 0) {
response->error = KM_ERROR_INVALID_INPUT_LENGTH;
return;
}
response->error = ss_manager->WriteKeyToStorage(key_slot, key, key_size);
}
void TrustyKeymaster::DestroyAttestationIds(
const DestroyAttestationIdsRequest& request,
DestroyAttestationIdsResponse* response) {
if (response == nullptr) {
return;
}
SecureStorageManager* ss_manager = SecureStorageManager::get_instance();
if (ss_manager == nullptr) {
response->error = KM_ERROR_SECURE_HW_COMMUNICATION_FAILED;
return;
}
response->error = ss_manager->ClearAttestationIds();
}
void TrustyKeymaster::SetAttestationIds(const SetAttestationIdsRequest& request,
EmptyKeymasterResponse* response) {
if (response == nullptr) {
return;
}
SecureStorageManager* ss_manager = SecureStorageManager::get_instance();
if (ss_manager == nullptr) {
response->error = KM_ERROR_SECURE_HW_COMMUNICATION_FAILED;
return;
}
response->error = ss_manager->SetAttestationIds(request);
}
void TrustyKeymaster::SetAttestationIdsKM3(
const SetAttestationIdsKM3Request& request,
EmptyKeymasterResponse* response) {
if (response == nullptr) {
return;
}
SecureStorageManager* ss_manager = SecureStorageManager::get_instance();
if (ss_manager == nullptr) {
response->error = KM_ERROR_SECURE_HW_COMMUNICATION_FAILED;
return;
}
response->error = ss_manager->SetAttestationIdsKM3(request);
}
void TrustyKeymaster::SetWrappedAttestationKey(
const SetAttestationKeyRequest& request,
SetAttestationKeyResponse* response) {
if (response == nullptr) {
return;
}
AttestationKeySlot key_slot =
keymaster_algorithm_to_key_slot(request.algorithm);
if (key_slot == AttestationKeySlot::kInvalid) {
response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
return;
}
/*
* This assumes unwrapping decreases size.
* If it doesn't, the unwrap call will fail.
*/
size_t unwrapped_buf_size = request.key_data.buffer_size();
size_t unwrapped_key_size;
std::unique_ptr<uint8_t[]> unwrapped_key(
new (std::nothrow) uint8_t[unwrapped_buf_size]);
if (!unwrapped_key) {
response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
return;
}
int rc = keybox_unwrap(request.key_data.begin(),
request.key_data.buffer_size(), unwrapped_key.get(),
unwrapped_buf_size, &unwrapped_key_size);
if (rc != NO_ERROR) {
response->error = KM_ERROR_VERIFICATION_FAILED;
return;
}
SecureStorageManager* ss_manager = SecureStorageManager::get_instance();
if (ss_manager == nullptr) {
response->error = KM_ERROR_SECURE_HW_COMMUNICATION_FAILED;
return;
}
response->error = ss_manager->WriteKeyToStorage(
key_slot, unwrapped_key.get(), unwrapped_key_size);
}
void TrustyKeymaster::ClearAttestationCertChain(
const ClearAttestationCertChainRequest& request,
ClearAttestationCertChainResponse* response) {
if (response == nullptr)
return;
SecureStorageManager* ss_manager = SecureStorageManager::get_instance();
if (ss_manager == nullptr) {
response->error = KM_ERROR_SECURE_HW_COMMUNICATION_FAILED;
return;
}
AttestationKeySlot key_slot;
key_slot = keymaster_algorithm_to_key_slot(request.algorithm);
if (key_slot == AttestationKeySlot::kInvalid) {
response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
return;
}
keymaster_error_t err = ss_manager->DeleteCertChainFromStorage(key_slot);
if (err != KM_ERROR_OK) {
LOG_E("Failed to delete cert chain.\n");
response->error = err;
return;
}
uint32_t cert_chain_length = 0;
err = ss_manager->ReadCertChainLength(key_slot, &cert_chain_length);
if (err != KM_ERROR_OK) {
LOG_E("Failed to read cert chain length.\n");
response->error = err;
return;
}
if (cert_chain_length != 0) {
LOG_E("Cert chain could not be deleted.\n");
response->error = err;
return;
}
response->error = KM_ERROR_OK;
}
void TrustyKeymaster::AppendAttestationCertChain(
const AppendAttestationCertChainRequest& request,
AppendAttestationCertChainResponse* response) {
if (response == nullptr)
return;
SecureStorageManager* ss_manager = SecureStorageManager::get_instance();
if (ss_manager == nullptr) {
response->error = KM_ERROR_SECURE_HW_COMMUNICATION_FAILED;
return;
}
size_t cert_size = request.cert_data.buffer_size();
const uint8_t* cert = request.cert_data.begin();
AttestationKeySlot key_slot;
response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
switch (request.algorithm) {
case KM_ALGORITHM_RSA:
key_slot = AttestationKeySlot::kRsa;
break;
case KM_ALGORITHM_EC:
key_slot = AttestationKeySlot::kEcdsa;
break;
default:
return;
}
response->error = KM_ERROR_INVALID_INPUT_LENGTH;
if (cert_size == 0) {
return;
}
uint32_t cert_chain_length = 0;
if (ss_manager->ReadCertChainLength(key_slot, &cert_chain_length) !=
KM_ERROR_OK) {
LOG_E("Failed to read cert chain length, initialize to 0.\n");
cert_chain_length = 0;
}
response->error = ss_manager->WriteCertToStorage(key_slot, cert, cert_size,
cert_chain_length);
}
void TrustyKeymaster::AtapGetCaRequest(const AtapGetCaRequestRequest& request,
AtapGetCaRequestResponse* response) {
if (response == nullptr)
return;
// Not implemented.
response->error = KM_ERROR_UNKNOWN_ERROR;
}
void TrustyKeymaster::AtapSetCaResponseBegin(
const AtapSetCaResponseBeginRequest& request,
AtapSetCaResponseBeginResponse* response) {
if (response == nullptr)
return;
// Not implemented.
response->error = KM_ERROR_UNKNOWN_ERROR;
}
void TrustyKeymaster::AtapSetCaResponseUpdate(
const AtapSetCaResponseUpdateRequest& request,
AtapSetCaResponseUpdateResponse* response) {
if (response == nullptr)
return;
// Not implemented.
response->error = KM_ERROR_UNKNOWN_ERROR;
}
void TrustyKeymaster::AtapSetCaResponseFinish(
const AtapSetCaResponseFinishRequest& request,
AtapSetCaResponseFinishResponse* response) {
if (response == nullptr)
return;
// Not implemented.
response->error = KM_ERROR_UNKNOWN_ERROR;
}
void TrustyKeymaster::AtapReadUuid(const AtapReadUuidRequest& request,
AtapReadUuidResponse* response) {
if (response == nullptr)
return;
SecureStorageManager* ss_manager = SecureStorageManager::get_instance();
if (ss_manager == nullptr) {
response->error = KM_ERROR_SECURE_HW_COMMUNICATION_FAILED;
return;
}
uint8_t uuid[kAttestationUuidSize]{};
response->error = ss_manager->ReadAttestationUuid(uuid);
if (response->error == KM_ERROR_OK) {
response->data.reserve(kAttestationUuidSize);
response->data.write(uuid, kAttestationUuidSize);
}
}
void TrustyKeymaster::AtapSetProductId(const AtapSetProductIdRequest& request,
AtapSetProductIdResponse* response) {
if (response == nullptr)
return;
SecureStorageManager* ss_manager = SecureStorageManager::get_instance();
if (ss_manager == nullptr) {
response->error = KM_ERROR_SECURE_HW_COMMUNICATION_FAILED;
return;
}
// Not implemented.
response->error = KM_ERROR_UNKNOWN_ERROR;
}
} // namespace keymaster