• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "keystore"
19 
20 #include <binder/IPCThreadState.h>
21 #include <binder/IServiceManager.h>
22 
23 #include <android/hardware/keymaster/3.0/IHwKeymasterDevice.h>
24 #include <android/system/wifi/keystore/1.0/IKeystore.h>
25 #include <wifikeystorehal/keystore.h>
26 
27 #include <cutils/log.h>
28 
29 #include "entropy.h"
30 #include "key_store_service.h"
31 #include "keystore.h"
32 #include "permissions.h"
33 #include "legacy_keymaster_device_wrapper.h"
34 #include "include/keystore/keystore_hidl_support.h"
35 #include "include/keystore/keystore_return_types.h"
36 
37 /* KeyStore is a secured storage for key-value pairs. In this implementation,
38  * each file stores one key-value pair. Keys are encoded in file names, and
39  * values are encrypted with checksums. The encryption key is protected by a
40  * user-defined password. To keep things simple, buffers are always larger than
41  * the maximum space we needed, so boundary checks on buffers are omitted. */
42 
43 using ::android::system::wifi::keystore::V1_0::IKeystore;
44 using ::android::system::wifi::keystore::V1_0::implementation::Keystore;
45 using ::android::hardware::configureRpcThreadpool;
46 
47 /**
48  * TODO implement keystore daemon using binderized keymaster HAL.
49  */
50 
main(int argc,char * argv[])51 int main(int argc, char* argv[]) {
52     using android::hardware::hidl_string;
53     if (argc < 2) {
54         ALOGE("A directory must be specified!");
55         return 1;
56     }
57     if (chdir(argv[1]) == -1) {
58         ALOGE("chdir: %s: %s", argv[1], strerror(errno));
59         return 1;
60     }
61 
62     Entropy entropy;
63     if (!entropy.open()) {
64         return 1;
65     }
66 
67     auto dev = android::hardware::keymaster::V3_0::IKeymasterDevice::getService();
68     if (dev.get() == nullptr) {
69         return -1;
70     }
71     auto fallback = android::keystore::makeSoftwareKeymasterDevice();
72     if (dev.get() == nullptr) {
73         return -1;
74     }
75 
76     if (configure_selinux() == -1) {
77         return -1;
78     }
79 
80     bool allowNewFallbackDevice = false;
81 
82     keystore::KeyStoreServiceReturnCode rc;
83     rc = KS_HANDLE_HIDL_ERROR(dev->getHardwareFeatures(
84             [&] (bool, bool, bool, bool supportsAttestation, bool, const hidl_string&,
85                  const hidl_string&) {
86                 // Attestation support indicates the hardware is keymaster 2.0 or higher.
87                 // For these devices we will not allow the fallback device for import or generation
88                 // of keys. The fallback device is only used for legacy keys present on the device.
89                 allowNewFallbackDevice = !supportsAttestation;
90             }));
91 
92     if (!rc.isOk()) {
93         return -1;
94     }
95 
96     KeyStore keyStore(&entropy, dev, fallback, allowNewFallbackDevice);
97     keyStore.initialize();
98     android::sp<android::IServiceManager> sm = android::defaultServiceManager();
99     android::sp<keystore::KeyStoreService> service = new keystore::KeyStoreService(&keyStore);
100     android::status_t ret = sm->addService(android::String16("android.security.keystore"), service);
101     if (ret != android::OK) {
102         ALOGE("Couldn't register binder service!");
103         return -1;
104     }
105 
106     /**
107      * Register the wifi keystore HAL service to run in passthrough mode.
108      * This will spawn off a new thread which will service the HIDL
109      * transactions.
110      */
111     configureRpcThreadpool(1, false /* callerWillJoin */);
112     android::sp<IKeystore> wifiKeystoreHalService = new Keystore();
113     android::status_t err = wifiKeystoreHalService->registerAsService();
114     if (ret != android::OK) {
115         ALOGE("Cannot register wifi keystore HAL service: %d", err);
116     }
117 
118     /*
119      * This thread is just going to process Binder transactions.
120      */
121     android::IPCThreadState::self()->joinThreadPool();
122     return 1;
123 }
124