16507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden/*
26507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden * Copyright (C) 2009 The Android Open Source Project
36507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden *
46507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden * Licensed under the Apache License, Version 2.0 (the "License");
56507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden * you may not use this file except in compliance with the License.
66507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden * You may obtain a copy of the License at
76507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden *
86507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden *      http://www.apache.org/licenses/LICENSE-2.0
96507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden *
106507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden * Unless required by applicable law or agreed to in writing, software
116507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden * distributed under the License is distributed on an "AS IS" BASIS,
126507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden * See the License for the specific language governing permissions and
146507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden * limitations under the License.
156507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden */
166507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden
176507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden//#define LOG_NDEBUG 0
186507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden#define LOG_TAG "keystore"
196507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden
206507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden#include <binder/IPCThreadState.h>
216507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden#include <binder/IServiceManager.h>
226507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden
23c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis#include <android/hardware/keymaster/3.0/IHwKeymasterDevice.h>
24e653c93db15400048605b49d74a21ec2c139afecRoshan Pius#include <android/system/wifi/keystore/1.0/IKeystore.h>
25e653c93db15400048605b49d74a21ec2c139afecRoshan Pius#include <wifikeystorehal/keystore.h>
26c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis
276507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden#include <cutils/log.h>
286507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden
296507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden#include "entropy.h"
306507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden#include "key_store_service.h"
316507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden#include "keystore.h"
326507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden#include "permissions.h"
33c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis#include "legacy_keymaster_device_wrapper.h"
34e8ba1802a649ada4cea78af133ab4fb549eb57f5Janis Danisevskis#include "include/keystore/keystore_hidl_support.h"
35e8ba1802a649ada4cea78af133ab4fb549eb57f5Janis Danisevskis#include "include/keystore/keystore_return_types.h"
366507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden
376507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden/* KeyStore is a secured storage for key-value pairs. In this implementation,
386507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden * each file stores one key-value pair. Keys are encoded in file names, and
396507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden * values are encrypted with checksums. The encryption key is protected by a
406507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden * user-defined password. To keep things simple, buffers are always larger than
416507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden * the maximum space we needed, so boundary checks on buffers are omitted. */
426507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden
43e653c93db15400048605b49d74a21ec2c139afecRoshan Piususing ::android::system::wifi::keystore::V1_0::IKeystore;
44e653c93db15400048605b49d74a21ec2c139afecRoshan Piususing ::android::system::wifi::keystore::V1_0::implementation::Keystore;
45e653c93db15400048605b49d74a21ec2c139afecRoshan Piususing ::android::hardware::configureRpcThreadpool;
46e653c93db15400048605b49d74a21ec2c139afecRoshan Pius
47c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis/**
48c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis * TODO implement keystore daemon using binderized keymaster HAL.
49c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis */
506507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden
516507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willdenint main(int argc, char* argv[]) {
52b8550a0929286bd8b91135c2beea1f61c01a441fShawn Willden    using android::hardware::hidl_string;
536507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden    if (argc < 2) {
546507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden        ALOGE("A directory must be specified!");
556507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden        return 1;
566507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden    }
576507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden    if (chdir(argv[1]) == -1) {
586507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden        ALOGE("chdir: %s: %s", argv[1], strerror(errno));
596507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden        return 1;
606507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden    }
616507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden
626507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden    Entropy entropy;
636507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden    if (!entropy.open()) {
646507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden        return 1;
656507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden    }
666507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden
679b3791caa8a5b5e93b8af5b0385470a16552f2b6Chris Phoenix    auto dev = android::hardware::keymaster::V3_0::IKeymasterDevice::getService();
68c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis    if (dev.get() == nullptr) {
69c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis        return -1;
706507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden    }
71c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis    auto fallback = android::keystore::makeSoftwareKeymasterDevice();
72c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis    if (dev.get() == nullptr) {
73c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis        return -1;
74814a6e725cd89ad6bf27a9951d25025dc9ace9a8Shawn Willden    }
75814a6e725cd89ad6bf27a9951d25025dc9ace9a8Shawn Willden
766507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden    if (configure_selinux() == -1) {
776507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden        return -1;
786507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden    }
796507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden
80e8ba1802a649ada4cea78af133ab4fb549eb57f5Janis Danisevskis    bool allowNewFallbackDevice = false;
81e8ba1802a649ada4cea78af133ab4fb549eb57f5Janis Danisevskis
82e8ba1802a649ada4cea78af133ab4fb549eb57f5Janis Danisevskis    keystore::KeyStoreServiceReturnCode rc;
83e8ba1802a649ada4cea78af133ab4fb549eb57f5Janis Danisevskis    rc = KS_HANDLE_HIDL_ERROR(dev->getHardwareFeatures(
84b8550a0929286bd8b91135c2beea1f61c01a441fShawn Willden            [&] (bool, bool, bool, bool supportsAttestation, bool, const hidl_string&,
85b8550a0929286bd8b91135c2beea1f61c01a441fShawn Willden                 const hidl_string&) {
86e8ba1802a649ada4cea78af133ab4fb549eb57f5Janis Danisevskis                // Attestation support indicates the hardware is keymaster 2.0 or higher.
87e8ba1802a649ada4cea78af133ab4fb549eb57f5Janis Danisevskis                // For these devices we will not allow the fallback device for import or generation
88e8ba1802a649ada4cea78af133ab4fb549eb57f5Janis Danisevskis                // of keys. The fallback device is only used for legacy keys present on the device.
89e8ba1802a649ada4cea78af133ab4fb549eb57f5Janis Danisevskis                allowNewFallbackDevice = !supportsAttestation;
90e8ba1802a649ada4cea78af133ab4fb549eb57f5Janis Danisevskis            }));
91e8ba1802a649ada4cea78af133ab4fb549eb57f5Janis Danisevskis
92e8ba1802a649ada4cea78af133ab4fb549eb57f5Janis Danisevskis    if (!rc.isOk()) {
93e8ba1802a649ada4cea78af133ab4fb549eb57f5Janis Danisevskis        return -1;
94e8ba1802a649ada4cea78af133ab4fb549eb57f5Janis Danisevskis    }
95e8ba1802a649ada4cea78af133ab4fb549eb57f5Janis Danisevskis
96e8ba1802a649ada4cea78af133ab4fb549eb57f5Janis Danisevskis    KeyStore keyStore(&entropy, dev, fallback, allowNewFallbackDevice);
976507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden    keyStore.initialize();
986507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden    android::sp<android::IServiceManager> sm = android::defaultServiceManager();
99c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis    android::sp<keystore::KeyStoreService> service = new keystore::KeyStoreService(&keyStore);
1006507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden    android::status_t ret = sm->addService(android::String16("android.security.keystore"), service);
1016507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden    if (ret != android::OK) {
1026507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden        ALOGE("Couldn't register binder service!");
1036507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden        return -1;
1046507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden    }
1056507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden
106e653c93db15400048605b49d74a21ec2c139afecRoshan Pius    /**
107e653c93db15400048605b49d74a21ec2c139afecRoshan Pius     * Register the wifi keystore HAL service to run in passthrough mode.
108e653c93db15400048605b49d74a21ec2c139afecRoshan Pius     * This will spawn off a new thread which will service the HIDL
109e653c93db15400048605b49d74a21ec2c139afecRoshan Pius     * transactions.
110e653c93db15400048605b49d74a21ec2c139afecRoshan Pius     */
111e653c93db15400048605b49d74a21ec2c139afecRoshan Pius    configureRpcThreadpool(1, false /* callerWillJoin */);
112e653c93db15400048605b49d74a21ec2c139afecRoshan Pius    android::sp<IKeystore> wifiKeystoreHalService = new Keystore();
113e653c93db15400048605b49d74a21ec2c139afecRoshan Pius    android::status_t err = wifiKeystoreHalService->registerAsService();
114e653c93db15400048605b49d74a21ec2c139afecRoshan Pius    if (ret != android::OK) {
115e653c93db15400048605b49d74a21ec2c139afecRoshan Pius        ALOGE("Cannot register wifi keystore HAL service: %d", err);
116e653c93db15400048605b49d74a21ec2c139afecRoshan Pius    }
117e653c93db15400048605b49d74a21ec2c139afecRoshan Pius
1186507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden    /*
119e653c93db15400048605b49d74a21ec2c139afecRoshan Pius     * This thread is just going to process Binder transactions.
1206507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden     */
1216507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden    android::IPCThreadState::self()->joinThreadPool();
1226507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden    return 1;
1236507c27ab7ea34dd150d7ef9fda41878ed32547cShawn Willden}
124