139 lines
5.5 KiB
C
139 lines
5.5 KiB
C
|
/*
|
||
|
**
|
||
|
** 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.
|
||
|
*/
|
||
|
|
||
|
#ifndef SYSTEM_KEYMASTER_KEYMASTER_PASSTHROUGH_OPERATION_H_
|
||
|
#define SYSTEM_KEYMASTER_KEYMASTER_PASSTHROUGH_OPERATION_H_
|
||
|
|
||
|
#include <hardware/keymaster1.h>
|
||
|
#include <hardware/keymaster2.h>
|
||
|
|
||
|
#include <keymaster/legacy_support/keymaster_passthrough_key.h>
|
||
|
#include <keymaster/operation.h>
|
||
|
|
||
|
namespace keymaster {
|
||
|
|
||
|
class AuthorizationSet;
|
||
|
class Key;
|
||
|
class Operation;
|
||
|
|
||
|
/**
|
||
|
* Template implementation for KM1 and KM2 operations
|
||
|
*/
|
||
|
template <typename KeymasterDeviceType> class KeymasterPassthroughOperation : public Operation {
|
||
|
public:
|
||
|
explicit KeymasterPassthroughOperation(keymaster_purpose_t purpose,
|
||
|
const KeymasterDeviceType* km_device, Key&& key)
|
||
|
: Operation(purpose, key.hw_enforced_move(), key.sw_enforced_move()),
|
||
|
key_blob_(key.key_material_move()), km_device_(km_device) {
|
||
|
operation_handle_ = 0;
|
||
|
}
|
||
|
virtual ~KeymasterPassthroughOperation() {}
|
||
|
|
||
|
keymaster_error_t Begin(const AuthorizationSet& input_params,
|
||
|
AuthorizationSet* output_params) override {
|
||
|
keymaster_key_param_set_t out_params = {};
|
||
|
keymaster_error_t rc;
|
||
|
rc = km_device_->begin(km_device_, purpose(), &key_blob_, &input_params, &out_params,
|
||
|
&operation_handle_);
|
||
|
if (rc == KM_ERROR_OK && output_params) output_params->Reinitialize(out_params);
|
||
|
keymaster_free_param_set(&out_params);
|
||
|
return rc;
|
||
|
}
|
||
|
keymaster_error_t Update(const AuthorizationSet& input_params, const Buffer& input,
|
||
|
AuthorizationSet* output_params, Buffer* output,
|
||
|
size_t* input_consumed) override {
|
||
|
keymaster_key_param_set_t out_params = {};
|
||
|
keymaster_blob_t in{input.peek_read(), input.available_read()};
|
||
|
keymaster_blob_t out = {};
|
||
|
keymaster_error_t rc;
|
||
|
rc = km_device_->update(km_device_, operation_handle_, &input_params, &in, input_consumed,
|
||
|
&out_params, &out);
|
||
|
if (rc == KM_ERROR_OK) {
|
||
|
if (output) output->Reinitialize(out.data, out.data_length);
|
||
|
if (output_params) output_params->Reinitialize(out_params);
|
||
|
}
|
||
|
keymaster_free_param_set(&out_params);
|
||
|
free(const_cast<uint8_t*>(out.data));
|
||
|
return rc;
|
||
|
}
|
||
|
keymaster_error_t Finish(const AuthorizationSet& input_params, const Buffer& input,
|
||
|
const Buffer& signature, AuthorizationSet* output_params,
|
||
|
Buffer* output) override;
|
||
|
keymaster_error_t Abort() { return km_device_->abort(km_device_, operation_handle_); }
|
||
|
|
||
|
private:
|
||
|
KeymasterKeyBlob key_blob_;
|
||
|
const KeymasterDeviceType* km_device_;
|
||
|
};
|
||
|
|
||
|
template <>
|
||
|
keymaster_error_t KeymasterPassthroughOperation<keymaster1_device_t>::Finish(
|
||
|
const AuthorizationSet& input_params, const Buffer& input, const Buffer& signature,
|
||
|
AuthorizationSet* output_params, Buffer* output);
|
||
|
template <>
|
||
|
keymaster_error_t KeymasterPassthroughOperation<keymaster2_device_t>::Finish(
|
||
|
const AuthorizationSet& input_params, const Buffer& input, const Buffer& signature,
|
||
|
AuthorizationSet* output_params, Buffer* output);
|
||
|
|
||
|
template <typename KeymasterDeviceType>
|
||
|
class KeymasterPassthroughOperationFactory : public OperationFactory {
|
||
|
public:
|
||
|
KeymasterPassthroughOperationFactory(keymaster_algorithm_t algorithm,
|
||
|
keymaster_purpose_t purpose,
|
||
|
const KeymasterDeviceType* km_device)
|
||
|
: key_type_(algorithm, purpose), km_device_(km_device) {}
|
||
|
virtual ~KeymasterPassthroughOperationFactory() {}
|
||
|
|
||
|
KeyType registry_key() const override { return key_type_; }
|
||
|
|
||
|
// Factory methods
|
||
|
OperationPtr CreateOperation(Key&& key, const AuthorizationSet& /*begin_params*/,
|
||
|
keymaster_error_t* error) override {
|
||
|
if (!error) return nullptr;
|
||
|
*error = KM_ERROR_OK;
|
||
|
OperationPtr op(new (std::nothrow) KeymasterPassthroughOperation<KeymasterDeviceType>(
|
||
|
key_type_.purpose, km_device_, std::move(key)));
|
||
|
if (!op) {
|
||
|
*error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
|
||
|
}
|
||
|
return op;
|
||
|
}
|
||
|
|
||
|
// Informational methods. The returned arrays reference static memory and must not be
|
||
|
// deallocated or modified.
|
||
|
const keymaster_padding_t* SupportedPaddingModes(size_t* padding_count) const override {
|
||
|
*padding_count = 0;
|
||
|
return nullptr;
|
||
|
}
|
||
|
const keymaster_block_mode_t* SupportedBlockModes(size_t* block_mode_count) const override {
|
||
|
*block_mode_count = 0;
|
||
|
return nullptr;
|
||
|
}
|
||
|
const keymaster_digest_t* SupportedDigests(size_t* digest_count) const override {
|
||
|
*digest_count = 0;
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
KeyType key_type_;
|
||
|
const KeymasterDeviceType* km_device_;
|
||
|
};
|
||
|
|
||
|
} // namespace keymaster
|
||
|
|
||
|
#endif // SYSTEM_KEYMASTER_KEYMASTER_PASSTHROUGH_OPERATION_H_
|