Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  hwrng_service.c

  Sprache: C
 

/*
 * Copyright (c) 2022, Google Inc. All rights reserved
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */


#define LOCAL_TRACE 0

#include <err.h>
#include <inttypes.h>
#include <lib/ktipc/ktipc.h>
#include <lib/rand/rand.h>
#include <lib/trusty/ipc.h>
#include <lib/trusty/ipc_msg.h>
#include <lib/trusty/uuid.h>
#include <lk/init.h>
#include <lk/list.h>
#include <lk/trace.h>

#include <interface/hwrng/hwrng.h>

#define HWRNG_SRV_NAME HWRNG_PORT
#define MAX_HWRNG_MSG_SIZE 128

struct hwrng_chan_ctx {
    struct list_node node;
    struct handle* chan;
    size_t req_size;
    int error;
    bool send_blocked;
};

static uint8_t rng_data[MAX_HWRNG_MSG_SIZE];

/* If we have data left over from the last request, keep track of it */
static size_t rng_data_avail_count;
static size_t rng_data_avail_pos;

static struct list_node hwrng_req_list = LIST_INITIAL_VALUE(hwrng_req_list);

/*
 * Handle HWRNG request queue
 */

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

    /* for all pending requests */
    bool more_requests;
    do {
        more_requests = false;
        list_for_every_entry_safe(&hwrng_req_list, ctx, temp,
                                  struct hwrng_chan_ctx, node) {
            if (ctx->error || ctx->send_blocked)
                continue/* can't service it right now */

            /*
             * send up to MAX_HWRNG_MSG_SIZE per client at a time,
             * to prevent a single client from starving all the others
             */

            size_t len = MIN(ctx->req_size, MAX_HWRNG_MSG_SIZE);
            if (rng_data_avail_count) {
                /* use leftover data if there is any */
                len = MIN(len, rng_data_avail_count);
            } else {
                /* get hwrng data */
                rand_get_bytes(rng_data, len);
                rng_data_avail_pos = 0;
                rng_data_avail_count = len;
            }

            /* send reply */
            rc = ktipc_send(ctx->chan, rng_data + rng_data_avail_pos, len);
            if (rc < 0) {
                if (rc == ERR_NOT_ENOUGH_BUFFER) {
                    /* mark it as send_blocked */
                    ctx->send_blocked = true;
                } else {
                    TRACEF("%s: failed (%d) to send_reply\n", __func__, rc);
                    ctx->error = rc;
                }
                continue;
            }

            rng_data_avail_pos += len;
            rng_data_avail_count -= len;
            ctx->req_size -= len;

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

static int hwrng_handle_msg(const struct ktipc_port* port,
                            struct handle* chan,
                            void* ctx_v) {
    int rc;
    struct hwrng_chan_ctx* ctx = ctx_v;
    struct hwrng_req req;

    /* check for an error from a previous send attempt */
    if (ctx->error) {
        return ctx->error;
    }

    /* read request */
    rc = ktipc_recv(chan, sizeof(req), &req, sizeof(req));
    if (rc < 0) {
        TRACEF("%s: failed (%d) to receive msg for chan\n", __func__, rc);
        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);
    }

    hwrng_handle_req_queue();

    return ctx->error;
}

static int hwrng_handle_connect(const struct ktipc_port* port,
                                struct handle* chan,
                                const struct uuid* peer,
                                void** ctx_p) {
    struct hwrng_chan_ctx* ctx = calloc(1sizeof(*ctx));
    if (!ctx) {
        TRACEF("%s: failed to allocate context\n", __func__);
        return ERR_NO_MEMORY;
    }

    ctx->chan = chan;
    *ctx_p = ctx;

    return NO_ERROR;
}

static void hwrng_handle_channel_cleanup(void* ctx_v) {
    struct hwrng_chan_ctx* ctx = ctx_v;

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

    free(ctx);
}

static int hwrng_handle_send_unblocked(const struct ktipc_port* port,
                                       struct handle* chan,
                                       void* ctx_v) {
    struct hwrng_chan_ctx* ctx = ctx_v;

    if (ctx->error) {
        return ctx->error;
    }

    ctx->send_blocked = false;

    hwrng_handle_req_queue();

    return ctx->error;
}

const static struct ktipc_srv_ops hwrng_srv_ops = {
        .on_connect = hwrng_handle_connect,
        .on_message = hwrng_handle_msg,
        .on_channel_cleanup = hwrng_handle_channel_cleanup,
        .on_send_unblocked = hwrng_handle_send_unblocked,
};

const static struct ktipc_port_acl hwrng_srv_port_acl = {
        .flags = IPC_PORT_ALLOW_TA_CONNECT,
        .uuids = NULL,
        .uuid_num = 0,
        .extra_data = NULL,
};

const static struct ktipc_port hwrng_srv_port = {
        .name = HWRNG_SRV_NAME,
        .uuid = &kernel_uuid,
        .msg_max_size = MAX_HWRNG_MSG_SIZE,
        .msg_queue_len = 1,
        .acl = &hwrng_srv_port_acl,
        .priv = NULL,
};

static struct ktipc_server hwrng_ktipc_server =
        KTIPC_SERVER_INITIAL_VALUE(hwrng_ktipc_server, "hwrng_ktipc_server");

static void hwrng_ktipc_server_init(uint lvl) {
    int rc;

    rc = ktipc_server_start(&hwrng_ktipc_server);
    if (rc < 0) {
        panic("Failed (%d) to start hwrng server\n", rc);
    }

    rc = ktipc_server_add_port(&hwrng_ktipc_server, &hwrng_srv_port,
                               &hwrng_srv_ops);
    if (rc < 0) {
        panic("Failed (%d) to create hwrng service port\n", rc);
    }
}

LK_INIT_HOOK(hwrng_ktipc_server_init,
             hwrng_ktipc_server_init,
             LK_INIT_LEVEL_APPS - 1)

Messung V0.5 in Prozent
C=88 H=91 G=89

¤ Dauer der Verarbeitung: 0.9 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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik