diff options
author | Andrew Scull <ascull@google.com> | 2018-01-03 11:51:54 +0000 |
---|---|---|
committer | Andrew Scull <ascull@google.com> | 2018-01-10 18:06:51 +0000 |
commit | 7093431e82f0afe1ae7ce0f74802a107b962fd54 (patch) | |
tree | 54c3543bd2d6d2057dc460bdd966408a94c2fc87 /authsecret | |
parent | b4216c54bea761c983d9815ad36d1e77b230d832 (diff) | |
download | android_hardware_interfaces-7093431e82f0afe1ae7ce0f74802a107b962fd54.tar.gz android_hardware_interfaces-7093431e82f0afe1ae7ce0f74802a107b962fd54.tar.bz2 android_hardware_interfaces-7093431e82f0afe1ae7ce0f74802a107b962fd54.zip |
AuthSecret HAL
A security HAL to allow vendor to cryptographically tie components to
the primary user's credential.
Test: AuthSecretHidlTest
Bug: 71527305
Change-Id: I67ebf423dfccb00415d1d79b54e3ded31256cfff
Diffstat (limited to 'authsecret')
-rw-r--r-- | authsecret/1.0/Android.bp | 17 | ||||
-rw-r--r-- | authsecret/1.0/IAuthSecret.hal | 48 | ||||
-rw-r--r-- | authsecret/1.0/default/Android.bp | 21 | ||||
-rw-r--r-- | authsecret/1.0/default/AuthSecret.cpp | 47 | ||||
-rw-r--r-- | authsecret/1.0/default/AuthSecret.h | 36 | ||||
-rw-r--r-- | authsecret/1.0/default/android.hardware.authsecret@1.0-service.rc | 4 | ||||
-rw-r--r-- | authsecret/1.0/default/service.cpp | 41 | ||||
-rw-r--r-- | authsecret/1.0/vts/functional/Android.bp | 22 | ||||
-rw-r--r-- | authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp | 97 |
9 files changed, 333 insertions, 0 deletions
diff --git a/authsecret/1.0/Android.bp b/authsecret/1.0/Android.bp new file mode 100644 index 000000000..9cde99a5f --- /dev/null +++ b/authsecret/1.0/Android.bp @@ -0,0 +1,17 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.authsecret@1.0", + root: "android.hardware", + vndk: { + enabled: true, + }, + srcs: [ + "IAuthSecret.hal", + ], + interfaces: [ + "android.hidl.base@1.0", + ], + gen_java: true, +} + diff --git a/authsecret/1.0/IAuthSecret.hal b/authsecret/1.0/IAuthSecret.hal new file mode 100644 index 000000000..d2cb5da54 --- /dev/null +++ b/authsecret/1.0/IAuthSecret.hal @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2018 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. + */ +package android.hardware.authsecret@1.0; + +/** + * This security HAL allows vendor components to be cryptographically tied to + * the primary user's credential. For example, security hardware could require + * proof that the credential is known before applying updates. + * + * This HAL is optional so does not require an implementation on device. + */ +interface IAuthSecret { + /** + * When the primary user correctly enters their credential, this method is + * passed a secret derived from that credential to prove that their + * credential is known. + * + * The first time this is called, the secret must be used to provision state + * that depends on the primary user's credential. The same secret is passed + * on each call until a factory reset after which there must be a new + * secret. + * + * The secret must be at lesat 16 bytes. + * + * @param secret blob derived from the primary user's credential. + */ + primaryUserCredential(vec<uint8_t> secret); + + /** + * Called from recovery during factory reset. The secret is now lost and can + * no longer be derived. Any data linked to the secret must be destroyed and + * any dependence on the secret must be removed. + */ + factoryReset(); +}; diff --git a/authsecret/1.0/default/Android.bp b/authsecret/1.0/default/Android.bp new file mode 100644 index 000000000..5c3234fc7 --- /dev/null +++ b/authsecret/1.0/default/Android.bp @@ -0,0 +1,21 @@ +cc_binary { + name: "android.hardware.authsecret@1.0-service", + init_rc: ["android.hardware.authsecret@1.0-service.rc"], + relative_install_path: "hw", + vendor: true, + srcs: [ + "service.cpp", + "AuthSecret.cpp", + ], + cflags: [ + "-Wall", + "-Werror", + ], + shared_libs: [ + "libhidlbase", + "libhidltransport", + "liblog", + "libutils", + "android.hardware.authsecret@1.0", + ], +} diff --git a/authsecret/1.0/default/AuthSecret.cpp b/authsecret/1.0/default/AuthSecret.cpp new file mode 100644 index 000000000..46a3ec121 --- /dev/null +++ b/authsecret/1.0/default/AuthSecret.cpp @@ -0,0 +1,47 @@ +#include "AuthSecret.h" + +namespace android { +namespace hardware { +namespace authsecret { +namespace V1_0 { +namespace implementation { + +// Methods from ::android::hardware::authsecret::V1_0::IAuthSecret follow. +Return<void> AuthSecret::primaryUserCredential(const hidl_vec<uint8_t>& secret) { + (void)secret; + + // To create a dependency on the credential, it is recommended to derive a + // different value from the provided secret for each purpose e.g. + // + // purpose1_secret = hash( "purpose1" || secret ) + // purpose2_secret = hash( "purpose2" || secret ) + // + // The derived values can then be used as cryptographic keys or stored + // securely for comparison in a future call. + // + // For example, a security module might require that the credential has been + // entered before it applies any updates. This can be achieved by storing a + // derived value in the module and only applying updates when the same + // derived value is presented again. + // + // This implementation does nothing. + + return Void(); +} + +Return<void> AuthSecret::factoryReset() { + // Clear all dependency on the secret. + // + // With the example of updating a security module, the stored value must be + // cleared so that the new primary user enrolled as the approver of updates. + // + // This implementation does nothing as there is no dependence on the secret. + + return Void(); +} + +} // namespace implementation +} // namespace V1_0 +} // namespace authsecret +} // namespace hardware +} // namespace android diff --git a/authsecret/1.0/default/AuthSecret.h b/authsecret/1.0/default/AuthSecret.h new file mode 100644 index 000000000..edb49b856 --- /dev/null +++ b/authsecret/1.0/default/AuthSecret.h @@ -0,0 +1,36 @@ +#ifndef ANDROID_HARDWARE_AUTHSECRET_V1_0_AUTHSECRET_H +#define ANDROID_HARDWARE_AUTHSECRET_V1_0_AUTHSECRET_H + +#include <android/hardware/authsecret/1.0/IAuthSecret.h> +#include <hidl/MQDescriptor.h> +#include <hidl/Status.h> + +namespace android { +namespace hardware { +namespace authsecret { +namespace V1_0 { +namespace implementation { + +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_memory; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::sp; + +struct AuthSecret : public IAuthSecret { + // Methods from ::android::hardware::authsecret::V1_0::IAuthSecret follow. + Return<void> primaryUserCredential(const hidl_vec<uint8_t>& secret) override; + Return<void> factoryReset() override; + + // Methods from ::android::hidl::base::V1_0::IBase follow. +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace authsecret +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_AUTHSECRET_V1_0_AUTHSECRET_H diff --git a/authsecret/1.0/default/android.hardware.authsecret@1.0-service.rc b/authsecret/1.0/default/android.hardware.authsecret@1.0-service.rc new file mode 100644 index 000000000..e82da7eef --- /dev/null +++ b/authsecret/1.0/default/android.hardware.authsecret@1.0-service.rc @@ -0,0 +1,4 @@ +service vendor.authsecret-1-0 /vendor/bin/hw/android.hardware.authsecret@1.0-service + class hal + user system + group system diff --git a/authsecret/1.0/default/service.cpp b/authsecret/1.0/default/service.cpp new file mode 100644 index 000000000..4acd16c72 --- /dev/null +++ b/authsecret/1.0/default/service.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.1 (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.1 + * + * 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. + */ + +#define LOG_TAG "android.hardware.authsecret@1.0-service" + +#include <android/hardware/authsecret/1.0/IAuthSecret.h> +#include <hidl/HidlTransportSupport.h> + +#include "AuthSecret.h" + +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; +using android::hardware::authsecret::V1_0::IAuthSecret; +using android::hardware::authsecret::V1_0::implementation::AuthSecret; +using android::sp; +using android::status_t; +using android::OK; + +int main() { + configureRpcThreadpool(1, true); + + sp<IAuthSecret> authSecret = new AuthSecret; + status_t status = authSecret->registerAsService(); + LOG_ALWAYS_FATAL_IF(status != OK, "Could not register IAuthSecret"); + + joinRpcThreadpool(); + return 0; +} diff --git a/authsecret/1.0/vts/functional/Android.bp b/authsecret/1.0/vts/functional/Android.bp new file mode 100644 index 000000000..de9f560ec --- /dev/null +++ b/authsecret/1.0/vts/functional/Android.bp @@ -0,0 +1,22 @@ +// +// Copyright (C) 2018 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. +// + +cc_test { + name: "VtsHalAuthSecretV1_0TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: ["VtsHalAuthSecretV1_0TargetTest.cpp"], + static_libs: ["android.hardware.authsecret@1.0"], +} diff --git a/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp b/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp new file mode 100644 index 000000000..b0cbd9129 --- /dev/null +++ b/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2018 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/authsecret/1.0/IAuthSecret.h> + +#include <VtsHalHidlTargetTestBase.h> + +using ::android::hardware::hidl_vec; +using ::android::hardware::authsecret::V1_0::IAuthSecret; +using ::android::sp; + +/** + * There is no expected behaviour that can be tested so these tests check the + * HAL doesn't crash with different execution orders. + */ +struct AuthSecretHidlTest : public ::testing::VtsHalHidlTargetTestBase { + virtual void SetUp() override { + authsecret = ::testing::VtsHalHidlTargetTestBase::getService<IAuthSecret>(); + ASSERT_NE(authsecret, nullptr); + authsecret->factoryReset(); + } + + sp<IAuthSecret> authsecret; +}; + +/* Provision the primary user with a secret. */ +TEST_F(AuthSecretHidlTest, provisionPrimaryUserCredential) { + hidl_vec<uint8_t> secret{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + authsecret->primaryUserCredential(secret); +} + +/* Provision the primary user with a large secret. */ +TEST_F(AuthSecretHidlTest, provisionPrimaryUserCredentialWithLargeSecret) { + hidl_vec<uint8_t> secret{89, 233, 52, 29, 130, 210, 229, 170, 124, 102, 56, 238, 198, + 199, 246, 152, 185, 123, 155, 215, 29, 252, 30, 70, 118, 29, + 149, 36, 222, 203, 163, 7, 72, 56, 247, 19, 198, 76, 71, + 37, 120, 201, 220, 70, 150, 18, 23, 22, 236, 57, 184, 86, + 190, 122, 210, 207, 74, 51, 222, 157, 74, 196, 86, 208}; + authsecret->primaryUserCredential(secret); +} + +/* Provision the primary user with a secret and pass the secret again. */ +TEST_F(AuthSecretHidlTest, provisionPrimaryUserCredentialAndPassAgain) { + hidl_vec<uint8_t> secret{64, 2, 3, 0, 5, 6, 7, 172, 9, 10, 11, 255, 13, 14, 15, 83}; + authsecret->primaryUserCredential(secret); + authsecret->primaryUserCredential(secret); +} + +/* Provision the primary user with a secret and pass the secret again repeatedly. */ +TEST_F(AuthSecretHidlTest, provisionPrimaryUserCredentialAndPassAgainMultipleTimes) { + hidl_vec<uint8_t> secret{1, 2, 34, 4, 5, 6, 7, 8, 9, 105, 11, 12, 13, 184, 15, 16}; + authsecret->primaryUserCredential(secret); + constexpr int N = 5; + for (int i = 0; i < N; ++i) { + authsecret->primaryUserCredential(secret); + } +} + +/* Factory reset before provisioning the primary user with a secret. */ +TEST_F(AuthSecretHidlTest, factoryResetWithoutProvisioningPrimaryUserCredential) { + authsecret->factoryReset(); +} + +/* Provision the primary user with a secret then factory reset. */ +TEST_F(AuthSecretHidlTest, provisionPrimaryUserCredentialAndFactoryReset) { + hidl_vec<uint8_t> secret{1, 24, 124, 240, 5, 6, 7, 8, 9, 13, 11, 12, 189, 14, 195, 16}; + authsecret->primaryUserCredential(secret); + authsecret->factoryReset(); +} + +/* Provision the primary differently after factory reset. */ +TEST_F(AuthSecretHidlTest, provisionPrimaryUserCredentialDifferentlyAfterFactoryReset) { + { + hidl_vec<uint8_t> secret1{19, 0, 65, 20, 65, 12, 7, 8, 9, 13, 29, 12, 189, 32, 195, 16}; + authsecret->primaryUserCredential(secret1); + } + + authsecret->factoryReset(); + + { + hidl_vec<uint8_t> secret2{61, 93, 124, 240, 5, 0, 7, 201, 9, 129, 11, 12, 0, 14, 0, 16}; + authsecret->primaryUserCredential(secret2); + } +} |