Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/trusty/trusty/user/app/confirmationui/src/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 8 kB image not shown  

Quelle  main.cpp

  Sprache: C
 

/*
 * Copyright 2019 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.
 */


#define TLOG_TAG "confirmationui"

#ifdef WITH_HANDLE_PROT
#include <lib/handle_prot/handle_prot.h>
#endif
#include <lib/keymaster/keymaster.h>
#include <lib/tipc/tipc.h>
#include <lib/tipc/tipc_srv.h>
#include <lk/err_ptr.h>
#include <lk/macros.h>
#include <sys/mman.h>
#include <trusty_log.h>
#include <uapi/err.h>

#include <memory>

#include "ipc.h"
#include "trusty_operation.h"

struct chan_ctx {
    void* shm_base;
    size_t shm_len;
    std::unique_ptr<TrustyOperation> op;
};

static inline bool is_inited(struct chan_ctx* ctx) {
    return ctx->shm_base;
}

static bool get_auth_token_key(teeui::AuthTokenKey& authKey) {
    long rc = keymaster_open();
    bool result = false;

    if (rc < 0) {
        return false;
    }

    keymaster_session_t session = (keymaster_session_t)rc;
    uint8_t* key = nullptr;
    uint32_t local_length = 0;
    rc = keymaster_get_auth_token_key(session, &key, &local_length);
    keymaster_close(session);

    if (rc == NO_ERROR) {
        if (local_length == teeui::kAuthTokenKeySize) {
            /* Success  - store the key */
            memcpy(authKey.data(), key, teeui::kAuthTokenKeySize);
            result = true;
        }

        free(key);
    }

    return result;
}

struct __attribute__((__packed__)) confirmationui_req {
    struct confirmationui_hdr hdr;
    union {
        struct confirmationui_init_req init_args;
        struct confirmationui_msg_args msg_args;
    };
};

static int confirmationui_recv(handle_t chan,
                               confirmationui_req* req,
                               handle_t* h) {
    int rc;
    ipc_msg_info msg_info;
    uint32_t max_num_handles = h ? 1 : 0;
    struct iovec iov = {
            .iov_base = req,
            .iov_len = sizeof(*req),
    };
    struct ipc_msg ipc_msg = {
            .num_iov = 1,
            .iov = &iov,
            .num_handles = max_num_handles,
            .handles = h,
    };

    rc = get_msg(chan, &msg_info);
    if (rc != NO_ERROR) {
        TLOGE("Failed to get message (%d)\n", rc);
        return rc;
    }

    if (msg_info.len > sizeof(*req)) {
        TLOGE("Message is too long (%zd)\n", msg_info.len);
        rc = ERR_BAD_LEN;
        goto out;
    }

    if (msg_info.num_handles > max_num_handles) {
        TLOGE("Message has too many handles (%u)\n", msg_info.num_handles);
        rc = ERR_TOO_BIG;
        goto out;
    }

    rc = read_msg(chan, msg_info.id, 0, &ipc_msg);

out:
    put_msg(chan, msg_info.id);
    return rc;
}

static int handle_init(handle_t chan,
                       handle_t shm_handle,
                       uint32_t shm_len,
                       struct chan_ctx* ctx) {
    int rc;
    struct confirmationui_hdr hdr;

    if (is_inited(ctx)) {
        TLOGE("TA is already initialized.\n");
        return ERR_BAD_STATE;
    }

    if (shm_len > CONFIRMATIONUI_MAX_MSG_SIZE) {
        TLOGE("Shared memory too long\n");
        return ERR_BAD_LEN;
    }
#ifdef WITH_HANDLE_PROT
    rc = handle_prot_secure(shm_handle, false);
    if (rc < 0) {
        TLOGE("Shared memory should be non-secure, rc=%d\n", rc);
        return rc;
    }

    rc = handle_prot_prot_id(shm_handle, 0);
    if (rc < 0) {
        TLOGE("Shared memory prot Id invalid, rc=%d.\n", rc);
        return rc;
    }
#endif
    void* shm_base = mmap(0, shm_len, PROT_READ | PROT_WRITE, 0, shm_handle, 0);
    if (shm_base == MAP_FAILED) {
        TLOGE("Failed to mmap() handle\n");
        return ERR_BAD_HANDLE;
    }

    hdr.cmd = CONFIRMATIONUI_CMD_INIT | CONFIRMATIONUI_RESP_BIT;
    rc = tipc_send1(chan, &hdr, sizeof(hdr));
    if (rc != (int)sizeof(hdr)) {
        TLOGE("Failed to send response (%d)\n", rc);
        if (rc >= 0) {
            rc = ERR_BAD_LEN;
        }
        goto err;
    }

    ctx->shm_base = shm_base;
    ctx->shm_len = shm_len;
    return NO_ERROR;

err:
    int rc1 = munmap(shm_base, shm_len);
    if (rc1 != NO_ERROR) {
        TLOGW("munmap() failed: %d\n", rc1);
    }
    return rc;
}

