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

Commit bb6377e6 authored by Janis Danisevskis's avatar Janis Danisevskis
Browse files

Some changes required for the actual integration with a GUI renderer

These changes accumulated during the integration with the Pixel specific
impelemtation. The make it easiser to integrate an GUI renderer with the
core logic.

Bug: 63928580
Test: VTS tests and manual tests
Change-Id: I7001f60709ce806a16f098492bdb71eb05e6ca9a
parent a1dc57b6
Loading
Loading
Loading
Loading
+6 −1
Original line number Original line Diff line number Diff line
@@ -43,7 +43,12 @@ Return<ResponseCode> ConfirmationUI::promptUserConfirmation(
    const hidl_vec<uint8_t>& extraData, const hidl_string& locale,
    const hidl_vec<uint8_t>& extraData, const hidl_string& locale,
    const hidl_vec<UIOption>& uiOptions) {
    const hidl_vec<UIOption>& uiOptions) {
    auto& operation = MyOperation::get();
    auto& operation = MyOperation::get();
    return operation.init(resultCB, promptText, extraData, locale, uiOptions);
    auto result = operation.init(resultCB, promptText, extraData, locale, uiOptions);
    if (result == ResponseCode::OK) {
        // This is where implementation start the UI and then call setPending on success.
        operation.setPending();
    }
    return result;
}
}


Return<ResponseCode> ConfirmationUI::deliverSecureInputEvent(
Return<ResponseCode> ConfirmationUI::deliverSecureInputEvent(
+8 −2
Original line number Original line Diff line number Diff line
@@ -52,8 +52,14 @@ class HMacImplementation {
        const uint8_t key[32], std::initializer_list<support::ByteBufferProxy> buffers);
        const uint8_t key[32], std::initializer_list<support::ByteBufferProxy> buffers);
};
};


