1/* 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 <keystore/keymaster_tags.h> 21#include <keystore/authorization_set.h> 22#include <keystore/keystore_hidl_support.h> 23 24using namespace ::keystore; 25using android::hardware::hidl_string; 26 27namespace android { 28namespace vold { 29 30KeymasterOperation::~KeymasterOperation() { 31 if (mDevice.get()) mDevice->abort(mOpHandle); 32} 33 34bool KeymasterOperation::updateCompletely(const std::string& input, std::string* output) { 35 if (output) 36 output->clear(); 37 auto it = input.begin(); 38 uint32_t inputConsumed; 39 40 ErrorCode km_error; 41 auto hidlCB = [&] (ErrorCode ret, uint32_t _inputConsumed, 42 const hidl_vec<KeyParameter>& /*ignored*/, const hidl_vec<uint8_t>& _output) { 43 km_error = ret; 44 if (km_error != ErrorCode::OK) return; 45 inputConsumed = _inputConsumed; 46 if (output) 47 output->append(reinterpret_cast<const char*>(&_output[0]), _output.size()); 48 }; 49 50 while (it != input.end()) { 51 size_t toRead = static_cast<size_t>(input.end() - it); 52 auto inputBlob = blob2hidlVec(reinterpret_cast<const uint8_t*>(&*it), toRead); 53 auto error = mDevice->update(mOpHandle, hidl_vec<KeyParameter>(), inputBlob, hidlCB); 54 if (!error.isOk()) { 55 LOG(ERROR) << "update failed: " << error.description(); 56 mDevice = nullptr; 57 return false; 58 } 59 if (km_error != ErrorCode::OK) { 60 LOG(ERROR) << "update failed, code " << int32_t(km_error); 61 mDevice = nullptr; 62 return false; 63 } 64 if (inputConsumed > toRead) { 65 LOG(ERROR) << "update reported too much input consumed"; 66 mDevice = nullptr; 67 return false; 68 } 69 it += inputConsumed; 70 } 71 return true; 72} 73 74bool KeymasterOperation::finish(std::string* output) { 75 ErrorCode km_error; 76 auto hidlCb = [&] (ErrorCode ret, const hidl_vec<KeyParameter>& /*ignored*/, 77 const hidl_vec<uint8_t>& _output) { 78 km_error = ret; 79 if (km_error != ErrorCode::OK) return; 80 if (output) 81 output->assign(reinterpret_cast<const char*>(&_output[0]), _output.size()); 82 }; 83 auto error = mDevice->finish(mOpHandle, hidl_vec<KeyParameter>(), hidl_vec<uint8_t>(), 84 hidl_vec<uint8_t>(), hidlCb); 85 mDevice = nullptr; 86 if (!error.isOk()) { 87 LOG(ERROR) << "finish failed: " << error.description(); 88 return false; 89 } 90 if (km_error != ErrorCode::OK) { 91 LOG(ERROR) << "finish failed, code " << int32_t(km_error); 92 return false; 93 } 94 return true; 95} 96 97Keymaster::Keymaster() { 98 mDevice = ::android::hardware::keymaster::V3_0::IKeymasterDevice::getService(); 99} 100 101bool Keymaster::generateKey(const AuthorizationSet& inParams, std::string* key) { 102 ErrorCode km_error; 103 auto hidlCb = [&] (ErrorCode ret, const hidl_vec<uint8_t>& keyBlob, 104 const KeyCharacteristics& /*ignored*/) { 105 km_error = ret; 106 if (km_error != ErrorCode::OK) return; 107 if (key) 108 key->assign(reinterpret_cast<const char*>(&keyBlob[0]), keyBlob.size()); 109 }; 110 111 auto error = mDevice->generateKey(inParams.hidl_data(), hidlCb); 112 if (!error.isOk()) { 113 LOG(ERROR) << "generate_key failed: " << error.description(); 114 return false; 115 } 116 if (km_error != ErrorCode::OK) { 117 LOG(ERROR) << "generate_key failed, code " << int32_t(km_error); 118 return false; 119 } 120 return true; 121} 122 123bool Keymaster::deleteKey(const std::string& key) { 124 auto keyBlob = blob2hidlVec(key); 125 auto error = mDevice->deleteKey(keyBlob); 126 if (!error.isOk()) { 127 LOG(ERROR) << "delete_key failed: " << error.description(); 128 return false; 129 } 130 if (ErrorCode(error) != ErrorCode::OK) { 131 LOG(ERROR) << "delete_key failed, code " << uint32_t(ErrorCode(error)); 132 return false; 133 } 134 return true; 135} 136 137bool Keymaster::upgradeKey(const std::string& oldKey, const AuthorizationSet& inParams, 138 std::string* newKey) { 139 auto oldKeyBlob = blob2hidlVec(oldKey); 140 ErrorCode km_error; 141 auto hidlCb = [&] (ErrorCode ret, const hidl_vec<uint8_t>& upgradedKeyBlob) { 142 km_error = ret; 143 if (km_error != ErrorCode::OK) return; 144 if (newKey) 145 newKey->assign(reinterpret_cast<const char*>(&upgradedKeyBlob[0]), 146 upgradedKeyBlob.size()); 147 }; 148 auto error = mDevice->upgradeKey(oldKeyBlob, inParams.hidl_data(), hidlCb); 149 if (!error.isOk()) { 150 LOG(ERROR) << "upgrade_key failed: " << error.description(); 151 return false; 152 } 153 if (km_error != ErrorCode::OK) { 154 LOG(ERROR) << "upgrade_key failed, code " << int32_t(km_error); 155 return false; 156 } 157 return true; 158} 159 160KeymasterOperation Keymaster::begin(KeyPurpose purpose, const std::string& key, 161 const AuthorizationSet& inParams, 162 AuthorizationSet* outParams) { 163 auto keyBlob = blob2hidlVec(key); 164 uint64_t mOpHandle; 165 ErrorCode km_error; 166 167 auto hidlCb = [&] (ErrorCode ret, const hidl_vec<KeyParameter>& _outParams, 168 uint64_t operationHandle) { 169 km_error = ret; 170 if (km_error != ErrorCode::OK) return; 171 if (outParams) 172 *outParams = _outParams; 173 mOpHandle = operationHandle; 174 }; 175 176 auto error = mDevice->begin(purpose, keyBlob, inParams.hidl_data(), hidlCb); 177 if (!error.isOk()) { 178 LOG(ERROR) << "begin failed: " << error.description(); 179 return KeymasterOperation(ErrorCode::UNKNOWN_ERROR); 180 } 181 if (km_error != ErrorCode::OK) { 182 LOG(ERROR) << "begin failed, code " << int32_t(km_error); 183 return KeymasterOperation(km_error); 184 } 185 return KeymasterOperation(mDevice, mOpHandle); 186} 187bool Keymaster::isSecure() { 188 bool _isSecure = false; 189 auto rc = mDevice->getHardwareFeatures( 190 [&] (bool isSecure, bool, bool, bool, bool, const hidl_string&, const hidl_string&) { 191 _isSecure = isSecure; }); 192 return rc.isOk() && _isSecure; 193} 194 195} // namespace vold 196} // namespace android 197 198using namespace ::android::vold; 199 200int keymaster_compatibility_cryptfs_scrypt() { 201 Keymaster dev; 202 if (!dev) { 203 LOG(ERROR) << "Failed to initiate keymaster session"; 204 return -1; 205 } 206 return dev.isSecure(); 207} 208 209int keymaster_create_key_for_cryptfs_scrypt(uint32_t rsa_key_size, 210 uint64_t rsa_exponent, 211 uint32_t ratelimit, 212 uint8_t* key_buffer, 213 uint32_t key_buffer_size, 214 uint32_t* key_out_size) 215{ 216 Keymaster dev; 217 std::string key; 218 if (!dev) { 219 LOG(ERROR) << "Failed to initiate keymaster session"; 220 return -1; 221 } 222 if (!key_buffer || !key_out_size) { 223 LOG(ERROR) << __FILE__ << ":" << __LINE__ << ":Invalid argument"; 224 return -1; 225 } 226 if (key_out_size) { 227 *key_out_size = 0; 228 } 229 230 auto paramBuilder = AuthorizationSetBuilder() 231 .Authorization(TAG_ALGORITHM, Algorithm::RSA) 232 .Authorization(TAG_KEY_SIZE, rsa_key_size) 233 .Authorization(TAG_RSA_PUBLIC_EXPONENT, rsa_exponent) 234 .Authorization(TAG_PURPOSE, KeyPurpose::SIGN) 235 .Authorization(TAG_PADDING, PaddingMode::NONE) 236 .Authorization(TAG_DIGEST, Digest::NONE) 237 .Authorization(TAG_BLOB_USAGE_REQUIREMENTS, 238 KeyBlobUsageRequirements::STANDALONE) 239 .Authorization(TAG_NO_AUTH_REQUIRED) 240 .Authorization(TAG_MIN_SECONDS_BETWEEN_OPS, ratelimit); 241 242 if (!dev.generateKey(paramBuilder, &key)) { 243 return -1; 244 } 245 246 if (key_out_size) { 247 *key_out_size = key.size(); 248 } 249 250 if (key_buffer_size < key.size()) { 251 return -1; 252 } 253 254 std::copy(key.data(), key.data() + key.size(), key_buffer); 255 return 0; 256} 257 258int keymaster_sign_object_for_cryptfs_scrypt(const uint8_t* key_blob, 259 size_t key_blob_size, 260 uint32_t ratelimit, 261 const uint8_t* object, 262 const size_t object_size, 263 uint8_t** signature_buffer, 264 size_t* signature_buffer_size) 265{ 266 Keymaster dev; 267 if (!dev) { 268 LOG(ERROR) << "Failed to initiate keymaster session"; 269 return -1; 270 } 271 if (!key_blob || !object || !signature_buffer || !signature_buffer_size) { 272 LOG(ERROR) << __FILE__ << ":" << __LINE__ << ":Invalid argument"; 273 return -1; 274 } 275 276 AuthorizationSet outParams; 277 std::string key(reinterpret_cast<const char*>(key_blob), key_blob_size); 278 std::string input(reinterpret_cast<const char*>(object), object_size); 279 std::string output; 280 KeymasterOperation op; 281 282 auto paramBuilder = AuthorizationSetBuilder() 283 .Authorization(TAG_PADDING, PaddingMode::NONE) 284 .Authorization(TAG_DIGEST, Digest::NONE); 285 286 while (true) { 287 op = dev.begin(KeyPurpose::SIGN, key, paramBuilder, &outParams); 288 if (op.errorCode() == ErrorCode::KEY_RATE_LIMIT_EXCEEDED) { 289 sleep(ratelimit); 290 continue; 291 } else break; 292 } 293 294 if (op.errorCode() != ErrorCode::OK) { 295 LOG(ERROR) << "Error starting keymaster signature transaction: " << int32_t(op.errorCode()); 296 return -1; 297 } 298 299 if (!op.updateCompletely(input, &output)) { 300 LOG(ERROR) << "Error sending data to keymaster signature transaction: " 301 << uint32_t(op.errorCode()); 302 return -1; 303 } 304 305 if (!op.finish(&output)) { 306 LOG(ERROR) << "Error finalizing keymaster signature transaction: " << int32_t(op.errorCode()); 307 return -1; 308 } 309 310 *signature_buffer = reinterpret_cast<uint8_t*>(malloc(output.size())); 311 if (*signature_buffer == nullptr) { 312 LOG(ERROR) << "Error allocation buffer for keymaster signature"; 313 return -1; 314 } 315 *signature_buffer_size = output.size(); 316 std::copy(output.data(), output.data() + output.size(), *signature_buffer); 317 return 0; 318} 319