static int handle_msg(handle_t chan, uint32_t req_len, struct chan_ctx* ctx) {
    int rc;
    uint8_t msg[CONFIRMATIONUI_MAX_MSG_SIZE];
    uint32_t resp_len = ctx->shm_len;
    struct confirmationui_hdr hdr;
    struct confirmationui_msg_args args;

    if (!is_inited(ctx)) {
        TLOGE("TA is not initialized.\n");
        return ERR_BAD_STATE;
    }

    if (req_len > ctx->shm_len) {
        TLOGE("Message too long (%u)\n", req_len);
        return ERR_BAD_LEN;
    }

    assert(req_len <= sizeof(msg));
    memcpy(msg, ctx->shm_base, req_len);

    ctx->op->handleMsg(msg, req_len, ctx->shm_base, &resp_len);

    hdr.cmd = CONFIRMATIONUI_CMD_MSG | CONFIRMATIONUI_RESP_BIT;
    args.msg_len = resp_len;
    rc = tipc_send2(chan, &hdr, sizeof(hdr), &args, sizeof(args));
    if (rc != (int)(sizeof(hdr) + sizeof(args))) {
        TLOGE("Failed to send response (%d)\n", rc);
        if (rc >= 0) {
            rc = ERR_BAD_LEN;
        }
        return rc;
    }

    return NO_ERROR;
}

static int on_connect(const struct tipc_port* port,
                      handle_t chan,
                      const struct uuid* peer,
                      void** ctx_p) {
    auto op = std::make_unique<TrustyOperation>();
    if (!op) {
        TLOGE("Failed to allocate TrustyOperation\n");
        return ERR_NO_MEMORY;
    }

    struct chan_ctx* ctx = (struct chan_ctx*)calloc(1sizeof(*ctx));
    if (!ctx) {
        TLOGE("Failed to allocate channel context\n");
        return ERR_NO_MEMORY;
    }

#if defined(PLATFORM_GENERIC_ARM64)
    /* Use the test key for emulator. */
    constexpr const auto kTestKey = teeui::AuthTokenKey::fill(
            static_cast<uint8_t>(teeui::TestKeyBits::BYTE));
    op->setHmacKey(kTestKey);
#else
    teeui::AuthTokenKey authKey;
    if (get_auth_token_key(authKey) == true) {
        TLOGD("%s, get auth token key successfully\n", __func__);
    } else {
        TLOGE("%s, get auth token key failed\n", __func__);
        /* Abort operation and free all resources. */
        op->abort();
        free(ctx);
        return ERR_GENERIC;
    }
    op->setHmacKey(authKey);
#endif

    ctx->op = std::move(op);
    *ctx_p = ctx;
    return NO_ERROR;
}

static void on_channel_cleanup(void* _ctx) {
    struct chan_ctx* ctx = (struct chan_ctx*)_ctx;
    /* Abort operation and free all resources. */
    int rc = munmap(ctx->shm_base, ctx->shm_len);
    if (rc != NO_ERROR) {
        TLOGW("munmap() failed: %d\n", rc);
    }
    ctx->op->abort();
    ctx->op.reset();
    free(ctx);
}

static int on_message(const struct tipc_port* port, handle_t chan, void* _ctx) {
    int rc;
    struct confirmationui_req req;
    handle_t shm_handle = INVALID_IPC_HANDLE;
    struct chan_ctx* ctx = (struct chan_ctx*)_ctx;

    assert(ctx);

    rc = confirmationui_recv(chan, &req, &shm_handle);
    if (rc < 0) {
        TLOGE("Failed to receive confirmationui request (%d)\n", rc);
        return rc;
    }

    if (rc != (int)sizeof(req)) {
        TLOGE("Receive request of unexpected size(%d)\n", rc);
        rc = ERR_BAD_LEN;
        goto out;
    }

    switch (req.hdr.cmd) {
    case CONFIRMATIONUI_CMD_INIT:
        rc = handle_init(chan, shm_handle, req.init_args.shm_len, ctx);
        goto out;

    case CONFIRMATIONUI_CMD_MSG:
        rc = handle_msg(chan, req.msg_args.msg_len, ctx);
        goto out;

    default:
        TLOGE("cmd 0x%x: unknown command\n", req.hdr.cmd);
        rc = ERR_CMD_UNKNOWN;
        goto out;
    }

out:
    close(shm_handle);
    return rc;
}

static struct tipc_port_acl confirmationui_port_acl = {
        .flags = IPC_PORT_ALLOW_NS_CONNECT,
};

static struct tipc_port confirmationui_port = {
        .name = CONFIRMATIONUI_PORT,
        .msg_max_size = sizeof(confirmationui_req),
        .msg_queue_len = 1,
        .acl = &confirmationui_port_acl,
};

static struct tipc_srv_ops confirmationui_ops = {
        .on_connect = on_connect,
        .on_message = on_message,
        .on_channel_cleanup = on_channel_cleanup,
};

int main(void) {
    int rc;
    struct tipc_hset* hset;

    TLOGD("Initializing ConfirmationUI app\n");

    hset = tipc_hset_create();
    if (IS_ERR(hset)) {
        TLOGE("Failed to create handle set (%d)\n", PTR_ERR(hset));
        return PTR_ERR(hset);
    }

    rc = tipc_add_service(hset, &confirmationui_port, 11,
                          &confirmationui_ops);
    if (rc != NO_ERROR) {
        return rc;
    }

    return tipc_run_event_loop(hset);
}

Messung V0.5 in Prozent
C=93 H=95 G=93

¤ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet am  2026-06-26) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.