| Shawn Willden | 6507c27 | 2016-01-05 22:51:48 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2009 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 |  | 
| Janis Danisevskis | c146014 | 2017-12-18 16:48:46 -0800 | [diff] [blame] | 17 | #define LOG_TAG "keystore" | 
|  | 18 |  | 
| Shawn Willden | 0329a82 | 2017-12-04 13:55:14 -0700 | [diff] [blame] | 19 | #include <android-base/logging.h> | 
| Janis Danisevskis | c146014 | 2017-12-18 16:48:46 -0800 | [diff] [blame] | 20 | #include <android/hidl/manager/1.1/IServiceManager.h> | 
| Shawn Willden | bb22a6c | 2017-12-06 19:35:28 -0700 | [diff] [blame] | 21 | #include <android/security/IKeystoreService.h> | 
| Shawn Willden | c67a8aa | 2017-12-03 17:51:29 -0700 | [diff] [blame] | 22 | #include <android/system/wifi/keystore/1.0/IKeystore.h> | 
| Shawn Willden | 6507c27 | 2016-01-05 22:51:48 -0700 | [diff] [blame] | 23 | #include <binder/IPCThreadState.h> | 
|  | 24 | #include <binder/IServiceManager.h> | 
| Shawn Willden | bb22a6c | 2017-12-06 19:35:28 -0700 | [diff] [blame] | 25 | #include <hidl/HidlTransportSupport.h> | 
| Shawn Willden | eedcfe9 | 2018-01-18 15:35:46 -0700 | [diff] [blame] | 26 | #include <keymasterV4_0/Keymaster3.h> | 
|  | 27 | #include <keymasterV4_0/Keymaster4.h> | 
| Shawn Willden | c67a8aa | 2017-12-03 17:51:29 -0700 | [diff] [blame] | 28 | #include <utils/StrongPointer.h> | 
| Roshan Pius | e653c93 | 2017-03-29 10:08:47 -0700 | [diff] [blame] | 29 | #include <wifikeystorehal/keystore.h> | 
| Janis Danisevskis | c7a9fa2 | 2016-10-13 18:43:45 +0100 | [diff] [blame] | 30 |  | 
| Shawn Willden | bb22a6c | 2017-12-06 19:35:28 -0700 | [diff] [blame] | 31 | #include <keystore/keystore_hidl_support.h> | 
|  | 32 | #include <keystore/keystore_return_types.h> | 
|  | 33 |  | 
| Shawn Willden | fa5702f | 2017-12-03 15:14:58 -0700 | [diff] [blame] | 34 | #include "KeyStore.h" | 
| Shawn Willden | 6507c27 | 2016-01-05 22:51:48 -0700 | [diff] [blame] | 35 | #include "entropy.h" | 
| Shawn Willden | fa5702f | 2017-12-03 15:14:58 -0700 | [diff] [blame] | 36 | #include "key_store_service.h" | 
|  | 37 | #include "legacy_keymaster_device_wrapper.h" | 
|  | 38 | #include "permissions.h" | 
| Shawn Willden | 6507c27 | 2016-01-05 22:51:48 -0700 | [diff] [blame] | 39 |  | 
|  | 40 | /* KeyStore is a secured storage for key-value pairs. In this implementation, | 
|  | 41 | * each file stores one key-value pair. Keys are encoded in file names, and | 
|  | 42 | * values are encrypted with checksums. The encryption key is protected by a | 
|  | 43 | * user-defined password. To keep things simple, buffers are always larger than | 
|  | 44 | * the maximum space we needed, so boundary checks on buffers are omitted. */ | 
|  | 45 |  | 
| Shawn Willden | c67a8aa | 2017-12-03 17:51:29 -0700 | [diff] [blame] | 46 | using ::android::sp; | 
| Shawn Willden | fa5702f | 2017-12-03 15:14:58 -0700 | [diff] [blame] | 47 | using ::android::hardware::configureRpcThreadpool; | 
| Roshan Pius | e653c93 | 2017-03-29 10:08:47 -0700 | [diff] [blame] | 48 | using ::android::system::wifi::keystore::V1_0::IKeystore; | 
|  | 49 | using ::android::system::wifi::keystore::V1_0::implementation::Keystore; | 
| Janis Danisevskis | c146014 | 2017-12-18 16:48:46 -0800 | [diff] [blame] | 50 | using ::android::hidl::manager::V1_1::IServiceManager; | 
|  | 51 | using ::android::hardware::hidl_string; | 
|  | 52 | using ::android::hardware::hidl_vec; | 
|  | 53 | using ::android::hardware::keymaster::V4_0::SecurityLevel; | 
| Janis Danisevskis | 3506d33 | 2017-12-19 16:27:28 -0800 | [diff] [blame] | 54 | using ::android::hardware::keymaster::V4_0::HmacSharingParameters; | 
|  | 55 | using ::android::hardware::keymaster::V4_0::ErrorCode; | 
| Roshan Pius | e653c93 | 2017-03-29 10:08:47 -0700 | [diff] [blame] | 56 |  | 
| Shawn Willden | eedcfe9 | 2018-01-18 15:35:46 -0700 | [diff] [blame] | 57 | using ::keystore::keymaster::support::Keymaster; | 
|  | 58 | using ::keystore::keymaster::support::Keymaster3; | 
|  | 59 | using ::keystore::keymaster::support::Keymaster4; | 
| Shawn Willden | c67a8aa | 2017-12-03 17:51:29 -0700 | [diff] [blame] | 60 |  | 
| Janis Danisevskis | c146014 | 2017-12-18 16:48:46 -0800 | [diff] [blame] | 61 | using keystore::KeymasterDevices; | 
|  | 62 |  | 
|  | 63 | template <typename Wrapper> | 
|  | 64 | KeymasterDevices enumerateKeymasterDevices(IServiceManager* serviceManager) { | 
|  | 65 | KeymasterDevices result; | 
|  | 66 | serviceManager->listByInterface( | 
|  | 67 | Wrapper::WrappedIKeymasterDevice::descriptor, [&](const hidl_vec<hidl_string>& names) { | 
|  | 68 | auto try_get_device = [&](const auto& name, bool fail_silent) { | 
|  | 69 | auto device = Wrapper::WrappedIKeymasterDevice::getService(name); | 
|  | 70 | if (fail_silent && !device) return; | 
|  | 71 | CHECK(device) << "Failed to get service for \"" | 
|  | 72 | << Wrapper::WrappedIKeymasterDevice::descriptor | 
|  | 73 | << "\" with interface name \"" << name << "\""; | 
|  | 74 |  | 
| Shawn Willden | cd416c5 | 2018-01-22 09:37:43 -0700 | [diff] [blame] | 75 | sp<Keymaster> kmDevice(new Wrapper(device, name)); | 
| Janis Danisevskis | c146014 | 2017-12-18 16:48:46 -0800 | [diff] [blame] | 76 | auto halVersion = kmDevice->halVersion(); | 
|  | 77 | SecurityLevel securityLevel = halVersion.securityLevel; | 
|  | 78 | LOG(INFO) << "found " << Wrapper::WrappedIKeymasterDevice::descriptor | 
|  | 79 | << " with interface name " << name << " and seclevel " | 
|  | 80 | << toString(securityLevel); | 
|  | 81 | CHECK(static_cast<uint32_t>(securityLevel) < result.size()) | 
|  | 82 | << "Security level of \"" << Wrapper::WrappedIKeymasterDevice::descriptor | 
|  | 83 | << "\" with interface name \"" << name << "\" out of range"; | 
|  | 84 | auto& deviceSlot = result[securityLevel]; | 
|  | 85 | if (deviceSlot) { | 
|  | 86 | if (!fail_silent) { | 
|  | 87 | LOG(WARNING) << "Implementation of \"" | 
|  | 88 | << Wrapper::WrappedIKeymasterDevice::descriptor | 
|  | 89 | << "\" with interface name \"" << name | 
|  | 90 | << "\" and security level: " << toString(securityLevel) | 
|  | 91 | << " Masked by other implementation of Keymaster"; | 
|  | 92 | } | 
|  | 93 | } else { | 
|  | 94 | deviceSlot = kmDevice; | 
|  | 95 | } | 
|  | 96 | }; | 
|  | 97 | bool has_default = false; | 
|  | 98 | for (auto& n : names) { | 
|  | 99 | try_get_device(n, false); | 
|  | 100 | if (n == "default") has_default = true; | 
|  | 101 | } | 
|  | 102 | // Make sure that we always check the default device. If we enumerate only what is | 
|  | 103 | // known to hwservicemanager, we miss a possible passthrough HAL. | 
|  | 104 | if (!has_default) { | 
|  | 105 | try_get_device("default", true /* fail_silent */); | 
|  | 106 | } | 
|  | 107 | }); | 
|  | 108 | return result; | 
|  | 109 | } | 
|  | 110 |  | 
|  | 111 | KeymasterDevices initializeKeymasters() { | 
|  | 112 | auto serviceManager = android::hidl::manager::V1_1::IServiceManager::getService(); | 
|  | 113 | CHECK(serviceManager.get()) << "Failed to get ServiceManager"; | 
|  | 114 | auto result = enumerateKeymasterDevices<Keymaster4>(serviceManager.get()); | 
| Janis Danisevskis | c146014 | 2017-12-18 16:48:46 -0800 | [diff] [blame] | 115 | auto softKeymaster = result[SecurityLevel::SOFTWARE]; | 
| Shawn Willden | 5a6afd0 | 2018-05-09 15:47:15 -0600 | [diff] [blame] | 116 | if (!result[SecurityLevel::TRUSTED_ENVIRONMENT]) { | 
| Janis Danisevskis | c146014 | 2017-12-18 16:48:46 -0800 | [diff] [blame] | 117 | result = enumerateKeymasterDevices<Keymaster3>(serviceManager.get()); | 
|  | 118 | } | 
|  | 119 | if (softKeymaster) result[SecurityLevel::SOFTWARE] = softKeymaster; | 
|  | 120 | if (result[SecurityLevel::SOFTWARE] && !result[SecurityLevel::TRUSTED_ENVIRONMENT]) { | 
|  | 121 | LOG(WARNING) << "No secure Keymaster implementation found, but device offers insecure" | 
|  | 122 | " Keymaster HAL. Using as default."; | 
|  | 123 | result[SecurityLevel::TRUSTED_ENVIRONMENT] = result[SecurityLevel::SOFTWARE]; | 
|  | 124 | result[SecurityLevel::SOFTWARE] = nullptr; | 
|  | 125 | } | 
|  | 126 | if (!result[SecurityLevel::SOFTWARE]) { | 
|  | 127 | auto fbdev = android::keystore::makeSoftwareKeymasterDevice(); | 
|  | 128 | CHECK(fbdev.get()) << "Unable to create Software Keymaster Device"; | 
| Shawn Willden | cd416c5 | 2018-01-22 09:37:43 -0700 | [diff] [blame] | 129 | result[SecurityLevel::SOFTWARE] = new Keymaster3(fbdev, "Software"); | 
| Janis Danisevskis | c146014 | 2017-12-18 16:48:46 -0800 | [diff] [blame] | 130 | } | 
|  | 131 | return result; | 
|  | 132 | } | 
| Shawn Willden | 6507c27 | 2016-01-05 22:51:48 -0700 | [diff] [blame] | 133 |  | 
|  | 134 | int main(int argc, char* argv[]) { | 
| Shawn Willden | b8550a0 | 2017-02-23 11:06:05 -0700 | [diff] [blame] | 135 | using android::hardware::hidl_string; | 
| Shawn Willden | 0329a82 | 2017-12-04 13:55:14 -0700 | [diff] [blame] | 136 | CHECK(argc >= 2) << "A directory must be specified!"; | 
|  | 137 | CHECK(chdir(argv[1]) != -1) << "chdir: " << argv[1] << ": " << strerror(errno); | 
| Shawn Willden | 6507c27 | 2016-01-05 22:51:48 -0700 | [diff] [blame] | 138 |  | 
|  | 139 | Entropy entropy; | 
| Shawn Willden | 0329a82 | 2017-12-04 13:55:14 -0700 | [diff] [blame] | 140 | CHECK(entropy.open()) << "Failed to open entropy source."; | 
| Shawn Willden | 6507c27 | 2016-01-05 22:51:48 -0700 | [diff] [blame] | 141 |  | 
| Janis Danisevskis | c146014 | 2017-12-18 16:48:46 -0800 | [diff] [blame] | 142 | auto kmDevices = initializeKeymasters(); | 
| Shawn Willden | c67a8aa | 2017-12-03 17:51:29 -0700 | [diff] [blame] | 143 |  | 
| Janis Danisevskis | c146014 | 2017-12-18 16:48:46 -0800 | [diff] [blame] | 144 | CHECK(kmDevices[SecurityLevel::SOFTWARE]) << "Missing software Keymaster device"; | 
|  | 145 | CHECK(kmDevices[SecurityLevel::TRUSTED_ENVIRONMENT]) | 
|  | 146 | << "Error no viable keymaster device found"; | 
| Shawn Willden | 814a6e7 | 2016-03-15 08:37:29 -0600 | [diff] [blame] | 147 |  | 
| Shawn Willden | 0329a82 | 2017-12-04 13:55:14 -0700 | [diff] [blame] | 148 | CHECK(configure_selinux() != -1) << "Failed to configure SELinux."; | 
| Shawn Willden | 6507c27 | 2016-01-05 22:51:48 -0700 | [diff] [blame] | 149 |  | 
| Janis Danisevskis | c146014 | 2017-12-18 16:48:46 -0800 | [diff] [blame] | 150 | auto halVersion = kmDevices[SecurityLevel::TRUSTED_ENVIRONMENT]->halVersion(); | 
| Janis Danisevskis | e8ba180 | 2017-01-30 10:49:51 +0000 | [diff] [blame] | 151 |  | 
| Shawn Willden | 0329a82 | 2017-12-04 13:55:14 -0700 | [diff] [blame] | 152 | // If the hardware is keymaster 2.0 or higher we will not allow the fallback device for import | 
|  | 153 | // or generation of keys. The fallback device is only used for legacy keys present on the | 
|  | 154 | // device. | 
| Janis Danisevskis | c146014 | 2017-12-18 16:48:46 -0800 | [diff] [blame] | 155 | SecurityLevel minimalAllowedSecurityLevelForNewKeys = | 
|  | 156 | halVersion.majorVersion >= 2 ? SecurityLevel::TRUSTED_ENVIRONMENT : SecurityLevel::SOFTWARE; | 
| Janis Danisevskis | e8ba180 | 2017-01-30 10:49:51 +0000 | [diff] [blame] | 157 |  | 
| Janis Danisevskis | c146014 | 2017-12-18 16:48:46 -0800 | [diff] [blame] | 158 | keystore::KeyStore keyStore(&entropy, kmDevices, minimalAllowedSecurityLevelForNewKeys); | 
| Shawn Willden | 6507c27 | 2016-01-05 22:51:48 -0700 | [diff] [blame] | 159 | keyStore.initialize(); | 
|  | 160 | android::sp<android::IServiceManager> sm = android::defaultServiceManager(); | 
| Janis Danisevskis | c7a9fa2 | 2016-10-13 18:43:45 +0100 | [diff] [blame] | 161 | android::sp<keystore::KeyStoreService> service = new keystore::KeyStoreService(&keyStore); | 
| Shawn Willden | 6507c27 | 2016-01-05 22:51:48 -0700 | [diff] [blame] | 162 | android::status_t ret = sm->addService(android::String16("android.security.keystore"), service); | 
| Shawn Willden | 0329a82 | 2017-12-04 13:55:14 -0700 | [diff] [blame] | 163 | CHECK(ret == android::OK) << "Couldn't register binder service!"; | 
| Shawn Willden | 6507c27 | 2016-01-05 22:51:48 -0700 | [diff] [blame] | 164 |  | 
| Roshan Pius | e653c93 | 2017-03-29 10:08:47 -0700 | [diff] [blame] | 165 | /** | 
|  | 166 | * Register the wifi keystore HAL service to run in passthrough mode. | 
|  | 167 | * This will spawn off a new thread which will service the HIDL | 
|  | 168 | * transactions. | 
|  | 169 | */ | 
|  | 170 | configureRpcThreadpool(1, false /* callerWillJoin */); | 
|  | 171 | android::sp<IKeystore> wifiKeystoreHalService = new Keystore(); | 
|  | 172 | android::status_t err = wifiKeystoreHalService->registerAsService(); | 
| Shawn Willden | 0329a82 | 2017-12-04 13:55:14 -0700 | [diff] [blame] | 173 | CHECK(ret == android::OK) << "Cannot register wifi keystore HAL service: " << err; | 
| Roshan Pius | e653c93 | 2017-03-29 10:08:47 -0700 | [diff] [blame] | 174 |  | 
| Shawn Willden | 6507c27 | 2016-01-05 22:51:48 -0700 | [diff] [blame] | 175 | /* | 
| Roshan Pius | e653c93 | 2017-03-29 10:08:47 -0700 | [diff] [blame] | 176 | * This thread is just going to process Binder transactions. | 
| Shawn Willden | 6507c27 | 2016-01-05 22:51:48 -0700 | [diff] [blame] | 177 | */ | 
|  | 178 | android::IPCThreadState::self()->joinThreadPool(); | 
| Shawn Willden | 6507c27 | 2016-01-05 22:51:48 -0700 | [diff] [blame] | 179 | return 1; | 
|  | 180 | } |