Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/trusty/trusty/hardware/nxp/app/hwcrypto/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 6 kB image not shown  

Quelle  hwrng_srv.c

  Sprache: C
 

/*
 * Copyright (C) 2016-2017 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 <assert.h>
#include <inttypes.h>
#include <lk/list.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <trusty_ipc.h>
#include <uapi/err.h>

#include <interface/hwrng/hwrng.h>

#include "common.h"
#include "hwrng_srv_priv.h"

#define TLOG_TAG "hwrng_srv"
#include <trusty_log.h>

#define HWRNG_SRV_NAME HWRNG_PORT
#define MAX_HWRNG_MSG_SIZE 4096

struct hwrng_chan_ctx {
    tipc_event_handler_t evt_handler;
    struct list_node node;
    handle_t chan;
    size_t req_size;
    bool send_blocked;
};

static void hwrng_port_handler(const uevent_t* ev, void* priv);
static void hwrng_chan_handler(const uevent_t* ev, void* priv);

static handle_t hwrng_port = INVALID_IPC_HANDLE;

static tipc_event_handler_t hwrng_port_evt_handler = {
        .proc = hwrng_port_handler,
};

static uint8_t rng_data[MAX_HWRNG_MSG_SIZE];

static struct list_node hwrng_req_list = LIST_INITIAL_VALUE(hwrng_req_list);

/****************************************************************************/

/*
 *  Hexdump content of memory region
 */

static void _hexdump8(const void* ptr, size_t len) {
    uintptr_t address = (uintptr_t)ptr;
    size_t count;
    size_t i;

    for (count = 0; count < len; count += 16) {
        fprintf(stderr, "0x%08" PRIxPTR ": ", address);
        for (i = 0; i < MIN(len - count, 16); i++) {
            fprintf(stderr, "0x%02hhx ", *(const uint8_t*)(address + i));
        }
        fprintf(stderr, "\n");
        address += 16;
    }
}

/*
 * Close specified HWRNG service channel
 */

static void hwrng_close_chan(struct hwrng_chan_ctx* ctx) {
    close(ctx->chan);

    if (list_in_list(&ctx->node))
        list_delete(&ctx->node);

    free(ctx);
}

/*
 * Handle HWRNG request queue
 */

static bool hwrng_handle_req_queue(void) {
    struct hwrng_chan_ctx* ctx;
    struct hwrng_chan_ctx* temp;

    /* service channels */
    bool need_more = false;

    /* for all pending requests */
    list_for_every_entry_safe(&hwrng_req_list, ctx, temp, struct hwrng_chan_ctx,
                              node) {
        if (ctx->send_blocked)
            continue/* cant service it rignt now */

        size_t len = ctx->req_size;

        if (len > MAX_HWRNG_MSG_SIZE)
            len = MAX_HWRNG_MSG_SIZE;

        /* get rng data */
        hwrng_dev_get_rng_data(rng_data, len);

        /* send reply */
        int rc = tipc_send_single_buf(ctx->chan, rng_data, len);
        if (rc < 0) {
            if (rc == ERR_NOT_ENOUGH_BUFFER) {
                /* mark it as send_blocked */
                ctx->send_blocked = true;
            } else {
                /* just close HWRNG request channel */
                TLOGE("failed (%d) to send_reply\n", rc);
                hwrng_close_chan(ctx);
            }
            continue;
        }

        ctx->req_size -= len;

        if (ctx->req_size == 0) {
            /* remove it from pending list */
            list_delete(&ctx->node);
        } else {
            need_more = true;
        }
    }

    return need_more;
}

/*
 * Check if we can handle request queue
 */

static void hwrng_kick_req_queue(void) {
    hwrng_handle_req_queue();
}

/*
 *  Read and queue HWRNG request message
 */

static int hwrng_chan_handle_msg(struct hwrng_chan_ctx* ctx) {
    int rc;
    struct hwrng_req req;

    assert(ctx);

    /* read request */
    rc = tipc_recv_single_buf(ctx->chan, &req, sizeof(req));
    if (rc != sizeof(req)) {
        TLOGE("failed (%d) to receive msg for chan %d\n", rc, ctx->chan);
        return rc;
    }

    /* check if we already have request in progress */
    if (list_in_list(&ctx->node)) {
        /* extend it */
        ctx->req_size += req.len;
    } else {
        /* queue it */
        ctx->req_size = req.len;
        list_add_tail(&hwrng_req_list, &ctx->node);
    }

    return 0;
}

/*
 *  Channel handler where HWRNG requests are coming from
 */

static void hwrng_chan_handler(const uevent_t* ev, void* priv) {
    struct hwrng_chan_ctx* ctx = priv;

    assert(ctx);
    assert(ev->handle == ctx->chan);

    tipc_handle_chan_errors(ev);

    if (ev->event & IPC_HANDLE_POLL_HUP) {
        hwrng_close_chan(ctx);
    } else {
        if (ev->event & IPC_HANDLE_POLL_SEND_UNBLOCKED) {
            ctx->send_blocked = false;
        }

        if (ev->event & IPC_HANDLE_POLL_MSG) {
            int rc = hwrng_chan_handle_msg(ctx);
            if (rc) {
                hwrng_close_chan(ctx);
            }
        }
    }

    /* kick state machine */
    hwrng_kick_req_queue();
}

/*
 * Port were HWRNG requests are coming from
 */

static void hwrng_port_handler(const uevent_t* ev, void* priv) {
    uuid_t peer_uuid;

    tipc_handle_port_errors(ev);

    if (ev->event & IPC_HANDLE_POLL_READY) {
        handle_t chan;

        /* incoming connection: accept it */
        int rc = accept(ev->handle, &peer_uuid);
        if (rc < 0) {
            TLOGE("failed (%d) to accept on port %d\n", rc, ev->handle);
            return;
        }
        chan = (handle_t)rc;

        /* allocate state */
        struct hwrng_chan_ctx* ctx = calloc(1sizeof(*ctx));
        if (!ctx) {
            TLOGE("failed to alloc state for chan %d\n", chan);
            close(chan);
            return;
        }

        /* init channel state */
        ctx->evt_handler.priv = ctx;
        ctx->evt_handler.proc = hwrng_chan_handler;
        ctx->chan = chan;

        /* attach channel handler */
        rc = set_cookie(chan, &ctx->evt_handler);
        if (rc) {
            TLOGE("failed (%d) to set_cookie on chan %d\n", rc, chan);
            free(ctx);
            close(chan);
            return;
        }
    }
}

/*
 *  Initialize HWRNG services
 */

int hwrng_start_service(void) {
    int rc;

    TLOGD("Start HWRNG service\n");

    /* create HWRNG port */
    rc = port_create(HWRNG_SRV_NAME, 1, MAX_HWRNG_MSG_SIZE,
                     IPC_PORT_ALLOW_TA_CONNECT);
    if (rc < 0) {
        TLOGE("Failed (%d) to create port '%s'\n", rc, HWRNG_SRV_NAME);
        return rc;
    } else {
        hwrng_port = (handle_t)rc;
        set_cookie(hwrng_port, &hwrng_port_evt_handler);
    }

    return NO_ERROR;
}

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

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet am  2026-06-27) ¤

*© 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.