blob: c43613e65f9d52f4fa31d5c64eb6ed9af895cbbf [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 Crowley1ef25582016-01-21 20:26:12 +000023
24namespace android {
25namespace vold {
26
Paul Crowley0323afd2016-03-15 17:04:39 -070027class IKeymasterDevice {
28 public:
29 IKeymasterDevice() {}
30 virtual ~IKeymasterDevice() {}
31 virtual keymaster_error_t generate_key(const keymaster_key_param_set_t* params,
32 keymaster_key_blob_t* key_blob) const = 0;
33 virtual keymaster_error_t delete_key(const keymaster_key_blob_t* key) const = 0;
34 virtual keymaster_error_t begin(keymaster_purpose_t purpose, const keymaster_key_blob_t* key,
35 const keymaster_key_param_set_t* in_params,
36 keymaster_key_param_set_t* out_params,
37 keymaster_operation_handle_t* operation_handle) const = 0;
38 virtual keymaster_error_t update(keymaster_operation_handle_t operation_handle,
39 const keymaster_key_param_set_t* in_params,
40 const keymaster_blob_t* input, size_t* input_consumed,
41 keymaster_key_param_set_t* out_params,
42 keymaster_blob_t* output) const = 0;
43 virtual keymaster_error_t finish(keymaster_operation_handle_t operation_handle,
44 const keymaster_key_param_set_t* in_params,
45 const keymaster_blob_t* signature,
46 keymaster_key_param_set_t* out_params,
47 keymaster_blob_t* output) const = 0;
48 virtual keymaster_error_t abort(keymaster_operation_handle_t operation_handle) const = 0;
49
50 protected:
51 DISALLOW_COPY_AND_ASSIGN(IKeymasterDevice);
52};
53
54template <typename T> class KeymasterDevice : public IKeymasterDevice {
55 public:
Chih-Hung Hsiehc81de6f2016-04-29 14:42:01 -070056 explicit KeymasterDevice(T* d) : mDevice{d} {}
Paul Crowley0323afd2016-03-15 17:04:39 -070057 keymaster_error_t generate_key(const keymaster_key_param_set_t* params,
58 keymaster_key_blob_t* key_blob) const override final {
59 return mDevice->generate_key(mDevice, params, key_blob, nullptr);
60 }
61 keymaster_error_t delete_key(const keymaster_key_blob_t* key) const override final {
62 if (mDevice->delete_key == nullptr) return KM_ERROR_OK;
63 return mDevice->delete_key(mDevice, key);
64 }
65 keymaster_error_t begin(keymaster_purpose_t purpose, const keymaster_key_blob_t* key,
66 const keymaster_key_param_set_t* in_params,
67 keymaster_key_param_set_t* out_params,
68 keymaster_operation_handle_t* operation_handle) const override final {
69 return mDevice->begin(mDevice, purpose, key, in_params, out_params, operation_handle);
70 }
71 keymaster_error_t update(keymaster_operation_handle_t operation_handle,
72 const keymaster_key_param_set_t* in_params,
73 const keymaster_blob_t* input, size_t* input_consumed,
74 keymaster_key_param_set_t* out_params,
75 keymaster_blob_t* output) const override final {
76 return mDevice->update(mDevice, operation_handle, in_params, input, input_consumed,
77 out_params, output);
78 }
79 keymaster_error_t abort(keymaster_operation_handle_t operation_handle) const override final {
80 return mDevice->abort(mDevice, operation_handle);
81 }
82
83 protected:
84 T* const mDevice;
85};
86
87class Keymaster1Device : public KeymasterDevice<keymaster1_device_t> {
88 public:
Chih-Hung Hsiehc81de6f2016-04-29 14:42:01 -070089 explicit Keymaster1Device(keymaster1_device_t* d) : KeymasterDevice<keymaster1_device_t>{d} {}
Paul Crowley0323afd2016-03-15 17:04:39 -070090 ~Keymaster1Device() override final { keymaster1_close(mDevice); }
91 keymaster_error_t finish(keymaster_operation_handle_t operation_handle,
92 const keymaster_key_param_set_t* in_params,
93 const keymaster_blob_t* signature,
94 keymaster_key_param_set_t* out_params,
95 keymaster_blob_t* output) const override final {
96 return mDevice->finish(mDevice, operation_handle, in_params, signature, out_params, output);
97 }
98};
99
100class Keymaster2Device : public KeymasterDevice<keymaster2_device_t> {
101 public:
Chih-Hung Hsiehc81de6f2016-04-29 14:42:01 -0700102 explicit Keymaster2Device(keymaster2_device_t* d) : KeymasterDevice<keymaster2_device_t>{d} {}
Paul Crowley0323afd2016-03-15 17:04:39 -0700103 ~Keymaster2Device() override final { keymaster2_close(mDevice); }
104 keymaster_error_t finish(keymaster_operation_handle_t operation_handle,
105 const keymaster_key_param_set_t* in_params,
106 const keymaster_blob_t* signature,
107 keymaster_key_param_set_t* out_params,
108 keymaster_blob_t* output) const override final {
109 return mDevice->finish(mDevice, operation_handle, in_params, nullptr, signature, out_params,
110 output);
111 }
112};
113
114KeymasterOperation::~KeymasterOperation() {
115 if (mDevice) mDevice->abort(mOpHandle);
116}
117
Paul Crowleydf528a72016-03-09 09:31:37 -0800118bool KeymasterOperation::updateCompletely(const std::string& input, std::string* output) {
Paul Crowleya051eb72016-03-08 16:08:32 -0800119 output->clear();
Paul Crowley1ef25582016-01-21 20:26:12 +0000120 auto it = input.begin();
121 while (it != input.end()) {
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000122 size_t toRead = static_cast<size_t>(input.end() - it);
Paul Crowleydf528a72016-03-09 09:31:37 -0800123 keymaster_blob_t inputBlob{reinterpret_cast<const uint8_t*>(&*it), toRead};
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000124 keymaster_blob_t outputBlob;
125 size_t inputConsumed;
Paul Crowley0323afd2016-03-15 17:04:39 -0700126 auto error =
127 mDevice->update(mOpHandle, nullptr, &inputBlob, &inputConsumed, nullptr, &outputBlob);
Paul Crowley1ef25582016-01-21 20:26:12 +0000128 if (error != KM_ERROR_OK) {
129 LOG(ERROR) << "update failed, code " << error;
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000130 mDevice = nullptr;
Paul Crowley1ef25582016-01-21 20:26:12 +0000131 return false;
132 }
Paul Crowleydf528a72016-03-09 09:31:37 -0800133 output->append(reinterpret_cast<const char*>(outputBlob.data), outputBlob.data_length);
134 free(const_cast<uint8_t*>(outputBlob.data));
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000135 if (inputConsumed > toRead) {
Paul Crowley1ef25582016-01-21 20:26:12 +0000136 LOG(ERROR) << "update reported too much input consumed";
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000137 mDevice = nullptr;
Paul Crowley1ef25582016-01-21 20:26:12 +0000138 return false;
139 }
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000140 it += inputConsumed;
Paul Crowley1ef25582016-01-21 20:26:12 +0000141 }
142 return true;
143}
144
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000145bool KeymasterOperation::finish() {
Paul Crowley0323afd2016-03-15 17:04:39 -0700146 auto error = mDevice->finish(mOpHandle, nullptr, nullptr, nullptr, nullptr);
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000147 mDevice = nullptr;
Paul Crowley1ef25582016-01-21 20:26:12 +0000148 if (error != KM_ERROR_OK) {
149 LOG(ERROR) << "finish failed, code " << error;
150 return false;
151 }
152 return true;
153}
154
Paul Crowleydf528a72016-03-09 09:31:37 -0800155bool KeymasterOperation::finishWithOutput(std::string* output) {
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000156 keymaster_blob_t outputBlob;
Paul Crowley0323afd2016-03-15 17:04:39 -0700157 auto error = mDevice->finish(mOpHandle, nullptr, nullptr, nullptr, &outputBlob);
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000158 mDevice = nullptr;
Paul Crowley1ef25582016-01-21 20:26:12 +0000159 if (error != KM_ERROR_OK) {
160 LOG(ERROR) << "finish failed, code " << error;
161 return false;
162 }
Paul Crowleydf528a72016-03-09 09:31:37 -0800163 output->assign(reinterpret_cast<const char*>(outputBlob.data), outputBlob.data_length);
164 free(const_cast<uint8_t*>(outputBlob.data));
Paul Crowley1ef25582016-01-21 20:26:12 +0000165 return true;
166}
167
168Keymaster::Keymaster() {
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000169 mDevice = nullptr;
Paul Crowleydf528a72016-03-09 09:31:37 -0800170 const hw_module_t* module;
Paul Crowley1ef25582016-01-21 20:26:12 +0000171 int ret = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &module);
172 if (ret != 0) {
173 LOG(ERROR) << "hw_get_module_by_class returned " << ret;
174 return;
175 }
Paul Crowley0323afd2016-03-15 17:04:39 -0700176 if (module->module_api_version == KEYMASTER_MODULE_API_VERSION_1_0) {
177 keymaster1_device_t* device;
178 ret = keymaster1_open(module, &device);
179 if (ret != 0) {
180 LOG(ERROR) << "keymaster1_open returned " << ret;
181 return;
182 }
183 mDevice = std::make_shared<Keymaster1Device>(device);
184 } else if (module->module_api_version == KEYMASTER_MODULE_API_VERSION_2_0) {
185 keymaster2_device_t* device;
186 ret = keymaster2_open(module, &device);
187 if (ret != 0) {
188 LOG(ERROR) << "keymaster2_open returned " << ret;
189 return;
190 }
191 mDevice = std::make_shared<Keymaster2Device>(device);
192 } else {
Paul Crowley1ef25582016-01-21 20:26:12 +0000193 LOG(ERROR) << "module_api_version is " << module->module_api_version;
194 return;
195 }
Paul Crowley1ef25582016-01-21 20:26:12 +0000196}
197
Paul Crowleydf528a72016-03-09 09:31:37 -0800198bool Keymaster::generateKey(const keymaster::AuthorizationSet& inParams, std::string* key) {
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000199 keymaster_key_blob_t keyBlob;
Paul Crowley0323afd2016-03-15 17:04:39 -0700200 auto error = mDevice->generate_key(&inParams, &keyBlob);
Paul Crowley1ef25582016-01-21 20:26:12 +0000201 if (error != KM_ERROR_OK) {
202 LOG(ERROR) << "generate_key failed, code " << error;
203 return false;
204 }
Paul Crowleydf528a72016-03-09 09:31:37 -0800205 key->assign(reinterpret_cast<const char*>(keyBlob.key_material), keyBlob.key_material_size);
206 free(const_cast<uint8_t*>(keyBlob.key_material));
Paul Crowley1ef25582016-01-21 20:26:12 +0000207 return true;
208}
209
Paul Crowleydf528a72016-03-09 09:31:37 -0800210bool Keymaster::deleteKey(const std::string& key) {
Paul Crowleydf528a72016-03-09 09:31:37 -0800211 keymaster_key_blob_t keyBlob{reinterpret_cast<const uint8_t*>(key.data()), key.size()};
Paul Crowley0323afd2016-03-15 17:04:39 -0700212 auto error = mDevice->delete_key(&keyBlob);
Paul Crowley1ef25582016-01-21 20:26:12 +0000213 if (error != KM_ERROR_OK) {
214 LOG(ERROR) << "delete_key failed, code " << error;
215 return false;
216 }
217 return true;
218}
219
Paul Crowleydf528a72016-03-09 09:31:37 -0800220KeymasterOperation Keymaster::begin(keymaster_purpose_t purpose, const std::string& key,
221 const keymaster::AuthorizationSet& inParams,
222 keymaster::AuthorizationSet* outParams) {
223 keymaster_key_blob_t keyBlob{reinterpret_cast<const uint8_t*>(key.data()), key.size()};
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000224 keymaster_operation_handle_t mOpHandle;
225 keymaster_key_param_set_t outParams_set;
Paul Crowley0323afd2016-03-15 17:04:39 -0700226 auto error = mDevice->begin(purpose, &keyBlob, &inParams, &outParams_set, &mOpHandle);
Paul Crowley1ef25582016-01-21 20:26:12 +0000227 if (error != KM_ERROR_OK) {
228 LOG(ERROR) << "begin failed, code " << error;
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000229 return KeymasterOperation(nullptr, mOpHandle);
Paul Crowley1ef25582016-01-21 20:26:12 +0000230 }
Paul Crowleya051eb72016-03-08 16:08:32 -0800231 outParams->Clear();
232 outParams->push_back(outParams_set);
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000233 keymaster_free_param_set(&outParams_set);
234 return KeymasterOperation(mDevice, mOpHandle);
Paul Crowley1ef25582016-01-21 20:26:12 +0000235}
236
Paul Crowleydf528a72016-03-09 09:31:37 -0800237KeymasterOperation Keymaster::begin(keymaster_purpose_t purpose, const std::string& key,
238 const keymaster::AuthorizationSet& inParams) {
239 keymaster_key_blob_t keyBlob{reinterpret_cast<const uint8_t*>(key.data()), key.size()};
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000240 keymaster_operation_handle_t mOpHandle;
Paul Crowley0323afd2016-03-15 17:04:39 -0700241 auto error = mDevice->begin(purpose, &keyBlob, &inParams, nullptr, &mOpHandle);
Paul Crowley1ef25582016-01-21 20:26:12 +0000242 if (error != KM_ERROR_OK) {
243 LOG(ERROR) << "begin failed, code " << error;
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000244 return KeymasterOperation(nullptr, mOpHandle);
Paul Crowley1ef25582016-01-21 20:26:12 +0000245 }
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000246 return KeymasterOperation(mDevice, mOpHandle);
Paul Crowley1ef25582016-01-21 20:26:12 +0000247}
248
249} // namespace vold
250} // namespace android