12fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis/*
22fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis**
32fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis** Copyright 2017, The Android Open Source Project
42fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis**
52fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis** Licensed under the Apache License, Version 2.0 (the "License");
62fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis** you may not use this file except in compliance with the License.
72fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis** You may obtain a copy of the License at
82fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis**
92fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis**     http://www.apache.org/licenses/LICENSE-2.0
102fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis**
112fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis** Unless required by applicable law or agreed to in writing, software
122fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis** distributed under the License is distributed on an "AS IS" BASIS,
132fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis** See the License for the specific language governing permissions and
152fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis** limitations under the License.
162fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis*/
172fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
182fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis#ifndef SYSTEM_KEYMASTER_KEYMASTER_PASSTHROUGH_OPERATION_H_
192fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis#define SYSTEM_KEYMASTER_KEYMASTER_PASSTHROUGH_OPERATION_H_
202fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
212fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis#include <hardware/keymaster1.h>
222fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis#include <hardware/keymaster2.h>
232fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
242fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis#include <keymaster/legacy_support/keymaster_passthrough_key.h>
252fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis#include <keymaster/operation.h>
262fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
272fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskisnamespace keymaster {
282fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
292fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskisclass AuthorizationSet;
302fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskisclass Key;
312fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskisclass Operation;
322fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
332fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis/**
342fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis * Template implementation for KM1 and KM2 operations
352fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis */
36deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willdentemplate <typename KeymasterDeviceType> class KeymasterPassthroughOperation : public Operation {
372fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis  public:
382fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    explicit KeymasterPassthroughOperation(keymaster_purpose_t purpose,
39deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden                                           const KeymasterDeviceType* km_device, Key&& key)
40deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden        : Operation(purpose, key.hw_enforced_move(), key.sw_enforced_move()),
41deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden          key_blob_(key.key_material_move()), km_device_(km_device) {
422fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        operation_handle_ = 0;
432fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    }
442fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    virtual ~KeymasterPassthroughOperation() {}
452fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
46deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden    keymaster_error_t Begin(const AuthorizationSet& input_params,
47deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden                            AuthorizationSet* output_params) override {
482fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        keymaster_key_param_set_t out_params = {};
492fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        keymaster_error_t rc;
502fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        rc = km_device_->begin(km_device_, purpose(), &key_blob_, &input_params, &out_params,
51deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden                               &operation_handle_);
522fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        if (rc == KM_ERROR_OK && output_params) output_params->Reinitialize(out_params);
532fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        keymaster_free_param_set(&out_params);
542fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        return rc;
552fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    }
562fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    keymaster_error_t Update(const AuthorizationSet& input_params, const Buffer& input,
572fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis                             AuthorizationSet* output_params, Buffer* output,
582fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis                             size_t* input_consumed) override {
592fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        keymaster_key_param_set_t out_params = {};
60deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden        keymaster_blob_t in{input.peek_read(), input.available_read()};
612fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        keymaster_blob_t out = {};
622fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        keymaster_error_t rc;
63deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden        rc = km_device_->update(km_device_, operation_handle_, &input_params, &in, input_consumed,
64deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden                                &out_params, &out);
652fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        if (rc == KM_ERROR_OK) {
662fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis            if (output) output->Reinitialize(out.data, out.data_length);
672fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis            if (output_params) output_params->Reinitialize(out_params);
682fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        }
692fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        keymaster_free_param_set(&out_params);
702fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        free(const_cast<uint8_t*>(out.data));
712fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        return rc;
722fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    }
732fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    keymaster_error_t Finish(const AuthorizationSet& input_params, const Buffer& input,
742fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis                             const Buffer& signature, AuthorizationSet* output_params,
752fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis                             Buffer* output) override;
76deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden    keymaster_error_t Abort() { return km_device_->abort(km_device_, operation_handle_); }
772fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
78deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden  private:
792fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    KeymasterKeyBlob key_blob_;
802fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    const KeymasterDeviceType* km_device_;
812fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis};
822fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
83deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willdentemplate <>
84deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willdenkeymaster_error_t KeymasterPassthroughOperation<keymaster1_device_t>::Finish(
85deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden    const AuthorizationSet& input_params, const Buffer& input, const Buffer& signature,
86deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden    AuthorizationSet* output_params, Buffer* output);
87deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willdentemplate <>
88deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willdenkeymaster_error_t KeymasterPassthroughOperation<keymaster2_device_t>::Finish(
89deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden    const AuthorizationSet& input_params, const Buffer& input, const Buffer& signature,
90deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden    AuthorizationSet* output_params, Buffer* output);
912fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
922fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskistemplate <typename KeymasterDeviceType>
93deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willdenclass KeymasterPassthroughOperationFactory : public OperationFactory {
942fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis  public:
952fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    KeymasterPassthroughOperationFactory(keymaster_algorithm_t algorithm,
96deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden                                         keymaster_purpose_t purpose,
97deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden                                         const KeymasterDeviceType* km_device)
98deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden        : key_type_(algorithm, purpose), km_device_(km_device) {}
992fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    virtual ~KeymasterPassthroughOperationFactory() {}
1002fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
101deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden    KeyType registry_key() const override { return key_type_; }
1022fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
1032fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    // Factory methods
104deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden    OperationPtr CreateOperation(Key&& key, const AuthorizationSet& /*begin_params*/,
1052fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis                                 keymaster_error_t* error) override {
1062fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        if (!error) return nullptr;
1072fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        *error = KM_ERROR_OK;
1082fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        OperationPtr op(new (std::nothrow) KeymasterPassthroughOperation<KeymasterDeviceType>(
109deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden            key_type_.purpose, km_device_, std::move(key)));
1102fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        if (!op) {
1112fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis            *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
1122fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        }
1132fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        return op;
1142fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    }
1152fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
1162fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    // Informational methods.  The returned arrays reference static memory and must not be
1172fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    // deallocated or modified.
1182fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    const keymaster_padding_t* SupportedPaddingModes(size_t* padding_count) const override {
1192fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        *padding_count = 0;
1202fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        return NULL;
1212fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    }
1222fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    const keymaster_block_mode_t* SupportedBlockModes(size_t* block_mode_count) const override {
1232fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        *block_mode_count = 0;
1242fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        return NULL;
1252fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    }
1262fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    const keymaster_digest_t* SupportedDigests(size_t* digest_count) const override {
1272fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        *digest_count = 0;
1282fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        return NULL;
1292fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    }
130deffcb7efaac94b2c674247cb9888a0af3d7e256Shawn Willden
1312fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis  private:
1322fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    KeyType key_type_;
1332fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    const KeymasterDeviceType* km_device_;
1342fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis};
1352fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
1362fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis}  // namespace keymaster
1372fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
1382fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis#endif  // SYSTEM_KEYMASTER_KEYMASTER_PASSTHROUGH_OPERATION_H_
139