1 /*
2 **
3 ** Copyright 2017, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 #ifndef SYSTEM_KEYMASTER_KEYMASTER_PASSTHROUGH_OPERATION_H_
19 #define SYSTEM_KEYMASTER_KEYMASTER_PASSTHROUGH_OPERATION_H_
20 
21 #include <hardware/keymaster1.h>
22 #include <hardware/keymaster2.h>
23 
24 #include <keymaster/legacy_support/keymaster_passthrough_key.h>
25 #include <keymaster/operation.h>
26 
27 namespace keymaster {
28 
29 class AuthorizationSet;
30 class Key;
31 class Operation;
32 
33 /**
34  * Template implementation for KM1 and KM2 operations
35  */
36 template <typename KeymasterDeviceType> class KeymasterPassthroughOperation : public Operation {
37   public:
KeymasterPassthroughOperation(keymaster_purpose_t purpose,const KeymasterDeviceType * km_device,Key && key)38     explicit KeymasterPassthroughOperation(keymaster_purpose_t purpose,
39                                            const KeymasterDeviceType* km_device, Key&& key)
40         : Operation(purpose, key.hw_enforced_move(), key.sw_enforced_move()),
41           key_blob_(key.key_material_move()), km_device_(km_device) {
42         operation_handle_ = 0;
43     }
~KeymasterPassthroughOperation()44     virtual ~KeymasterPassthroughOperation() {}
45 
Begin(const AuthorizationSet & input_params,AuthorizationSet * output_params)46     keymaster_error_t Begin(const AuthorizationSet& input_params,
47                             AuthorizationSet* output_params) override {
48         keymaster_key_param_set_t out_params = {};
49         keymaster_error_t rc;
50         rc = km_device_->begin(km_device_, purpose(), &key_blob_, &input_params, &out_params,
51                                &operation_handle_);
52         if (rc == KM_ERROR_OK && output_params) output_params->Reinitialize(out_params);
53         keymaster_free_param_set(&out_params);
54         return rc;
55     }
Update(const AuthorizationSet & input_params,const Buffer & input,AuthorizationSet * output_params,Buffer * output,size_t * input_consumed)56     keymaster_error_t Update(const AuthorizationSet& input_params, const Buffer& input,
57                              AuthorizationSet* output_params, Buffer* output,
58                              size_t* input_consumed) override {
59         keymaster_key_param_set_t out_params = {};
60         keymaster_blob_t in{input.peek_read(), input.available_read()};
61         keymaster_blob_t out = {};
62         keymaster_error_t rc;
63         rc = km_device_->update(km_device_, operation_handle_, &input_params, &in, input_consumed,
64                                 &out_params, &out);
65         if (rc == KM_ERROR_OK) {
66             if (output) output->Reinitialize(out.data, out.data_length);
67             if (output_params) output_params->Reinitialize(out_params);
68         }
69         keymaster_free_param_set(&out_params);
70         free(const_cast<uint8_t*>(out.data));
71         return rc;
72     }
73     keymaster_error_t Finish(const AuthorizationSet& input_params, const Buffer& input,
74                              const Buffer& signature, AuthorizationSet* output_params,
75                              Buffer* output) override;
Abort()76     keymaster_error_t Abort() { return km_device_->abort(km_device_, operation_handle_); }
77 
78   private:
79     KeymasterKeyBlob key_blob_;
80     const KeymasterDeviceType* km_device_;
81 };
82 
83 template <>
84 keymaster_error_t KeymasterPassthroughOperation<keymaster1_device_t>::Finish(
85     const AuthorizationSet& input_params, const Buffer& input, const Buffer& signature,
86     AuthorizationSet* output_params, Buffer* output);
87 template <>
88 keymaster_error_t KeymasterPassthroughOperation<keymaster2_device_t>::Finish(
89     const AuthorizationSet& input_params, const Buffer& input, const Buffer& signature,
90     AuthorizationSet* output_params, Buffer* output);
91 
92 template <typename KeymasterDeviceType>
93 class KeymasterPassthroughOperationFactory : public OperationFactory {
94   public:
KeymasterPassthroughOperationFactory(keymaster_algorithm_t algorithm,keymaster_purpose_t purpose,const KeymasterDeviceType * km_device)95     KeymasterPassthroughOperationFactory(keymaster_algorithm_t algorithm,
96                                          keymaster_purpose_t purpose,
97                                          const KeymasterDeviceType* km_device)
98         : key_type_(algorithm, purpose), km_device_(km_device) {}
~KeymasterPassthroughOperationFactory()99     virtual ~KeymasterPassthroughOperationFactory() {}
100 
registry_key()101     KeyType registry_key() const override { return key_type_; }
102 
103     // Factory methods
CreateOperation(Key && key,const AuthorizationSet &,keymaster_error_t * error)104     OperationPtr CreateOperation(Key&& key, const AuthorizationSet& /*begin_params*/,
105                                  keymaster_error_t* error) override {
106         if (!error) return nullptr;
107         *error = KM_ERROR_OK;
108         OperationPtr op(new (std::nothrow) KeymasterPassthroughOperation<KeymasterDeviceType>(
109             key_type_.purpose, km_device_, std::move(key)));
110         if (!op) {
111             *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
112         }
113         return op;
114     }
115 
116     // Informational methods.  The returned arrays reference static memory and must not be
117     // deallocated or modified.
SupportedPaddingModes(size_t * padding_count)118     const keymaster_padding_t* SupportedPaddingModes(size_t* padding_count) const override {
119         *padding_count = 0;
120         return nullptr;
121     }
SupportedBlockModes(size_t * block_mode_count)122     const keymaster_block_mode_t* SupportedBlockModes(size_t* block_mode_count) const override {
123         *block_mode_count = 0;
124         return nullptr;
125     }
SupportedDigests(size_t * digest_count)126     const keymaster_digest_t* SupportedDigests(size_t* digest_count) const override {
127         *digest_count = 0;
128         return nullptr;
129     }
130 
131   private:
132     KeyType key_type_;
133     const KeymasterDeviceType* km_device_;
134 };
135 
136 }  // namespace keymaster
137 
138 #endif  // SYSTEM_KEYMASTER_KEYMASTER_PASSTHROUGH_OPERATION_H_
139