blob: ec80ab58cef3f3a6fe5830e20f84c4fc2c68c5aa [file] [log] [blame]
Ethan Yonkerbd7492d2016-12-07 13:55:01 -06001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "Keymaster.h"
18
19//#include <android-base/logging.h>
20#include <hardware/hardware.h>
21#include <hardware/keymaster1.h>
22#include <hardware/keymaster2.h>
23
24#include <iostream>
25#define ERROR 1
26#define LOG(x) std::cout
27
28namespace android {
29namespace vold {
30
31class IKeymasterDevice {
32 public:
33 IKeymasterDevice() {}
34 virtual ~IKeymasterDevice() {}
35 /*virtual keymaster_error_t generate_key(const keymaster_key_param_set_t* params,
36 keymaster_key_blob_t* key_blob) const = 0;*/
37 virtual keymaster_error_t delete_key(const keymaster_key_blob_t* key) const = 0;
38 virtual keymaster_error_t begin(keymaster_purpose_t purpose, const keymaster_key_blob_t* key,
39 const keymaster_key_param_set_t* in_params,
40 keymaster_key_param_set_t* out_params,
41 keymaster_operation_handle_t* operation_handle) const = 0;
42 virtual keymaster_error_t update(keymaster_operation_handle_t operation_handle,
43 const keymaster_key_param_set_t* in_params,
44 const keymaster_blob_t* input, size_t* input_consumed,
45 keymaster_key_param_set_t* out_params,
46 keymaster_blob_t* output) const = 0;
47 virtual keymaster_error_t finish(keymaster_operation_handle_t operation_handle,
48 const keymaster_key_param_set_t* in_params,
49 const keymaster_blob_t* signature,
50 keymaster_key_param_set_t* out_params,
51 keymaster_blob_t* output) const = 0;
52 virtual keymaster_error_t abort(keymaster_operation_handle_t operation_handle) const = 0;
53
54 protected:
55 DISALLOW_COPY_AND_ASSIGN(IKeymasterDevice);
56};
57
58template <typename T> class KeymasterDevice : public IKeymasterDevice {
59 public:
60 KeymasterDevice(T* d) : mDevice{d} {}
61 /*keymaster_error_t generate_key(const keymaster_key_param_set_t* params,
62 keymaster_key_blob_t* key_blob) const override final {
63 return mDevice->generate_key(mDevice, params, key_blob, nullptr);
64 }*/
65 keymaster_error_t delete_key(const keymaster_key_blob_t* key) const override final {
66 if (mDevice->delete_key == nullptr) return KM_ERROR_OK;
67 return mDevice->delete_key(mDevice, key);
68 }
69 keymaster_error_t begin(keymaster_purpose_t purpose, const keymaster_key_blob_t* key,
70 const keymaster_key_param_set_t* in_params,
71 keymaster_key_param_set_t* out_params,
72 keymaster_operation_handle_t* operation_handle) const override final {
73 return mDevice->begin(mDevice, purpose, key, in_params, out_params, operation_handle);
74 }
75 keymaster_error_t update(keymaster_operation_handle_t operation_handle,
76 const keymaster_key_param_set_t* in_params,
77 const keymaster_blob_t* input, size_t* input_consumed,
78 keymaster_key_param_set_t* out_params,
79 keymaster_blob_t* output) const override final {
80 return mDevice->update(mDevice, operation_handle, in_params, input, input_consumed,
81 out_params, output);
82 }
83 keymaster_error_t abort(keymaster_operation_handle_t operation_handle) const override final {
84 return mDevice->abort(mDevice, operation_handle);
85 }
86
87 protected:
88 T* const mDevice;
89};
90
91class Keymaster1Device : public KeymasterDevice<keymaster1_device_t> {
92 public:
93 Keymaster1Device(keymaster1_device_t* d) : KeymasterDevice<keymaster1_device_t>{d} {}
94 ~Keymaster1Device() override final { keymaster1_close(mDevice); }
95 keymaster_error_t finish(keymaster_operation_handle_t operation_handle,
96 const keymaster_key_param_set_t* in_params,
97 const keymaster_blob_t* signature,
98 keymaster_key_param_set_t* out_params,
99 keymaster_blob_t* output) const override final {
100 return mDevice->finish(mDevice, operation_handle, in_params, signature, out_params, output);
101 }
102};
103
104class Keymaster2Device : public KeymasterDevice<keymaster2_device_t> {
105 public:
106 Keymaster2Device(keymaster2_device_t* d) : KeymasterDevice<keymaster2_device_t>{d} {}
107 ~Keymaster2Device() override final { keymaster2_close(mDevice); }
108 keymaster_error_t finish(keymaster_operation_handle_t operation_handle,
109 const keymaster_key_param_set_t* in_params,
110 const keymaster_blob_t* signature,
111 keymaster_key_param_set_t* out_params,
112 keymaster_blob_t* output) const override final {
113 return mDevice->finish(mDevice, operation_handle, in_params, nullptr, signature, out_params,
114 output);
115 }
116};
117
118KeymasterOperation::~KeymasterOperation() {
119 if (mDevice) mDevice->abort(mOpHandle);
120}
121
122bool KeymasterOperation::updateCompletely(const std::string& input, std::string* output) {
123 output->clear();
124 auto it = input.begin();
125 while (it != input.end()) {
126 size_t toRead = static_cast<size_t>(input.end() - it);
127 keymaster_blob_t inputBlob{reinterpret_cast<const uint8_t*>(&*it), toRead};
128 keymaster_blob_t outputBlob;
129 size_t inputConsumed;
130 auto error =
131 mDevice->update(mOpHandle, nullptr, &inputBlob, &inputConsumed, nullptr, &outputBlob);
132 if (error != KM_ERROR_OK) {
Captain Throwbacka5283b32020-02-19 12:11:23 -0500133 LOG(ERROR) << "update failed, code " << error << "\n";
Ethan Yonkerbd7492d2016-12-07 13:55:01 -0600134 mDevice = nullptr;
135 return false;
136 }
137 output->append(reinterpret_cast<const char*>(outputBlob.data), outputBlob.data_length);
138 free(const_cast<uint8_t*>(outputBlob.data));
139 if (inputConsumed > toRead) {
Captain Throwbacka5283b32020-02-19 12:11:23 -0500140 LOG(ERROR) << "update reported too much input consumed\n";
Ethan Yonkerbd7492d2016-12-07 13:55:01 -0600141 mDevice = nullptr;
142 return false;
143 }
144 it += inputConsumed;
145 }
146 return true;
147}
148
149bool KeymasterOperation::finish() {
150 auto error = mDevice->finish(mOpHandle, nullptr, nullptr, nullptr, nullptr);
151 mDevice = nullptr;
152 if (error != KM_ERROR_OK) {
Captain Throwbacka5283b32020-02-19 12:11:23 -0500153 LOG(ERROR) << "finish failed, code " << error << "\n";
Ethan Yonkerbd7492d2016-12-07 13:55:01 -0600154 return false;
155 }
156 return true;
157}
158
159bool KeymasterOperation::finishWithOutput(std::string* output) {
160 keymaster_blob_t outputBlob;
161 auto error = mDevice->finish(mOpHandle, nullptr, nullptr, nullptr, &outputBlob);
162 mDevice = nullptr;
163 if (error != KM_ERROR_OK) {
Captain Throwbacka5283b32020-02-19 12:11:23 -0500164 LOG(ERROR) << "finish failed, code " << error << "\n";
Ethan Yonkerbd7492d2016-12-07 13:55:01 -0600165 return false;
166 }
167 output->assign(reinterpret_cast<const char*>(outputBlob.data), outputBlob.data_length);
168 free(const_cast<uint8_t*>(outputBlob.data));
169 return true;
170}
171
172Keymaster::Keymaster() {
173 mDevice = nullptr;
174 const hw_module_t* module;
175 int ret = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &module);
176 if (ret != 0) {
Captain Throwbacka5283b32020-02-19 12:11:23 -0500177 LOG(ERROR) << "hw_get_module_by_class returned " << ret << "\n";
Ethan Yonkerbd7492d2016-12-07 13:55:01 -0600178 return;
179 }
180 if (module->module_api_version == KEYMASTER_MODULE_API_VERSION_1_0) {
181 keymaster1_device_t* device;
182 ret = keymaster1_open(module, &device);
183 if (ret != 0) {
Captain Throwbacka5283b32020-02-19 12:11:23 -0500184 LOG(ERROR) << "keymaster1_open returned " << ret << "\n";
Ethan Yonkerbd7492d2016-12-07 13:55:01 -0600185 return;
186 }
187 mDevice = std::make_shared<Keymaster1Device>(device);
188 } else if (module->module_api_version == KEYMASTER_MODULE_API_VERSION_2_0) {
189 keymaster2_device_t* device;
190 ret = keymaster2_open(module, &device);
191 if (ret != 0) {
Captain Throwbacka5283b32020-02-19 12:11:23 -0500192 LOG(ERROR) << "keymaster2_open returned " << ret << "\n";
Ethan Yonkerbd7492d2016-12-07 13:55:01 -0600193 return;
194 }
195 mDevice = std::make_shared<Keymaster2Device>(device);
196 } else {
Captain Throwbacka5283b32020-02-19 12:11:23 -0500197 LOG(ERROR) << "module_api_version is " << module->module_api_version << "\n";
Ethan Yonkerbd7492d2016-12-07 13:55:01 -0600198 return;
199 }
200}
201
202/*bool Keymaster::generateKey(const keymaster::AuthorizationSet& inParams, std::string* key) {
203 keymaster_key_blob_t keyBlob;
204 auto error = mDevice->generate_key(&inParams, &keyBlob);
205 if (error != KM_ERROR_OK) {
Captain Throwbacka5283b32020-02-19 12:11:23 -0500206 LOG(ERROR) << "generate_key failed, code " << error << "\n";
Ethan Yonkerbd7492d2016-12-07 13:55:01 -0600207 return false;
208 }
209 key->assign(reinterpret_cast<const char*>(keyBlob.key_material), keyBlob.key_material_size);
210 free(const_cast<uint8_t*>(keyBlob.key_material));
211 return true;
212}*/
213
214bool Keymaster::deleteKey(const std::string& key) {
215 keymaster_key_blob_t keyBlob{reinterpret_cast<const uint8_t*>(key.data()), key.size()};
216 auto error = mDevice->delete_key(&keyBlob);
217 if (error != KM_ERROR_OK) {
Captain Throwbacka5283b32020-02-19 12:11:23 -0500218 LOG(ERROR) << "delete_key failed, code " << error << "\n";
Ethan Yonkerbd7492d2016-12-07 13:55:01 -0600219 return false;
220 }
221 return true;
222}
223
224KeymasterOperation Keymaster::begin(keymaster_purpose_t purpose, const std::string& key,
225 const keymaster::AuthorizationSet& inParams,
226 keymaster::AuthorizationSet* outParams) {
227 keymaster_key_blob_t keyBlob{reinterpret_cast<const uint8_t*>(key.data()), key.size()};
228 keymaster_operation_handle_t mOpHandle;
229 keymaster_key_param_set_t outParams_set;
230 auto error = mDevice->begin(purpose, &keyBlob, &inParams, &outParams_set, &mOpHandle);
231 if (error != KM_ERROR_OK) {
Captain Throwback49cfb7e2020-01-28 17:37:00 -0500232 LOG(ERROR) << "begin failed, code " << error << "\n";
Ethan Yonkerbd7492d2016-12-07 13:55:01 -0600233 return KeymasterOperation(nullptr, mOpHandle);
234 }
235 outParams->Clear();
236 outParams->push_back(outParams_set);
237 keymaster_free_param_set(&outParams_set);
238 return KeymasterOperation(mDevice, mOpHandle);
239}
240
241KeymasterOperation Keymaster::begin(keymaster_purpose_t purpose, const std::string& key,
242 const keymaster::AuthorizationSet& inParams) {
243 keymaster_key_blob_t keyBlob{reinterpret_cast<const uint8_t*>(key.data()), key.size()};
244 keymaster_operation_handle_t mOpHandle;
245 auto error = mDevice->begin(purpose, &keyBlob, &inParams, nullptr, &mOpHandle);
246 if (error != KM_ERROR_OK) {
Captain Throwback49cfb7e2020-01-28 17:37:00 -0500247 LOG(ERROR) << "begin failed, code " << error << "\n";
Ethan Yonkerbd7492d2016-12-07 13:55:01 -0600248 return KeymasterOperation(nullptr, mOpHandle);
249 }
250 return KeymasterOperation(mDevice, mOpHandle);
251}
252
253} // namespace vold
254} // namespace android