Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9087896 authored by Gang Wang's avatar Gang Wang Committed by Siarhei Vishniakou
Browse files

Use hmac to sign events in InputDispatcher

InputDispatcher will now be able to sign events. Add two static methods
to InputDispatcher class, for signing events, and for checking the event
signature.

The new methods can verify whether a MotionEntry object was actually created by
the Input system and whether the MotionEntry object was modified
afterwards.

Bug: 134977432
Test: none

Change-Id: Ica11bccd0c3fb065b02634bd236ae5a46f6b19ee
parent edd6bc95
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ cc_benchmark {
    shared_libs: [
        "libbase",
        "libbinder",
        "libcrypto",
        "libcutils",
        "libinput",
        "libinputflinger_base",
+26 −0
Original line number Diff line number Diff line
@@ -57,6 +57,32 @@ static std::string keyActionToString(int32_t action) {
    }
    return StringPrintf("%" PRId32, action);
}
VerifiedKeyEvent verifiedKeyEventFromKeyEntry(const KeyEntry& entry) {
    return {{VerifiedInputEvent::Type::KEY, entry.deviceId, entry.eventTime, entry.source,
             entry.displayId},
            entry.action,
            entry.downTime,
            entry.flags & VERIFIED_KEY_EVENT_FLAGS,
            entry.keyCode,
            entry.scanCode,
            entry.metaState,
            entry.repeatCount};
}

VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry) {
    const float rawX = entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X);
    const float rawY = entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y);
    const int actionMasked = entry.action & AMOTION_EVENT_ACTION_MASK;
    return {{VerifiedInputEvent::Type::MOTION, entry.deviceId, entry.eventTime, entry.source,
             entry.displayId},
            rawX,
            rawY,
            actionMasked,
            entry.downTime,
            entry.flags & VERIFIED_MOTION_EVENT_FLAGS,
            entry.metaState,
            entry.buttonState};
}

// --- EventEntry ---

+3 −0
Original line number Diff line number Diff line
@@ -220,6 +220,9 @@ private:
    static uint32_t nextSeq();
};

VerifiedKeyEvent verifiedKeyEventFromKeyEntry(const KeyEntry& entry);
VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry);

class InputDispatcher;
// A command entry captures state and behavior for an action to be performed in the
// dispatch loop after the initial processing has taken place.  It is essentially
+42 −3
Original line number Diff line number Diff line
@@ -2433,12 +2433,16 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
        switch (eventEntry->type) {
            case EventEntry::Type::KEY: {
                KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
                VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(*keyEntry);
                verifiedEvent.flags = dispatchEntry->resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
                verifiedEvent.action = dispatchEntry->resolvedAction;
                std::array<uint8_t, 32> hmac = mHmacKeyManager.sign(verifiedEvent);

                // Publish the key event.
                status = connection->inputPublisher
                                 .publishKeyEvent(dispatchEntry->seq, keyEntry->deviceId,
                                                  keyEntry->source, keyEntry->displayId,
                                                  INVALID_HMAC, dispatchEntry->resolvedAction,
                                                  std::move(hmac), dispatchEntry->resolvedAction,
                                                  dispatchEntry->resolvedFlags, keyEntry->keyCode,
                                                  keyEntry->scanCode, keyEntry->metaState,
                                                  keyEntry->repeatCount, keyEntry->downTime,
@@ -2482,12 +2486,18 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
                        usingCoords = scaledCoords;
                    }
                }
                VerifiedMotionEvent verifiedEvent =
                        verifiedMotionEventFromMotionEntry(*motionEntry);
                verifiedEvent.actionMasked =
                        dispatchEntry->resolvedAction & AMOTION_EVENT_ACTION_MASK;
                verifiedEvent.flags = dispatchEntry->resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
                std::array<uint8_t, 32> hmac = mHmacKeyManager.sign(verifiedEvent);

                // Publish the motion event.
                status = connection->inputPublisher
                                 .publishMotionEvent(dispatchEntry->seq, motionEntry->deviceId,
                                                     motionEntry->source, motionEntry->displayId,
                                                     INVALID_HMAC, dispatchEntry->resolvedAction,
                                                     std::move(hmac), dispatchEntry->resolvedAction,
                                                     motionEntry->actionButton,
                                                     dispatchEntry->resolvedFlags,
                                                     motionEntry->edgeFlags, motionEntry->metaState,
@@ -3392,8 +3402,37 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injec
}

std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
    std::array<uint8_t, 32> calculatedHmac;
    std::unique_ptr<VerifiedInputEvent> result;
    switch (event.getType()) {
        case AINPUT_EVENT_TYPE_KEY: {
            const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
            VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
            result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
            calculatedHmac = mHmacKeyManager.sign(verifiedKeyEvent);
            break;
        }
        case AINPUT_EVENT_TYPE_MOTION: {
            const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
            VerifiedMotionEvent verifiedMotionEvent =
                    verifiedMotionEventFromMotionEvent(motionEvent);
            result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
            calculatedHmac = mHmacKeyManager.sign(verifiedMotionEvent);
            break;
        }
        default: {
            ALOGE("Cannot verify events of type %" PRId32, event.getType());
            return nullptr;
        }
    }
    if (calculatedHmac == INVALID_HMAC) {
        return nullptr;
    }
    if (calculatedHmac != event.getHmac()) {
        return nullptr;
    }
    return result;
}

bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
    return injectorUid == 0 ||
+2 −0
Original line number Diff line number Diff line
@@ -217,6 +217,8 @@ private:
    // the pointer stream in order to claim it for a system gesture.
    std::unordered_map<int32_t, std::vector<Monitor>> mGestureMonitorsByDisplay GUARDED_BY(mLock);

    HmacKeyManager mHmacKeyManager;

    // Event injection and synchronization.
    std::condition_variable mInjectionResultAvailable;
    bool hasInjectionPermission(int32_t injectorPid, int32_t injectorUid);
Loading