blob: 57b94b2c41ca3269c1aaa74c4d79003fd1145d5e [file] [log] [blame]
Shawn Willden6507c272016-01-05 22:51:48 -07001/*
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 <keymaster/soft_keymaster_device.h>
21#include <keymaster/soft_keymaster_logger.h>
22
23#include <binder/IPCThreadState.h>
24#include <binder/IServiceManager.h>
25
26#include <cutils/log.h>
27
28#include "entropy.h"
29#include "key_store_service.h"
30#include "keystore.h"
31#include "permissions.h"
32
33/* KeyStore is a secured storage for key-value pairs. In this implementation,
34 * each file stores one key-value pair. Keys are encoded in file names, and
35 * values are encrypted with checksums. The encryption key is protected by a
36 * user-defined password. To keep things simple, buffers are always larger than
37 * the maximum space we needed, so boundary checks on buffers are omitted. */
38
39using keymaster::SoftKeymasterDevice;
40
41static int keymaster0_device_initialize(const hw_module_t* mod, keymaster1_device_t** dev) {
42 assert(mod->module_api_version < KEYMASTER_MODULE_API_VERSION_1_0);
43 ALOGI("Found keymaster0 module %s, version %x", mod->name, mod->module_api_version);
44
45 UniquePtr<SoftKeymasterDevice> soft_keymaster(new SoftKeymasterDevice);
46 keymaster0_device_t* km0_device = NULL;
47 keymaster_error_t error = KM_ERROR_OK;
48
49 int rc = keymaster0_open(mod, &km0_device);
50 if (rc) {
51 ALOGE("Error opening keystore keymaster0 device.");
52 goto err;
53 }
54
55 if (km0_device->flags & KEYMASTER_SOFTWARE_ONLY) {
56 ALOGI("Keymaster0 module is software-only. Using SoftKeymasterDevice instead.");
57 km0_device->common.close(&km0_device->common);
58 km0_device = NULL;
59 // SoftKeymasterDevice will be deleted by keymaster_device_release()
60 *dev = soft_keymaster.release()->keymaster_device();
61 return 0;
62 }
63
64 ALOGE("Wrapping keymaster0 module %s with SoftKeymasterDevice", mod->name);
65 error = soft_keymaster->SetHardwareDevice(km0_device);
66 km0_device = NULL; // SoftKeymasterDevice has taken ownership.
67 if (error != KM_ERROR_OK) {
68 ALOGE("Got error %d from SetHardwareDevice", error);
69 rc = error;
70 goto err;
71 }
72
73 // SoftKeymasterDevice will be deleted by keymaster_device_release()
74 *dev = soft_keymaster.release()->keymaster_device();
75 return 0;
76
77err:
78 if (km0_device)
79 km0_device->common.close(&km0_device->common);
80 *dev = NULL;
81 return rc;
82}
83
84static int keymaster1_device_initialize(const hw_module_t* mod, keymaster1_device_t** dev) {
85 assert(mod->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0);
86 ALOGI("Found keymaster1 module %s, version %x", mod->name, mod->module_api_version);
87
88 UniquePtr<SoftKeymasterDevice> soft_keymaster(new SoftKeymasterDevice);
89 keymaster1_device_t* km1_device = NULL;
90 keymaster_error_t error = KM_ERROR_OK;
91
92 int rc = keymaster1_open(mod, &km1_device);
93 if (rc) {
94 ALOGE("Error %d opening keystore keymaster1 device", rc);
95 goto err;
96 }
97
98 error = soft_keymaster->SetHardwareDevice(km1_device);
99 km1_device = NULL; // SoftKeymasterDevice has taken ownership.
100 if (error != KM_ERROR_OK) {
101 ALOGE("Got error %d from SetHardwareDevice", error);
102 rc = error;
103 goto err;
104 }
105
106 if (!soft_keymaster->Keymaster1DeviceIsGood()) {
107 ALOGI("Keymaster1 module is incomplete, using SoftKeymasterDevice wrapper");
108 // SoftKeymasterDevice will be deleted by keymaster_device_release()
109 *dev = soft_keymaster.release()->keymaster_device();
110 return 0;
111 } else {
112 ALOGI("Keymaster1 module is good, destroying wrapper and re-opening");
113 soft_keymaster.reset(NULL);
114 rc = keymaster1_open(mod, &km1_device);
115 if (rc) {
116 ALOGE("Error %d re-opening keystore keymaster1 device.", rc);
117 goto err;
118 }
119 *dev = km1_device;
120 return 0;
121 }
122
123err:
124 if (km1_device)
125 km1_device->common.close(&km1_device->common);
126 *dev = NULL;
127 return rc;
128}
129
130static int keymaster_device_initialize(keymaster1_device_t** dev) {
131 const hw_module_t* mod;
132
133 int rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod);
134 if (rc) {
135 ALOGI("Could not find any keystore module, using software-only implementation.");
136 // SoftKeymasterDevice will be deleted by keymaster_device_release()
137 *dev = (new SoftKeymasterDevice)->keymaster_device();
138 return 0;
139 }
140
141 if (mod->module_api_version < KEYMASTER_MODULE_API_VERSION_1_0) {
142 return keymaster0_device_initialize(mod, dev);
143 } else {
144 return keymaster1_device_initialize(mod, dev);
145 }
146}
147
148// softkeymaster_logger appears not to be used in keystore, but it installs itself as the
149// logger used by SoftKeymasterDevice.
150static keymaster::SoftKeymasterLogger softkeymaster_logger;
151
152static int fallback_keymaster_device_initialize(keymaster1_device_t** dev) {
153 *dev = (new SoftKeymasterDevice)->keymaster_device();
154 // SoftKeymasterDevice will be deleted by keymaster_device_release()
155 return 0;
156}
157
158static void keymaster_device_release(keymaster1_device_t* dev) {
159 dev->common.close(&dev->common);
160}
161
162int main(int argc, char* argv[]) {
163 if (argc < 2) {
164 ALOGE("A directory must be specified!");
165 return 1;
166 }
167 if (chdir(argv[1]) == -1) {
168 ALOGE("chdir: %s: %s", argv[1], strerror(errno));
169 return 1;
170 }
171
172 Entropy entropy;
173 if (!entropy.open()) {
174 return 1;
175 }
176
177 keymaster1_device_t* dev;
178 if (keymaster_device_initialize(&dev)) {
179 ALOGE("keystore keymaster could not be initialized; exiting");
180 return 1;
181 }
182
183 keymaster1_device_t* fallback;
184 if (fallback_keymaster_device_initialize(&fallback)) {
185 ALOGE("software keymaster could not be initialized; exiting");
186 return 1;
187 }
188
189 if (configure_selinux() == -1) {
190 return -1;
191 }
192
193 KeyStore keyStore(&entropy, dev, fallback);
194 keyStore.initialize();
195 android::sp<android::IServiceManager> sm = android::defaultServiceManager();
196 android::sp<android::KeyStoreService> service = new android::KeyStoreService(&keyStore);
197 android::status_t ret = sm->addService(android::String16("android.security.keystore"), service);
198 if (ret != android::OK) {
199 ALOGE("Couldn't register binder service!");
200 return -1;
201 }
202
203 /*
204 * We're the only thread in existence, so we're just going to process
205 * Binder transaction as a single-threaded program.
206 */
207 android::IPCThreadState::self()->joinThreadPool();
208
209 keymaster_device_release(dev);
210 return 1;
211}