Created libattestation
Move attestation logic from input into separate library. This way Input
and SurfaceFlinger can leverage the same logic
Test: inputflinger_test
Test: attestation_tests
Bug: 155825630
Change-Id: Ia4f65166da8a1c53a9570db59eab602190438696
diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp
index a0de607..96e6207 100644
--- a/services/inputflinger/Android.bp
+++ b/services/inputflinger/Android.bp
@@ -59,6 +59,9 @@
"libutils",
"libui",
],
+ static_libs: [
+ "libattestation",
+ ],
}
cc_library_shared {
diff --git a/services/inputflinger/benchmarks/Android.bp b/services/inputflinger/benchmarks/Android.bp
index 066a816..9abf8b1 100644
--- a/services/inputflinger/benchmarks/Android.bp
+++ b/services/inputflinger/benchmarks/Android.bp
@@ -18,6 +18,7 @@
"libutils",
],
static_libs: [
+ "libattestation",
"libinputdispatcher",
],
}
diff --git a/services/inputflinger/dispatcher/Android.bp b/services/inputflinger/dispatcher/Android.bp
index d29d8df..ff9aac9 100644
--- a/services/inputflinger/dispatcher/Android.bp
+++ b/services/inputflinger/dispatcher/Android.bp
@@ -48,6 +48,9 @@
"libui",
"libutils",
],
+ static_libs: [
+ "libattestation",
+ ],
header_libs: [
"libinputdispatcher_headers",
],
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 078448f..0980107 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -53,8 +53,6 @@
#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 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)
@@ -2692,6 +2643,22 @@
}
}
+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;
@@ -2701,7 +2668,7 @@
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;
}
@@ -2711,7 +2678,7 @@
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,
@@ -3559,7 +3526,7 @@
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: {
@@ -3567,7 +3534,7 @@
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 8988714..e452ca2 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 @@
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 @@
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 da50af5..3e0b5e8 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -294,70 +294,6 @@
}
};
-// --- 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 @@
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