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:
parent
0efbf432c1
commit
c67a8aa3f5
11 changed files with 312 additions and 32 deletions
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
53
keystore/Keymaster.h
Normal 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
62
keystore/Keymaster3.cpp
Normal 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
130
keystore/Keymaster3.h
Normal 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_
|
29
keystore/include/keystore/keymaster_types.h
Normal file
29
keystore/include/keystore/keymaster_types.h
Normal 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
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
#include <hardware/keymaster_defs.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <keystore/authorization_set.h>
|
||||
|
|
Loading…
Reference in a new issue