diff options
-rw-r--r-- | include/attestation/HmacKeyManager.h | 32 | ||||
-rw-r--r-- | include/input/Input.h | 5 | ||||
-rw-r--r-- | libs/attestation/Android.bp | 31 | ||||
-rw-r--r-- | libs/attestation/HmacKeyManager.cpp | 52 | ||||
-rw-r--r-- | libs/attestation/OWNERS | 2 | ||||
-rw-r--r-- | libs/attestation/TEST_MAPPING | 7 | ||||
-rw-r--r-- | libs/attestation/tests/Android.bp | 28 | ||||
-rw-r--r-- | libs/attestation/tests/HmacKeyManager_test.cpp | 52 | ||||
-rw-r--r-- | libs/input/Input.cpp | 1 | ||||
-rw-r--r-- | libs/input/KeyCharacterMap.cpp | 3 | ||||
-rw-r--r-- | libs/input/tests/InputEvent_test.cpp | 1 | ||||
-rw-r--r-- | libs/input/tests/InputPublisherAndConsumer_test.cpp | 3 | ||||
-rw-r--r-- | libs/input/tests/VelocityTracker_test.cpp | 1 | ||||
-rw-r--r-- | libs/input/tests/VerifiedInputEvent_test.cpp | 1 | ||||
-rw-r--r-- | services/inputflinger/Android.bp | 3 | ||||
-rw-r--r-- | services/inputflinger/benchmarks/Android.bp | 1 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/Android.bp | 3 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 73 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.h | 13 | ||||
-rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 121 |
20 files changed, 299 insertions, 134 deletions
diff --git a/include/attestation/HmacKeyManager.h b/include/attestation/HmacKeyManager.h new file mode 100644 index 0000000000..571a361889 --- /dev/null +++ b/include/attestation/HmacKeyManager.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 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 <array> + +namespace android { +/** + * Invalid value of HMAC - SHA256. Any events with this HMAC value will be marked as not verified. + */ +constexpr std::array<uint8_t, 32> INVALID_HMAC = {0}; + +class HmacKeyManager { +public: + HmacKeyManager(); + std::array<uint8_t, 32> sign(const uint8_t* data, size_t size) const; +private: + const std::array<uint8_t, 128> mHmacKey; +}; +} // namespace android
\ No newline at end of file diff --git a/include/input/Input.h b/include/input/Input.h index d40ba439db..7b66d3cac8 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -312,11 +312,6 @@ private: */ constexpr float AMOTION_EVENT_INVALID_CURSOR_POSITION = std::numeric_limits<float>::quiet_NaN(); -/** - * Invalid value of HMAC - SHA256. Any events with this HMAC value will be marked as not verified. - */ -constexpr std::array<uint8_t, 32> INVALID_HMAC = {0}; - /* * Pointer coordinate data. */ diff --git a/libs/attestation/Android.bp b/libs/attestation/Android.bp new file mode 100644 index 0000000000..b85aecd16d --- /dev/null +++ b/libs/attestation/Android.bp @@ -0,0 +1,31 @@ +// Copyright (C) 2020 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_library_static { + name: "libattestation", + cflags: [ + "-Wall", + "-Wextra", + "-Werror", + ], + srcs: [ + "HmacKeyManager.cpp" + ], + + clang: true, + + shared_libs: [ + "liblog", + "libcrypto", + ], +}
\ No newline at end of file diff --git a/libs/attestation/HmacKeyManager.cpp b/libs/attestation/HmacKeyManager.cpp new file mode 100644 index 0000000000..b15f143014 --- /dev/null +++ b/libs/attestation/HmacKeyManager.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 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 <attestation/HmacKeyManager.h> +#include <log/log.h> +#include <openssl/hmac.h> +#include <openssl/rand.h> + +namespace android { + +static std::array<uint8_t, 128> getRandomKey() { + std::array<uint8_t, 128> key; + if (RAND_bytes(key.data(), key.size()) != 1) { + LOG_ALWAYS_FATAL("Can't generate HMAC key"); + } + return key; +} + +HmacKeyManager::HmacKeyManager() : mHmacKey(getRandomKey()) {} + +std::array<uint8_t, 32> HmacKeyManager::sign(const uint8_t* data, size_t size) const { + // SHA256 always generates 32-bytes result + std::array<uint8_t, 32> hash; + unsigned int hashLen = 0; + uint8_t* result = + HMAC(EVP_sha256(), mHmacKey.data(), mHmacKey.size(), data, size, hash.data(), &hashLen); + if (result == nullptr) { + ALOGE("Could not sign the data using HMAC"); + return INVALID_HMAC; + } + + if (hashLen != hash.size()) { + ALOGE("HMAC-SHA256 has unexpected length"); + return INVALID_HMAC; + } + + return hash; +} +} // namespace android
\ No newline at end of file diff --git a/libs/attestation/OWNERS b/libs/attestation/OWNERS new file mode 100644 index 0000000000..4dbb0eae5c --- /dev/null +++ b/libs/attestation/OWNERS @@ -0,0 +1,2 @@ +chaviw@google.com +svv@google.com
\ No newline at end of file diff --git a/libs/attestation/TEST_MAPPING b/libs/attestation/TEST_MAPPING new file mode 100644 index 0000000000..43be638d91 --- /dev/null +++ b/libs/attestation/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "libattestation_tests" + } + ] +}
\ No newline at end of file diff --git a/libs/attestation/tests/Android.bp b/libs/attestation/tests/Android.bp new file mode 100644 index 0000000000..6ce5ea1b2d --- /dev/null +++ b/libs/attestation/tests/Android.bp @@ -0,0 +1,28 @@ +// Copyright (C) 2020 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: "libattestation_tests", + test_suites: ["device-tests"], + srcs: [ + "HmacKeyManager_test.cpp", + ], + static_libs: [ + "libattestation", + ], + shared_libs: [ + "liblog", + "libcrypto", + ], +} diff --git a/libs/attestation/tests/HmacKeyManager_test.cpp b/libs/attestation/tests/HmacKeyManager_test.cpp new file mode 100644 index 0000000000..7f7a408886 --- /dev/null +++ b/libs/attestation/tests/HmacKeyManager_test.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 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 <attestation/HmacKeyManager.h> +#include <gtest/gtest.h> + +namespace android { + +class HmacKeyManagerTest : public testing::Test { +protected: + HmacKeyManager mHmacKeyManager; +}; + +/** + * Ensure that separate calls to sign the same data are generating the same key. + * We avoid asserting against INVALID_HMAC. Since the key is random, there is a non-zero chance + * that a specific key and data combination would produce INVALID_HMAC, which would cause flaky + * tests. + */ +TEST_F(HmacKeyManagerTest, GeneratedHmac_IsConsistent) { + std::array<uint8_t, 10> data = {4, 3, 5, 1, 8, 5, 2, 7, 1, 8}; + + std::array<uint8_t, 32> hmac1 = mHmacKeyManager.sign(data.data(), sizeof(data)); + std::array<uint8_t, 32> hmac2 = mHmacKeyManager.sign(data.data(), sizeof(data)); + ASSERT_EQ(hmac1, hmac2); +} + +/** + * Ensure that changes in the hmac verification data produce a different hmac. + */ +TEST_F(HmacKeyManagerTest, GeneratedHmac_ChangesWhenFieldsChange) { + std::array<uint8_t, 10> data = {4, 3, 5, 1, 8, 5, 2, 7, 1, 8}; + std::array<uint8_t, 32> initialHmac = mHmacKeyManager.sign(data.data(), sizeof(data)); + + data[2] = 2; + ASSERT_NE(initialHmac, mHmacKeyManager.sign(data.data(), sizeof(data))); +} + +} // namespace android
\ No newline at end of file diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp index 51910fe6f9..692c65dc46 100644 --- a/libs/input/Input.cpp +++ b/libs/input/Input.cpp @@ -17,6 +17,7 @@ #define LOG_TAG "Input" //#define LOG_NDEBUG 0 +#include <attestation/HmacKeyManager.h> #include <cutils/compiler.h> #include <limits.h> #include <string.h> diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp index fd35131b6b..7ac8a2e02c 100644 --- a/libs/input/KeyCharacterMap.cpp +++ b/libs/input/KeyCharacterMap.cpp @@ -24,9 +24,10 @@ #endif #include <android/keycodes.h> +#include <attestation/HmacKeyManager.h> #include <input/InputEventLabels.h> -#include <input/Keyboard.h> #include <input/KeyCharacterMap.h> +#include <input/Keyboard.h> #include <utils/Log.h> #include <utils/Errors.h> diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp index 069bc0eb4e..601d8dabf7 100644 --- a/libs/input/tests/InputEvent_test.cpp +++ b/libs/input/tests/InputEvent_test.cpp @@ -17,6 +17,7 @@ #include <array> #include <math.h> +#include <attestation/HmacKeyManager.h> #include <binder/Parcel.h> #include <gtest/gtest.h> #include <input/Input.h> diff --git a/libs/input/tests/InputPublisherAndConsumer_test.cpp b/libs/input/tests/InputPublisherAndConsumer_test.cpp index e1f2562129..1452745d01 100644 --- a/libs/input/tests/InputPublisherAndConsumer_test.cpp +++ b/libs/input/tests/InputPublisherAndConsumer_test.cpp @@ -20,11 +20,12 @@ #include <sys/mman.h> #include <time.h> +#include <attestation/HmacKeyManager.h> #include <cutils/ashmem.h> #include <gtest/gtest.h> #include <input/InputTransport.h> -#include <utils/Timers.h> #include <utils/StopWatch.h> +#include <utils/Timers.h> namespace android { diff --git a/libs/input/tests/VelocityTracker_test.cpp b/libs/input/tests/VelocityTracker_test.cpp index e7db4b06a4..d049d05ac5 100644 --- a/libs/input/tests/VelocityTracker_test.cpp +++ b/libs/input/tests/VelocityTracker_test.cpp @@ -21,6 +21,7 @@ #include <math.h> #include <android-base/stringprintf.h> +#include <attestation/HmacKeyManager.h> #include <gtest/gtest.h> #include <input/VelocityTracker.h> diff --git a/libs/input/tests/VerifiedInputEvent_test.cpp b/libs/input/tests/VerifiedInputEvent_test.cpp index 21cfe8c36e..36f87b8a6a 100644 --- a/libs/input/tests/VerifiedInputEvent_test.cpp +++ b/libs/input/tests/VerifiedInputEvent_test.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include <attestation/HmacKeyManager.h> #include <gtest/gtest.h> #include <input/Input.h> diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp index a0de607864..96e62079c6 100644 --- a/services/inputflinger/Android.bp +++ b/services/inputflinger/Android.bp @@ -59,6 +59,9 @@ cc_defaults { "libutils", "libui", ], + static_libs: [ + "libattestation", + ], } cc_library_shared { diff --git a/services/inputflinger/benchmarks/Android.bp b/services/inputflinger/benchmarks/Android.bp index 066a816069..9abf8b179f 100644 --- a/services/inputflinger/benchmarks/Android.bp +++ b/services/inputflinger/benchmarks/Android.bp @@ -18,6 +18,7 @@ cc_benchmark { "libutils", ], static_libs: [ + "libattestation", "libinputdispatcher", ], } diff --git a/services/inputflinger/dispatcher/Android.bp b/services/inputflinger/dispatcher/Android.bp index d29d8dfda3..ff9aac9961 100644 --- a/services/inputflinger/dispatcher/Android.bp +++ b/services/inputflinger/dispatcher/Android.bp @@ -48,6 +48,9 @@ cc_defaults { "libui", "libutils", ], + static_libs: [ + "libattestation", + ], header_libs: [ "libinputdispatcher_headers", ], diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 9c8481c99f..b428c4ec1f 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -53,8 +53,6 @@ static constexpr bool DEBUG_FOCUS = false; #include <input/InputWindow.h> #include <log/log.h> #include <log/log_event_list.h> -#include <openssl/hmac.h> -#include <openssl/rand.h> #include <powermanager/PowerManager.h> #include <statslog.h> #include <unistd.h> @@ -344,53 +342,6 @@ static void addGestureMonitors(const std::vector<Monitor>& monitors, } } -static std::array<uint8_t, 128> getRandomKey() { - std::array<uint8_t, 128> key; - if (RAND_bytes(key.data(), key.size()) != 1) { - LOG_ALWAYS_FATAL("Can't generate HMAC key"); - } - return key; -} - -// --- HmacKeyManager --- - -HmacKeyManager::HmacKeyManager() : mHmacKey(getRandomKey()) {} - -std::array<uint8_t, 32> HmacKeyManager::sign(const VerifiedInputEvent& event) const { - size_t size; - switch (event.type) { - case VerifiedInputEvent::Type::KEY: { - size = sizeof(VerifiedKeyEvent); - break; - } - case VerifiedInputEvent::Type::MOTION: { - size = sizeof(VerifiedMotionEvent); - break; - } - } - const uint8_t* start = reinterpret_cast<const uint8_t*>(&event); - return sign(start, size); -} - -std::array<uint8_t, 32> HmacKeyManager::sign(const uint8_t* data, size_t size) const { - // SHA256 always generates 32-bytes result - std::array<uint8_t, 32> hash; - unsigned int hashLen = 0; - uint8_t* result = - HMAC(EVP_sha256(), mHmacKey.data(), mHmacKey.size(), data, size, hash.data(), &hashLen); - if (result == nullptr) { - ALOGE("Could not sign the data using HMAC"); - return INVALID_HMAC; - } - - if (hashLen != hash.size()) { - ALOGE("HMAC-SHA256 has unexpected length"); - return INVALID_HMAC; - } - - return hash; -} - // --- InputDispatcher --- InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) @@ -2682,6 +2633,22 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, } } +std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const { + size_t size; + switch (event.type) { + case VerifiedInputEvent::Type::KEY: { + size = sizeof(VerifiedKeyEvent); + break; + } + case VerifiedInputEvent::Type::MOTION: { + size = sizeof(VerifiedMotionEvent); + break; + } + } + const uint8_t* start = reinterpret_cast<const uint8_t*>(&event); + return mHmacKeyManager.sign(start, size); +} + const std::array<uint8_t, 32> InputDispatcher::getSignature( const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const { int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK; @@ -2691,7 +2658,7 @@ const std::array<uint8_t, 32> InputDispatcher::getSignature( VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry); verifiedEvent.actionMasked = actionMasked; verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS; - return mHmacKeyManager.sign(verifiedEvent); + return sign(verifiedEvent); } return INVALID_HMAC; } @@ -2701,7 +2668,7 @@ const std::array<uint8_t, 32> InputDispatcher::getSignature( VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry); verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS; verifiedEvent.action = dispatchEntry.resolvedAction; - return mHmacKeyManager.sign(verifiedEvent); + return sign(verifiedEvent); } void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime, @@ -3549,7 +3516,7 @@ std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const Inpu const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event); VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent); result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent); - calculatedHmac = mHmacKeyManager.sign(verifiedKeyEvent); + calculatedHmac = sign(verifiedKeyEvent); break; } case AINPUT_EVENT_TYPE_MOTION: { @@ -3557,7 +3524,7 @@ std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const Inpu VerifiedMotionEvent verifiedMotionEvent = verifiedMotionEventFromMotionEvent(motionEvent); result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent); - calculatedHmac = mHmacKeyManager.sign(verifiedMotionEvent); + calculatedHmac = sign(verifiedMotionEvent); break; } default: { diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h index c52d256dc3..93d3fdefd8 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.h +++ b/services/inputflinger/dispatcher/InputDispatcher.h @@ -31,6 +31,7 @@ #include "TouchState.h" #include "TouchedWindow.h" +#include <attestation/HmacKeyManager.h> #include <input/Input.h> #include <input/InputApplication.h> #include <input/InputTransport.h> @@ -58,16 +59,6 @@ namespace android::inputdispatcher { class Connection; -class HmacKeyManager { -public: - HmacKeyManager(); - std::array<uint8_t, 32> sign(const VerifiedInputEvent& event) const; - -private: - std::array<uint8_t, 32> sign(const uint8_t* data, size_t size) const; - const std::array<uint8_t, 128> mHmacKey; -}; - /* Dispatches events to input targets. Some functions of the input dispatcher, such as * identifying input targets, are controlled by a separate policy object. * @@ -133,6 +124,8 @@ public: virtual status_t unregisterInputChannel(const InputChannel& inputChannel) override; virtual status_t pilferPointers(const sp<IBinder>& token) override; + std::array<uint8_t, 32> sign(const VerifiedInputEvent& event) const; + private: enum class DropReason { NOT_DROPPED, diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index da50af5c5f..3e0b5e867d 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -294,70 +294,6 @@ private: } }; -// --- HmacKeyManagerTest --- - -class HmacKeyManagerTest : public testing::Test { -protected: - HmacKeyManager mHmacKeyManager; -}; - -/** - * Ensure that separate calls to sign the same data are generating the same key. - * We avoid asserting against INVALID_HMAC. Since the key is random, there is a non-zero chance - * that a specific key and data combination would produce INVALID_HMAC, which would cause flaky - * tests. - */ -TEST_F(HmacKeyManagerTest, GeneratedHmac_IsConsistent) { - KeyEvent event = getTestKeyEvent(); - VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event); - - std::array<uint8_t, 32> hmac1 = mHmacKeyManager.sign(verifiedEvent); - std::array<uint8_t, 32> hmac2 = mHmacKeyManager.sign(verifiedEvent); - ASSERT_EQ(hmac1, hmac2); -} - -/** - * Ensure that changes in VerifiedKeyEvent produce a different hmac. - */ -TEST_F(HmacKeyManagerTest, GeneratedHmac_ChangesWhenFieldsChange) { - KeyEvent event = getTestKeyEvent(); - VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event); - std::array<uint8_t, 32> initialHmac = mHmacKeyManager.sign(verifiedEvent); - - verifiedEvent.deviceId += 1; - ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); - - verifiedEvent.source += 1; - ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); - - verifiedEvent.eventTimeNanos += 1; - ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); - - verifiedEvent.displayId += 1; - ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); - - verifiedEvent.action += 1; - ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); - - verifiedEvent.downTimeNanos += 1; - ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); - - verifiedEvent.flags += 1; - ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); - - verifiedEvent.keyCode += 1; - ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); - - verifiedEvent.scanCode += 1; - ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); - - verifiedEvent.metaState += 1; - ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); - - verifiedEvent.repeatCount += 1; - ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); -} - // --- InputDispatcherTest --- class InputDispatcherTest : public testing::Test { @@ -2027,6 +1963,63 @@ TEST_F(InputDispatcherTest, VerifyInputEvent_MotionEvent) { EXPECT_EQ(motionArgs.buttonState, verifiedMotion.buttonState); } +/** + * Ensure that separate calls to sign the same data are generating the same key. + * We avoid asserting against INVALID_HMAC. Since the key is random, there is a non-zero chance + * that a specific key and data combination would produce INVALID_HMAC, which would cause flaky + * tests. + */ +TEST_F(InputDispatcherTest, GeneratedHmac_IsConsistent) { + KeyEvent event = getTestKeyEvent(); + VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event); + + std::array<uint8_t, 32> hmac1 = mDispatcher->sign(verifiedEvent); + std::array<uint8_t, 32> hmac2 = mDispatcher->sign(verifiedEvent); + ASSERT_EQ(hmac1, hmac2); +} + +/** + * Ensure that changes in VerifiedKeyEvent produce a different hmac. + */ +TEST_F(InputDispatcherTest, GeneratedHmac_ChangesWhenFieldsChange) { + KeyEvent event = getTestKeyEvent(); + VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event); + std::array<uint8_t, 32> initialHmac = mDispatcher->sign(verifiedEvent); + + verifiedEvent.deviceId += 1; + ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent)); + + verifiedEvent.source += 1; + ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent)); + + verifiedEvent.eventTimeNanos += 1; + ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent)); + + verifiedEvent.displayId += 1; + ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent)); + + verifiedEvent.action += 1; + ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent)); + + verifiedEvent.downTimeNanos += 1; + ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent)); + + verifiedEvent.flags += 1; + ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent)); + + verifiedEvent.keyCode += 1; + ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent)); + + verifiedEvent.scanCode += 1; + ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent)); + + verifiedEvent.metaState += 1; + ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent)); + + verifiedEvent.repeatCount += 1; + ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent)); +} + class InputDispatcherKeyRepeatTest : public InputDispatcherTest { protected: static constexpr nsecs_t KEY_REPEAT_TIMEOUT = 40 * 1000000; // 40 ms |