blob: 222b930d42b2f81c850584e052d32eb806a7948f [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>
20
21namespace android {
22namespace vold {
23
Paul Crowleydf528a72016-03-09 09:31:37 -080024bool KeymasterOperation::updateCompletely(const std::string& input, std::string* output) {
Paul Crowleya051eb72016-03-08 16:08:32 -080025 output->clear();
Paul Crowley1ef25582016-01-21 20:26:12 +000026 auto it = input.begin();
27 while (it != input.end()) {
Paul Crowley13ffd8e2016-01-27 14:30:22 +000028 size_t toRead = static_cast<size_t>(input.end() - it);
Paul Crowleydf528a72016-03-09 09:31:37 -080029 keymaster_blob_t inputBlob{reinterpret_cast<const uint8_t*>(&*it), toRead};
Paul Crowley13ffd8e2016-01-27 14:30:22 +000030 keymaster_blob_t outputBlob;
31 size_t inputConsumed;
Paul Crowleydf528a72016-03-09 09:31:37 -080032 auto error = mDevice->update(mDevice, mOpHandle, nullptr, &inputBlob, &inputConsumed,
33 nullptr, &outputBlob);
Paul Crowley1ef25582016-01-21 20:26:12 +000034 if (error != KM_ERROR_OK) {
35 LOG(ERROR) << "update failed, code " << error;
Paul Crowley13ffd8e2016-01-27 14:30:22 +000036 mDevice = nullptr;
Paul Crowley1ef25582016-01-21 20:26:12 +000037 return false;
38 }
Paul Crowleydf528a72016-03-09 09:31:37 -080039 output->append(reinterpret_cast<const char*>(outputBlob.data), outputBlob.data_length);
40 free(const_cast<uint8_t*>(outputBlob.data));
Paul Crowley13ffd8e2016-01-27 14:30:22 +000041 if (inputConsumed > toRead) {
Paul Crowley1ef25582016-01-21 20:26:12 +000042 LOG(ERROR) << "update reported too much input consumed";
Paul Crowley13ffd8e2016-01-27 14:30:22 +000043 mDevice = nullptr;
Paul Crowley1ef25582016-01-21 20:26:12 +000044 return false;
45 }
Paul Crowley13ffd8e2016-01-27 14:30:22 +000046 it += inputConsumed;
Paul Crowley1ef25582016-01-21 20:26:12 +000047 }
48 return true;
49}
50
Paul Crowley13ffd8e2016-01-27 14:30:22 +000051bool KeymasterOperation::finish() {
Paul Crowleydf528a72016-03-09 09:31:37 -080052 auto error = mDevice->finish(mDevice, mOpHandle, nullptr, nullptr, nullptr, nullptr);
Paul Crowley13ffd8e2016-01-27 14:30:22 +000053 mDevice = nullptr;
Paul Crowley1ef25582016-01-21 20:26:12 +000054 if (error != KM_ERROR_OK) {
55 LOG(ERROR) << "finish failed, code " << error;
56 return false;
57 }
58 return true;
59}
60
Paul Crowleydf528a72016-03-09 09:31:37 -080061bool KeymasterOperation::finishWithOutput(std::string* output) {
Paul Crowley13ffd8e2016-01-27 14:30:22 +000062 keymaster_blob_t outputBlob;
Paul Crowleydf528a72016-03-09 09:31:37 -080063 auto error = mDevice->finish(mDevice, mOpHandle, nullptr, nullptr, nullptr, &outputBlob);
Paul Crowley13ffd8e2016-01-27 14:30:22 +000064 mDevice = nullptr;
Paul Crowley1ef25582016-01-21 20:26:12 +000065 if (error != KM_ERROR_OK) {
66 LOG(ERROR) << "finish failed, code " << error;
67 return false;
68 }
Paul Crowleydf528a72016-03-09 09:31:37 -080069 output->assign(reinterpret_cast<const char*>(outputBlob.data), outputBlob.data_length);
70 free(const_cast<uint8_t*>(outputBlob.data));
Paul Crowley1ef25582016-01-21 20:26:12 +000071 return true;
72}
73
74Keymaster::Keymaster() {
Paul Crowley13ffd8e2016-01-27 14:30:22 +000075 mDevice = nullptr;
Paul Crowleydf528a72016-03-09 09:31:37 -080076 const hw_module_t* module;
Paul Crowley1ef25582016-01-21 20:26:12 +000077 int ret = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &module);
78 if (ret != 0) {
79 LOG(ERROR) << "hw_get_module_by_class returned " << ret;
80 return;
81 }
82 // TODO: This will need to be updated to support keymaster2.
83 if (module->module_api_version != KEYMASTER_MODULE_API_VERSION_1_0) {
84 LOG(ERROR) << "module_api_version is " << module->module_api_version;
85 return;
86 }
Paul Crowley13ffd8e2016-01-27 14:30:22 +000087 ret = keymaster1_open(module, &mDevice);
Paul Crowley1ef25582016-01-21 20:26:12 +000088 if (ret != 0) {
89 LOG(ERROR) << "keymaster1_open returned " << ret;
Paul Crowley13ffd8e2016-01-27 14:30:22 +000090 mDevice = nullptr;
Paul Crowley1ef25582016-01-21 20:26:12 +000091 return;
92 }
93}
94
Paul Crowleydf528a72016-03-09 09:31:37 -080095bool Keymaster::generateKey(const keymaster::AuthorizationSet& inParams, std::string* key) {
Paul Crowley13ffd8e2016-01-27 14:30:22 +000096 keymaster_key_blob_t keyBlob;
97 auto error = mDevice->generate_key(mDevice, &inParams, &keyBlob, nullptr);
Paul Crowley1ef25582016-01-21 20:26:12 +000098 if (error != KM_ERROR_OK) {
99 LOG(ERROR) << "generate_key failed, code " << error;
100 return false;
101 }
Paul Crowleydf528a72016-03-09 09:31:37 -0800102 key->assign(reinterpret_cast<const char*>(keyBlob.key_material), keyBlob.key_material_size);
103 free(const_cast<uint8_t*>(keyBlob.key_material));
Paul Crowley1ef25582016-01-21 20:26:12 +0000104 return true;
105}
106
Paul Crowleydf528a72016-03-09 09:31:37 -0800107bool Keymaster::deleteKey(const std::string& key) {
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000108 if (mDevice->delete_key == nullptr) return true;
Paul Crowleydf528a72016-03-09 09:31:37 -0800109 keymaster_key_blob_t keyBlob{reinterpret_cast<const uint8_t*>(key.data()), key.size()};
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000110 auto error = mDevice->delete_key(mDevice, &keyBlob);
Paul Crowley1ef25582016-01-21 20:26:12 +0000111 if (error != KM_ERROR_OK) {
112 LOG(ERROR) << "delete_key failed, code " << error;
113 return false;
114 }
115 return true;
116}
117
Paul Crowleydf528a72016-03-09 09:31:37 -0800118KeymasterOperation Keymaster::begin(keymaster_purpose_t purpose, const std::string& key,
119 const keymaster::AuthorizationSet& inParams,
120 keymaster::AuthorizationSet* outParams) {
121 keymaster_key_blob_t keyBlob{reinterpret_cast<const uint8_t*>(key.data()), key.size()};
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000122 keymaster_operation_handle_t mOpHandle;
123 keymaster_key_param_set_t outParams_set;
Paul Crowleydf528a72016-03-09 09:31:37 -0800124 auto error = mDevice->begin(mDevice, purpose, &keyBlob, &inParams, &outParams_set, &mOpHandle);
Paul Crowley1ef25582016-01-21 20:26:12 +0000125 if (error != KM_ERROR_OK) {
126 LOG(ERROR) << "begin failed, code " << error;
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000127 return KeymasterOperation(nullptr, mOpHandle);
Paul Crowley1ef25582016-01-21 20:26:12 +0000128 }
Paul Crowleya051eb72016-03-08 16:08:32 -0800129 outParams->Clear();
130 outParams->push_back(outParams_set);
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000131 keymaster_free_param_set(&outParams_set);
132 return KeymasterOperation(mDevice, mOpHandle);
Paul Crowley1ef25582016-01-21 20:26:12 +0000133}
134
Paul Crowleydf528a72016-03-09 09:31:37 -0800135KeymasterOperation Keymaster::begin(keymaster_purpose_t purpose, const std::string& key,
136 const keymaster::AuthorizationSet& inParams) {
137 keymaster_key_blob_t keyBlob{reinterpret_cast<const uint8_t*>(key.data()), key.size()};
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000138 keymaster_operation_handle_t mOpHandle;
Paul Crowleydf528a72016-03-09 09:31:37 -0800139 auto error = mDevice->begin(mDevice, purpose, &keyBlob, &inParams, nullptr, &mOpHandle);
Paul Crowley1ef25582016-01-21 20:26:12 +0000140 if (error != KM_ERROR_OK) {
141 LOG(ERROR) << "begin failed, code " << error;
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000142 return KeymasterOperation(nullptr, mOpHandle);
Paul Crowley1ef25582016-01-21 20:26:12 +0000143 }
Paul Crowley13ffd8e2016-01-27 14:30:22 +0000144 return KeymasterOperation(mDevice, mOpHandle);
Paul Crowley1ef25582016-01-21 20:26:12 +0000145}
146
147} // namespace vold
148} // namespace android