Add abstract wrapper around IKeymasterDevice.

The "Keymaster" class provides an abstraction that hides the
underlying implementation.  It will always inherit the current
IKeymasterDevice version and extend it with additional pure virtual methods
that are used by keystore to query for meta information.  This class
will in turn have subclasses which will wrap an instance of each
different version of IKeymasterDevice that we support.

Test: CTS
Change-Id: I62420dc0a8c196bb3f19753a8f304d46a75fae0e
This commit is contained in:
Shawn Willden 2017-12-03 17:51:29 -07:00
parent 0efbf432c1
commit c67a8aa3f5
11 changed files with 312 additions and 32 deletions

View file

@ -22,6 +22,7 @@ cc_binary {
srcs: [
":IKeyAttestationApplicationIdProvider.aidl",
"KeyStore.cpp",
"Keymaster3.cpp",
"auth_token_table.cpp",
"blob.cpp",
"entropy.cpp",
@ -40,6 +41,7 @@ cc_binary {
shared_libs: [
"android.hardware.keymaster@3.0",
"android.system.wifi.keystore@1.0",
"libbase",
"libbinder",
"libcrypto",
"libcutils",

View file

@ -33,15 +33,16 @@
#include "permissions.h"
#include <keystore/keystore_hidl_support.h>
namespace keystore {
const char* KeyStore::sOldMasterKey = ".masterkey";
const char* KeyStore::sMetaDataFile = ".metadata";
const android::String16 KeyStore::sRSAKeyType("RSA");
using namespace keystore;
using android::String8;
KeyStore::KeyStore(Entropy* entropy, const km_device_t& device, const km_device_t& fallback,
KeyStore::KeyStore(Entropy* entropy, const sp<Keymaster>& device, const sp<Keymaster>& fallback,
bool allowNewFallback)
: mEntropy(entropy), mDevice(device), mFallbackDevice(fallback),
mAllowNewFallback(allowNewFallback) {
@ -798,3 +799,5 @@ bool KeyStore::upgradeKeystore() {
return upgraded;
}
} // namespace keystore

View file

@ -21,24 +21,25 @@
#include <utils/Vector.h>
#include "Keymaster.h"
#include "blob.h"
#include "grant_store.h"
#include "include/keystore/keymaster_tags.h"
#include "user_state.h"
using ::keystore::NullOr;
namespace keystore {
using ::android::sp;
class KeyStore {
typedef ::android::sp<::android::hardware::keymaster::V3_0::IKeymasterDevice> km_device_t;
public:
KeyStore(Entropy* entropy, const km_device_t& device, const km_device_t& fallback,
KeyStore(Entropy* entropy, const sp<Keymaster>& device, const sp<Keymaster>& fallback,
bool allowNewFallback);
~KeyStore();
km_device_t& getDevice() { return mDevice; }
sp<Keymaster>& getDevice() { return mDevice; }
NullOr<km_device_t&> getFallbackDevice() {
NullOr<sp<Keymaster>&> getFallbackDevice() {
// we only return the fallback device if the creation of new fallback key blobs is
// allowed. (also see getDevice below)
if (mAllowNewFallback) {
@ -48,7 +49,7 @@ class KeyStore {
}
}
km_device_t& getDevice(const Blob& blob) {
sp<Keymaster>& getDevice(const Blob& blob) {
// We return a device, based on the nature of the blob to provide backward
// compatibility with old key blobs generated using the fallback device.
return blob.isFallback() ? mFallbackDevice : mDevice;
@ -126,8 +127,8 @@ class KeyStore {
static const android::String16 sRSAKeyType;
Entropy* mEntropy;
km_device_t mDevice;
km_device_t mFallbackDevice;
sp<Keymaster> mDevice;
sp<Keymaster> mFallbackDevice;
bool mAllowNewFallback;
android::Vector<UserState*> mMasterKeys;
@ -157,4 +158,6 @@ class KeyStore {
bool upgradeKeystore();
};
} // namespace keystore
#endif // KEYSTORE_KEYSTORE_H_

53
keystore/Keymaster.h Normal file
View file

@ -0,0 +1,53 @@
/*
**
** Copyright 2017, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#ifndef SYSTEM_SECURITY_KEYSTORE_KEYMASTER__H_
#define SYSTEM_SECURITY_KEYSTORE_KEYMASTER__H_
#include <keystore/keymaster_tags.h>
#include <keystore/keymaster_types.h>
namespace keystore {
/**
* Keymaster abstracts the underlying Keymaster device. It will always inherit from the latest
* keymaster HAL interface, and there will be one subclass which is a trivial passthrough, for
* devices that actually support the latest version. One or more additional subclasses will handle
* wrapping older HAL versions, if needed.
*
* The reason for adding this additional layer, rather than simply using the latest HAL directly and
* subclassing it to wrap any older HAL, is because this provides a place to put additional
* methods which keystore can use when it needs to distinguish between different underlying HAL
* versions, while still having to use only the latest interface.
*/
class Keymaster : public keymaster::IKeymasterDevice {
public:
virtual ~Keymaster() {}
struct VersionResult {
ErrorCode error;
uint8_t majorVersion;
bool isSecure;
bool supportsEc;
};
virtual VersionResult halVersion() = 0;
};
} // namespace keystore
#endif // SYSTEM_SECURITY_KEYSTORE_KEYMASTER_DEVICE_H_

62
keystore/Keymaster3.cpp Normal file
View file

@ -0,0 +1,62 @@
/*
**
** Copyright 2017, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#include "Keymaster3.h"
#include <android-base/logging.h>
#include <keystore/keystore_hidl_support.h>
namespace keystore {
using android::hardware::hidl_string;
void Keymaster3::getVersionIfNeeded() {
if (haveVersion_) return;
auto rc = km3_dev_->getHardwareFeatures(
[&](bool isSecure, bool supportsEllipticCurve, bool supportsSymmetricCryptography,
bool supportsAttestation, bool supportsAllDigests, const hidl_string& keymasterName,
const hidl_string& keymasterAuthorName) {
isSecure_ = isSecure;
supportsEllipticCurve_ = supportsEllipticCurve;
supportsSymmetricCryptography_ = supportsSymmetricCryptography;
supportsAttestation_ = supportsAttestation;
supportsAllDigests_ = supportsAllDigests;
keymasterName_ = keymasterName;
authorName_ = keymasterAuthorName;
if (!isSecure) {
majorVersion_ = 3; // SW version is 3 (don't think this should happen).
} else if (supportsAttestation) {
majorVersion_ = 2; // Could be 3, no real difference.
} else if (supportsSymmetricCryptography) {
majorVersion_ = 1;
} else {
majorVersion_ = 0;
}
});
CHECK(rc.isOk()) << "Got error " << rc.description() << " trying to get hardware features";
}
Keymaster::VersionResult Keymaster3::halVersion() {
getVersionIfNeeded();
return {ErrorCode::OK, majorVersion_, isSecure_, supportsEllipticCurve_};
}
} // namespace keystore

130
keystore/Keymaster3.h Normal file
View file

@ -0,0 +1,130 @@
/*
**
** Copyright 2017, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#ifndef KEYSTORE_KEYMASTER_3_H_
#define KEYSTORE_KEYMASTER_3_H_
#include <keystore/keymaster_types.h>
#include <utils/StrongPointer.h>
#include "Keymaster.h"
namespace keystore {
using android::sp;
using IKeymaster3Device = ::android::hardware::keymaster::V3_0::IKeymasterDevice;
class Keymaster3 : public Keymaster {
public:
Keymaster3(sp<IKeymasterDevice> km3_dev) : km3_dev_(km3_dev) {}
VersionResult halVersion() override;
Return<void> getHardwareFeatures(getHardwareFeatures_cb _hidl_cb) override {
getVersionIfNeeded();
_hidl_cb(isSecure_, supportsEllipticCurve_, supportsSymmetricCryptography_,
supportsAttestation_, supportsAllDigests_,
keymasterName_ + " (wrapped by keystore::Keymaster3)", authorName_);
return android::hardware::Void();
}
Return<ErrorCode> addRngEntropy(const hidl_vec<uint8_t>& data) override {
return km3_dev_->addRngEntropy(data);
}
Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams,
generateKey_cb _hidl_cb) override {
return km3_dev_->generateKey(keyParams, _hidl_cb);
}
Return<void> getKeyCharacteristics(const hidl_vec<uint8_t>& keyBlob,
const hidl_vec<uint8_t>& clientId,
const hidl_vec<uint8_t>& appData,
getKeyCharacteristics_cb _hidl_cb) override {
return km3_dev_->getKeyCharacteristics(keyBlob, clientId, appData, _hidl_cb);
}
Return<void> importKey(const hidl_vec<KeyParameter>& params, KeyFormat keyFormat,
const hidl_vec<uint8_t>& keyData, importKey_cb _hidl_cb) override {
return km3_dev_->importKey(params, keyFormat, keyData, _hidl_cb);
}
Return<void> exportKey(KeyFormat exportFormat, const hidl_vec<uint8_t>& keyBlob,
const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8_t>& appData,
exportKey_cb _hidl_cb) override {
return km3_dev_->exportKey(exportFormat, keyBlob, clientId, appData, _hidl_cb);
}
Return<void> attestKey(const hidl_vec<uint8_t>& keyToAttest,
const hidl_vec<KeyParameter>& attestParams,
attestKey_cb _hidl_cb) override {
return km3_dev_->attestKey(keyToAttest, attestParams, _hidl_cb);
}
Return<void> upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
const hidl_vec<KeyParameter>& upgradeParams,
upgradeKey_cb _hidl_cb) override {
return km3_dev_->upgradeKey(keyBlobToUpgrade, upgradeParams, _hidl_cb);
}
Return<ErrorCode> deleteKey(const hidl_vec<uint8_t>& keyBlob) override {
return km3_dev_->deleteKey(keyBlob);
}
Return<ErrorCode> deleteAllKeys() override { return km3_dev_->deleteAllKeys(); }
Return<ErrorCode> destroyAttestationIds() override { return km3_dev_->destroyAttestationIds(); }
Return<void> begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
const hidl_vec<KeyParameter>& inParams, begin_cb _hidl_cb) override {
return km3_dev_->begin(purpose, key, inParams, _hidl_cb);
}
Return<void> update(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
const hidl_vec<uint8_t>& input, update_cb _hidl_cb) override {
return km3_dev_->update(operationHandle, inParams, input, _hidl_cb);
}
Return<void> finish(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
const hidl_vec<uint8_t>& input, const hidl_vec<uint8_t>& signature,
finish_cb _hidl_cb) override {
return km3_dev_->finish(operationHandle, inParams, input, signature, _hidl_cb);
}
Return<ErrorCode> abort(uint64_t operationHandle) override {
return km3_dev_->abort(operationHandle);
}
private:
void getVersionIfNeeded();
sp<IKeymaster3Device> km3_dev_;
bool haveVersion_ = false;
uint8_t majorVersion_;
bool isSecure_;
bool supportsEllipticCurve_;
bool supportsSymmetricCryptography_;
bool supportsAttestation_;
bool supportsAllDigests_;
std::string keymasterName_;
std::string authorName_;
};
} // namespace keystore
#endif // KEYSTORE_KEYMASTER_3_H_

View file

@ -0,0 +1,29 @@
// Copyright 2017 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
#include <android/hardware/keymaster/3.0/types.h>
/**
* This header lifts the types from the current Keymaster version into the keystore namespace.
*/
namespace keystore {
namespace keymaster = ::android::hardware::keymaster::V3_0;
using keymaster::IKeymasterDevice;
using keymaster::SecurityLevel;
} // namespace keystore

View file

@ -1832,7 +1832,7 @@ bool KeyStoreService::checkAllowedOperationParams(const hidl_vec<KeyParameter>&
}
ErrorCode KeyStoreService::getOperationCharacteristics(const hidl_vec<uint8_t>& key,
km_device_t* dev,
sp<Keymaster>* dev,
const AuthorizationSet& params,
KeyCharacteristics* out) {
::std::vector<uint8_t> appId;

View file

@ -35,10 +35,9 @@ namespace keystore {
// binder::Status. Input parameters cannot be null unless annotated with @nullable in .aidl file.
class KeyStoreService : public android::security::BnKeystoreService,
android::IBinder::DeathRecipient {
typedef ::android::sp<::android::hardware::keymaster::V3_0::IKeymasterDevice> km_device_t;
public:
explicit KeyStoreService(KeyStore* keyStore) : mKeyStore(keyStore), mOperationMap(this) {}
virtual ~KeyStoreService() = default;
void binderDied(const android::wp<android::IBinder>& who);
@ -217,7 +216,7 @@ class KeyStoreService : public android::security::BnKeystoreService,
*/
bool checkAllowedOperationParams(const hidl_vec<KeyParameter>& params);
ErrorCode getOperationCharacteristics(const hidl_vec<uint8_t>& key, km_device_t* dev,
ErrorCode getOperationCharacteristics(const hidl_vec<uint8_t>& key, sp<Keymaster>* dev,
const AuthorizationSet& params, KeyCharacteristics* out);
/**
@ -274,7 +273,7 @@ class KeyStoreService : public android::security::BnKeystoreService,
KeyStoreServiceReturnCode upgradeKeyBlob(const android::String16& name, uid_t targetUid,
const AuthorizationSet& params, Blob* blob);
::KeyStore* mKeyStore;
KeyStore* mKeyStore;
OperationMap mOperationMap;
keystore::AuthTokenTable mAuthTokenTable;
KeystoreKeymasterEnforcement enforcement_policy;

View file

@ -17,16 +17,15 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "keystore"
#include <android/system/wifi/keystore/1.0/IKeystore.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <android/hardware/keymaster/3.0/IHwKeymasterDevice.h>
#include <android/system/wifi/keystore/1.0/IKeystore.h>
#include <cutils/log.h>
#include <utils/StrongPointer.h>
#include <wifikeystorehal/keystore.h>
#include <cutils/log.h>
#include "KeyStore.h"
#include "Keymaster3.h"
#include "entropy.h"
#include "include/keystore/keystore_hidl_support.h"
#include "include/keystore/keystore_return_types.h"
@ -41,10 +40,13 @@
* user-defined password. To keep things simple, buffers are always larger than
* the maximum space we needed, so boundary checks on buffers are omitted. */
using ::android::sp;
using ::android::hardware::configureRpcThreadpool;
using ::android::system::wifi::keystore::V1_0::IKeystore;
using ::android::system::wifi::keystore::V1_0::implementation::Keystore;
using keystore::Keymaster;
/**
* TODO implement keystore daemon using binderized keymaster HAL.
*/
@ -65,14 +67,13 @@ int main(int argc, char* argv[]) {
return 1;
}
auto dev = android::hardware::keymaster::V3_0::IKeymasterDevice::getService();
if (dev.get() == nullptr) {
return -1;
}
auto fallback = android::keystore::makeSoftwareKeymasterDevice();
if (dev.get() == nullptr) {
return -1;
}
auto hwdev = android::hardware::keymaster::V3_0::IKeymasterDevice::getService();
if (hwdev.get() == nullptr) return -1;
sp<Keymaster> dev = new keystore::Keymaster3(hwdev);
auto fbdev = android::keystore::makeSoftwareKeymasterDevice();
if (fbdev.get() == nullptr) return -1;
sp<Keymaster> fallback = new keystore::Keymaster3(fbdev);
if (configure_selinux() == -1) {
return -1;
@ -94,7 +95,7 @@ int main(int argc, char* argv[]) {
return -1;
}
KeyStore keyStore(&entropy, dev, fallback, allowNewFallbackDevice);
keystore::KeyStore keyStore(&entropy, dev, fallback, allowNewFallbackDevice);
keyStore.initialize();
android::sp<android::IServiceManager> sm = android::defaultServiceManager();
android::sp<keystore::KeyStoreService> service = new keystore::KeyStoreService(&keyStore);

View file

@ -24,8 +24,6 @@
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <hardware/keymaster_defs.h>
#include <memory>
#include <keystore/authorization_set.h>