blob: 722d9f2d1fb00c82912427615beba594088ac750 [file] [log] [blame]
Paul Crowley1ef25582016-01-21 20:26:12 +00001/*
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>
Paul Crowley0323afd2016-03-15 17:04:39 -070020#include <hardware/hardware.h>
21#include <hardware/keymaster1.h>
22#include <hardware/keymaster2.h>
Paul Crowleydff8c722016-05-16 08:14:56 -070023#include <keymaster/keymaster_configuration.h>
Paul Crowley1ef25582016-01-21 20:26:12 +000024
25namespace android {
26namespace vold {
27
Paul Crowley0323afd2016-03-15 17:04:39 -070028class IKeymasterDevice {
29 public:
30 IKeymasterDevice() {}
31 virtual ~IKeymasterDevice() {}
32 virtual keymaster_error_t generate_key(const keymaster_key_param_set_t* params,
33 keymaster_key_blob_t* key_blob) const = 0;
34 virtual keymaster_error_t delete_key(const keymaster_key_blob_t* key) const = 0;
Paul Crowleydff8c722016-05-16 08:14:56 -070035 virtual keymaster_error_t upgrade_key(const keymaster_key_blob_t* key_to_upgrade,
36 const keymaster_key_param_set_t* upgrade_params,
37 keymaster_key_blob_t* upgraded_key) const = 0;
Paul Crowley0323afd2016-03-15 17:04:39 -070038 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:
Chih-Hung Hsiehc81de6f2016-04-29 14:42:01 -070060 explicit KeymasterDevice(T* d) : mDevice{d} {}
Paul Crowley0323afd2016-03-15 17:04:39 -070061 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:
Chih-Hung Hsiehc81de6f2016-04-29 14:42:01 -070093 explicit Keymaster1Device(keymaster1_device_t* d) : KeymasterDevice<keymaster1_device_t>{d} {}
Paul Crowley0323afd2016-03-15 17:04:39 -070094 ~Keymaster1Device() override final { keymaster1_close(mDevice); }
Paul Crowleydff8c722016-05-16 08:14:56 -070095 keymaster_error_t upgrade_key(const keymaster_key_blob_t* key_to_upgrade,
96 const keymaster_key_param_set_t* upgrade_params,
97 keymaster_key_blob_t* upgraded_key) const override final {
98 return KM_ERROR_UNIMPLEMENTED;
99 }
Paul Crowley0323afd2016-03-15 17:04:39 -0700100 keymaster_error_t finish(keymaster_operation_handle_t operation_handle,
101 const keymaster_key_param_set_t* in_params,
102 const keymaster_blob_t* signature,
103 keymaster_key_param_set_t* out_params,
104 keymaster_blob_t* output) const override final {
105 return mDevice->finish(mDevice, operation_handle, in_params, signature, out_params, output);
106 }
107};
108
109class Keymaster2Device : public KeymasterDevice<keymaster2_device_t> {
110 public:
Chih-Hung Hsiehc81de6f2016-04-29 14:42:01 -0700111 explicit Keymaster2Device(keymaster2_device_t* d) : KeymasterDevice<keymaster2_device_t>{d} {}
Paul Crowley0323afd2016-03-15 17:04:39 -0700112 ~Keymaster2Device() override final { keymaster2_close(mDevice); }
Paul Crowleydff8c722016-05-16 08:14:56 -0700113 keymaster_error_t upgrade_key(const keymaster_key_blob_t* key_to_upgrade,
114 const keymaster_key_param_set_t* upgrade_params,
115 keymaster_key_blob_t* upgraded_key) const override final {
116 return mDevice->upgrade_key(mDevice, key_to_upgrade, upgrade_params, upgraded_key);
117 }
Paul Crowley0323afd2016-03-15 17:04:39 -0700118 keymaster_error_t finish(keymaster_operation_handle_t operation_handle,
119 const keymaster_key_param_set_t* in_params,
120 const keymaster_blob_t* signature,
121 keymaster_key_param_set_t* out_params,
122 keymaster_blob_t* output) const override final {
123 return mDevice->finish(mDevice, operation_handle, in_params, nullptr, signature, out_params,
124 output);
125 }
126};
127
128KeymasterOperation::~KeymasterOperation() {
129 if (mDevice) mDevice->abort(mOpHandle);
130}
131
Paul Crowleydf528a72016-03-09 09:31:37 -0800132bool KeymasterOperation::updateCompletely(const std::string& input, std::string* output) {
Paul Crowleya051eb72016-03-08 16:08:32 -0800133 output->clear();
Paul Crowley1ef25582016-01-21 20:26:12 +0000134 auto it = input.begin();
135 while (it != input.end()) {
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000136 size_t toRead = static_cast<size_t>(input.end() - it);
Paul Crowleydf528a72016-03-09 09:31:37 -0800137 keymaster_blob_t inputBlob{reinterpret_cast<const uint8_t*>(&*it), toRead};
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000138 keymaster_blob_t outputBlob;
139 size_t inputConsumed;
Paul Crowley0323afd2016-03-15 17:04:39 -0700140 auto error =
141 mDevice->update(mOpHandle, nullptr, &inputBlob, &inputConsumed, nullptr, &outputBlob);
Paul Crowley1ef25582016-01-21 20:26:12 +0000142 if (error != KM_ERROR_OK) {
143 LOG(ERROR) << "update failed, code " << error;
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000144 mDevice = nullptr;
Paul Crowley1ef25582016-01-21 20:26:12 +0000145 return false;
146 }
Paul Crowleydf528a72016-03-09 09:31:37 -0800147 output->append(reinterpret_cast<const char*>(outputBlob.data), outputBlob.data_length);
148 free(const_cast<uint8_t*>(outputBlob.data));
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000149 if (inputConsumed > toRead) {
Paul Crowley1ef25582016-01-21 20:26:12 +0000150 LOG(ERROR) << "update reported too much input consumed";
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000151 mDevice = nullptr;
Paul Crowley1ef25582016-01-21 20:26:12 +0000152 return false;
153 }
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000154 it += inputConsumed;
Paul Crowley1ef25582016-01-21 20:26:12 +0000155 }
156 return true;
157}
158
Paul Crowleydff8c722016-05-16 08:14:56 -0700159bool KeymasterOperation::finish(std::string* output) {
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000160 keymaster_blob_t outputBlob;
Paul Crowleydff8c722016-05-16 08:14:56 -0700161 auto error = mDevice->finish(mOpHandle, nullptr, nullptr, nullptr,
162 output ? &outputBlob : nullptr);
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000163 mDevice = nullptr;
Paul Crowley1ef25582016-01-21 20:26:12 +0000164 if (error != KM_ERROR_OK) {
165 LOG(ERROR) << "finish failed, code " << error;
166 return false;
167 }
Paul Crowleydff8c722016-05-16 08:14:56 -0700168 if (output) {
169 output->assign(reinterpret_cast<const char*>(outputBlob.data), outputBlob.data_length);
170 free(const_cast<uint8_t*>(outputBlob.data));
171 }
Paul Crowley1ef25582016-01-21 20:26:12 +0000172 return true;
173}
174
175Keymaster::Keymaster() {
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000176 mDevice = nullptr;
Paul Crowleydf528a72016-03-09 09:31:37 -0800177 const hw_module_t* module;
Paul Crowley1ef25582016-01-21 20:26:12 +0000178 int ret = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &module);
179 if (ret != 0) {
180 LOG(ERROR) << "hw_get_module_by_class returned " << ret;
181 return;
182 }
Paul Crowleydff8c722016-05-16 08:14:56 -0700183 LOG(DEBUG) << "module_api_version is " << module->module_api_version;
Paul Crowley0323afd2016-03-15 17:04:39 -0700184 if (module->module_api_version == KEYMASTER_MODULE_API_VERSION_1_0) {
185 keymaster1_device_t* device;
186 ret = keymaster1_open(module, &device);
187 if (ret != 0) {
188 LOG(ERROR) << "keymaster1_open returned " << ret;
189 return;
190 }
191 mDevice = std::make_shared<Keymaster1Device>(device);
192 } else if (module->module_api_version == KEYMASTER_MODULE_API_VERSION_2_0) {
193 keymaster2_device_t* device;
194 ret = keymaster2_open(module, &device);
195 if (ret != 0) {
196 LOG(ERROR) << "keymaster2_open returned " << ret;
197 return;
198 }
Paul Crowleydff8c722016-05-16 08:14:56 -0700199 auto error = ConfigureDevice(device);
200 if (error != KM_ERROR_OK) {
201 LOG(ERROR) << "ConfigureDevice returned " << error;
202 return;
203 }
Paul Crowley0323afd2016-03-15 17:04:39 -0700204 mDevice = std::make_shared<Keymaster2Device>(device);
205 } else {
Paul Crowley1ef25582016-01-21 20:26:12 +0000206 LOG(ERROR) << "module_api_version is " << module->module_api_version;
207 return;
208 }
Paul Crowley1ef25582016-01-21 20:26:12 +0000209}
210
Paul Crowleydf528a72016-03-09 09:31:37 -0800211bool Keymaster::generateKey(const keymaster::AuthorizationSet& inParams, std::string* key) {
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000212 keymaster_key_blob_t keyBlob;
Paul Crowley0323afd2016-03-15 17:04:39 -0700213 auto error = mDevice->generate_key(&inParams, &keyBlob);
Paul Crowley1ef25582016-01-21 20:26:12 +0000214 if (error != KM_ERROR_OK) {
215 LOG(ERROR) << "generate_key failed, code " << error;
216 return false;
217 }
Paul Crowleydf528a72016-03-09 09:31:37 -0800218 key->assign(reinterpret_cast<const char*>(keyBlob.key_material), keyBlob.key_material_size);
219 free(const_cast<uint8_t*>(keyBlob.key_material));
Paul Crowley1ef25582016-01-21 20:26:12 +0000220 return true;
221}
222
Paul Crowleydf528a72016-03-09 09:31:37 -0800223bool Keymaster::deleteKey(const std::string& key) {
Paul Crowleydf528a72016-03-09 09:31:37 -0800224 keymaster_key_blob_t keyBlob{reinterpret_cast<const uint8_t*>(key.data()), key.size()};
Paul Crowley0323afd2016-03-15 17:04:39 -0700225 auto error = mDevice->delete_key(&keyBlob);
Paul Crowley1ef25582016-01-21 20:26:12 +0000226 if (error != KM_ERROR_OK) {
227 LOG(ERROR) << "delete_key failed, code " << error;
228 return false;
229 }
230 return true;
231}
232
Paul Crowleydff8c722016-05-16 08:14:56 -0700233bool Keymaster::upgradeKey(const std::string& oldKey, const AuthorizationSet& inParams,
234 std::string* newKey) {
235 keymaster_key_blob_t oldKeyBlob{reinterpret_cast<const uint8_t*>(oldKey.data()), oldKey.size()};
236 keymaster_key_blob_t newKeyBlob;
237 auto error = mDevice->upgrade_key(&oldKeyBlob, &inParams, &newKeyBlob);
238 if (error != KM_ERROR_OK) {
239 LOG(ERROR) << "upgrade_key failed, code " << error;
240 return false;
241 }
242 newKey->assign(reinterpret_cast<const char*>(newKeyBlob.key_material),
243 newKeyBlob.key_material_size);
244 free(const_cast<uint8_t*>(newKeyBlob.key_material));
245 return true;
246}
247
Paul Crowleydf528a72016-03-09 09:31:37 -0800248KeymasterOperation Keymaster::begin(keymaster_purpose_t purpose, const std::string& key,
249 const keymaster::AuthorizationSet& inParams,
250 keymaster::AuthorizationSet* outParams) {
251 keymaster_key_blob_t keyBlob{reinterpret_cast<const uint8_t*>(key.data()), key.size()};
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000252 keymaster_operation_handle_t mOpHandle;
253 keymaster_key_param_set_t outParams_set;
Paul Crowleydff8c722016-05-16 08:14:56 -0700254 auto error = mDevice->begin(purpose, &keyBlob, &inParams,
255 outParams ? &outParams_set : nullptr, &mOpHandle);
Paul Crowley1ef25582016-01-21 20:26:12 +0000256 if (error != KM_ERROR_OK) {
257 LOG(ERROR) << "begin failed, code " << error;
Paul Crowleydff8c722016-05-16 08:14:56 -0700258 return KeymasterOperation(error);
Paul Crowley1ef25582016-01-21 20:26:12 +0000259 }
Paul Crowleydff8c722016-05-16 08:14:56 -0700260 if (outParams) {
261 outParams->Clear();
262 outParams->push_back(outParams_set);
263 keymaster_free_param_set(&outParams_set);
Paul Crowley1ef25582016-01-21 20:26:12 +0000264 }
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000265 return KeymasterOperation(mDevice, mOpHandle);
Paul Crowley1ef25582016-01-21 20:26:12 +0000266}
267
268} // namespace vold
269} // namespace android