summaryrefslogtreecommitdiffstats
path: root/legacy_support/keymaster_passthrough_operation.h
blob: 29c0372f69aa616d3bc635a415d2731896ea4853 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
**
** 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_