using MyOperation = generic::Operation<sp<IConfirmationResultCallback>, MonotonicClockTimeStamper,
class MyOperation : public generic::Operation<sp<IConfirmationResultCallback>,
                                       HMacImplementation>;
                                              MonotonicClockTimeStamper, HMacImplementation> {
   public:
    static MyOperation& get() {
        static MyOperation op;
        return op;
    }
};


}  // namespace implementation
}  // namespace implementation
}  // namespace V1_0
}  // namespace V1_0
+31 −15
Original line number Original line Diff line number Diff line
@@ -55,10 +55,27 @@ class Operation {
        (void)uiOptions;
        (void)uiOptions;
        resultCB_ = resultCB;
        resultCB_ = resultCB;
        if (error_ != ResponseCode::Ignored) return ResponseCode::OperationPending;
        if (error_ != ResponseCode::Ignored) return ResponseCode::OperationPending;
        // TODO make copy of promptText before using it may reside in shared buffer

        auto state = write(
        // We need to access the prompt text multiple times. Once for formatting the CBOR message
            WriteState(formattedMessageBuffer_),
        // and again for rendering the dialog. It is vital that the prompt does not change
            map(pair(text("prompt"), text(promptText)), pair(text("extra"), bytes(extraData))));
        // in the meantime. As of this point the prompt text is in a shared buffer and therefore
        // susceptible to TOCTOU attacks. Note that promptText.size() resides on the stack and
        // is safe to access multiple times. So now we copy the prompt string into the
        // scratchpad promptStringBuffer_ from where we can format the CBOR message and then
        // pass it to the renderer.
        if (promptText.size() >= uint32_t(MessageSize::MAX))
            return ResponseCode::UIErrorMessageTooLong;
        auto pos = std::copy(promptText.c_str(), promptText.c_str() + promptText.size(),
                             promptStringBuffer_);
        *pos = 0;  // null-terminate the prompt for the renderer.

        // Note the extra data is accessed only once for formating the CBOR message. So it is safe
        // to read it from the shared buffer directly. Anyway we don't trust or interpret the
        // extra data in any way so all we do is take a snapshot and we don't care if it is
        // modified concurrently.
        auto state = write(WriteState(formattedMessageBuffer_),
                           map(pair(text("prompt"), text(promptStringBuffer_, promptText.size())),
                               pair(text("extra"), bytes(extraData))));
        switch (state.error_) {
        switch (state.error_) {
            case Error::OK:
            case Error::OK:
                break;
                break;
@@ -71,20 +88,20 @@ class Operation {
                return ResponseCode::Unexpected;
                return ResponseCode::Unexpected;
        }
        }
        formattedMessageLength_ = state.data_ - formattedMessageBuffer_;
        formattedMessageLength_ = state.data_ - formattedMessageBuffer_;
        // setup TUI and diagnose more UI errors here.

        // on success record the start time
        // on success record the start time
        startTime_ = TimeStamper::now();
        startTime_ = TimeStamper::now();
        if (!startTime_.isOk()) {
        if (!startTime_.isOk()) {
            return ResponseCode::SystemError;
            return ResponseCode::SystemError;
        }
        }
        error_ = ResponseCode::OK;
        return ResponseCode::OK;
        return ResponseCode::OK;
    }
    }


    void setPending() { error_ = ResponseCode::OK; }

    void setHmacKey(const uint8_t (&key)[32]) { hmacKey_ = {key}; }
    void setHmacKey(const uint8_t (&key)[32]) { hmacKey_ = {key}; }


    void abort() {
    void abort() {
        // tear down TUI here
        if (isPending()) {
        if (isPending()) {
            resultCB_->result(ResponseCode::Aborted, {}, {});
            resultCB_->result(ResponseCode::Aborted, {}, {});
            error_ = ResponseCode::Ignored;
            error_ = ResponseCode::Ignored;
@@ -92,7 +109,6 @@ class Operation {
    }
    }


    void userCancel() {
    void userCancel() {
        // tear down TUI here
        if (isPending()) error_ = ResponseCode::Canceled;
        if (isPending()) error_ = ResponseCode::Canceled;
    }
    }


@@ -104,10 +120,10 @@ class Operation {
    }
    }


    bool isPending() const { return error_ != ResponseCode::Ignored; }
    bool isPending() const { return error_ != ResponseCode::Ignored; }

    const hidl_string getPrompt() const {
    static Operation& get() {
        hidl_string s;
        static Operation operation;
        s.setToExternal(promptStringBuffer_, strlen(promptStringBuffer_));
        return operation;
        return s;
    }
    }


    ResponseCode deliverSecureInputEvent(const HardwareAuthToken& secureInputToken) {
    ResponseCode deliverSecureInputEvent(const HardwareAuthToken& secureInputToken) {
@@ -156,7 +172,6 @@ class Operation {
        return result;
        return result;
    }
    }
    hidl_vec<uint8_t> userConfirm(const uint8_t key[32]) {
    hidl_vec<uint8_t> userConfirm(const uint8_t key[32]) {
        // tear down TUI here
        if (error_ != ResponseCode::OK) return {};
        if (error_ != ResponseCode::OK) return {};
        confirmationTokenScratchpad_ = HMacer::hmac256(key, "confirmation token", getMessage());
        confirmationTokenScratchpad_ = HMacer::hmac256(key, "confirmation token", getMessage());
        if (!confirmationTokenScratchpad_.isOk()) {
        if (!confirmationTokenScratchpad_.isOk()) {
@@ -169,9 +184,10 @@ class Operation {
        return result;
        return result;
    }
    }


    ResponseCode error_;
    ResponseCode error_ = ResponseCode::Ignored;
    uint8_t formattedMessageBuffer_[uint32_t(MessageSize::MAX)];
    uint8_t formattedMessageBuffer_[uint32_t(MessageSize::MAX)];
    size_t formattedMessageLength_;
    char promptStringBuffer_[uint32_t(MessageSize::MAX)];
    size_t formattedMessageLength_ = 0;
    NullOr<array<uint8_t, 32>> confirmationTokenScratchpad_;
    NullOr<array<uint8_t, 32>> confirmationTokenScratchpad_;
    Callback resultCB_;
    Callback resultCB_;
    typename TimeStamper::TimeStamp startTime_;
    typename TimeStamper::TimeStamp startTime_;