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