1296047Soshogbo/*- 2296047Soshogbo * Copyright (c) 2013 The FreeBSD Foundation 3296047Soshogbo * All rights reserved. 4296047Soshogbo * 5296047Soshogbo * This software was developed by Pawel Jakub Dawidek under sponsorship from 6296047Soshogbo * the FreeBSD Foundation. 7296047Soshogbo * 8296047Soshogbo * Redistribution and use in source and binary forms, with or without 9296047Soshogbo * modification, are permitted provided that the following conditions 10296047Soshogbo * are met: 11296047Soshogbo * 1. Redistributions of source code must retain the above copyright 12296047Soshogbo * notice, this list of conditions and the following disclaimer. 13296047Soshogbo * 2. Redistributions in binary form must reproduce the above copyright 14296047Soshogbo * notice, this list of conditions and the following disclaimer in the 15296047Soshogbo * documentation and/or other materials provided with the distribution. 16296047Soshogbo * 17296047Soshogbo * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 18296047Soshogbo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19296047Soshogbo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20296047Soshogbo * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 21296047Soshogbo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22296047Soshogbo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23296047Soshogbo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24296047Soshogbo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25296047Soshogbo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26296047Soshogbo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27296047Soshogbo * SUCH DAMAGE. 28296047Soshogbo */ 29296047Soshogbo 30296047Soshogbo#include <sys/cdefs.h> 31296047Soshogbo__FBSDID("$FreeBSD$"); 32296047Soshogbo 33296047Soshogbo#include <sys/nv.h> 34296047Soshogbo 35296047Soshogbo#include <assert.h> 36296047Soshogbo#include <errno.h> 37296047Soshogbo#include <stdio.h> 38296047Soshogbo#include <stdlib.h> 39296047Soshogbo#include <string.h> 40296047Soshogbo 41296047Soshogbo#include <libcasper.h> 42296047Soshogbo#include <libcasper_service.h> 43296047Soshogbo 44296047Soshogbo#include "cap_random.h" 45296047Soshogbo 46296047Soshogbo#define MAXSIZE (1024 * 1024) 47296047Soshogbo 48296047Soshogboint 49296047Soshogbocap_random_buf(cap_channel_t *chan, void *buf, size_t nbytes) 50296047Soshogbo{ 51296047Soshogbo nvlist_t *nvl; 52296047Soshogbo const void *randbuf; 53296047Soshogbo uint8_t *ptr; 54296047Soshogbo size_t left, randbufsize; 55296047Soshogbo 56296047Soshogbo left = nbytes; 57296047Soshogbo ptr = buf; 58296047Soshogbo 59296047Soshogbo while (left > 0) { 60296047Soshogbo nvl = nvlist_create(0); 61296047Soshogbo nvlist_add_string(nvl, "cmd", "generate"); 62296047Soshogbo nvlist_add_number(nvl, "size", 63296047Soshogbo (uint64_t)(left > MAXSIZE ? MAXSIZE : left)); 64296047Soshogbo nvl = cap_xfer_nvlist(chan, nvl, 0); 65296047Soshogbo if (nvl == NULL) 66296047Soshogbo return (-1); 67296047Soshogbo if (nvlist_get_number(nvl, "error") != 0) { 68296047Soshogbo errno = (int)nvlist_get_number(nvl, "error"); 69296047Soshogbo nvlist_destroy(nvl); 70296047Soshogbo return (-1); 71296047Soshogbo } 72296047Soshogbo 73296047Soshogbo randbuf = nvlist_get_binary(nvl, "data", &randbufsize); 74296047Soshogbo memcpy(ptr, randbuf, randbufsize); 75296047Soshogbo 76296047Soshogbo nvlist_destroy(nvl); 77296047Soshogbo 78296047Soshogbo ptr += randbufsize; 79296047Soshogbo assert(left >= randbufsize); 80296047Soshogbo left -= randbufsize; 81296047Soshogbo } 82296047Soshogbo 83296047Soshogbo return (0); 84296047Soshogbo} 85296047Soshogbo 86296047Soshogbo/* 87296047Soshogbo * Service functions. 88296047Soshogbo */ 89296047Soshogbo 90296047Soshogbostatic int 91296047Soshogborandom_command(const char *cmd, const nvlist_t *limits __unused, 92296047Soshogbo nvlist_t *nvlin, nvlist_t *nvlout) 93296047Soshogbo{ 94296047Soshogbo void *data; 95296047Soshogbo size_t size; 96296047Soshogbo 97296047Soshogbo if (strcmp(cmd, "generate") != 0) 98296047Soshogbo return (EINVAL); 99296047Soshogbo if (!nvlist_exists_number(nvlin, "size")) 100296047Soshogbo return (EINVAL); 101296047Soshogbo 102296047Soshogbo size = (size_t)nvlist_get_number(nvlin, "size"); 103296047Soshogbo if (size == 0 || size > MAXSIZE) 104296047Soshogbo return (EINVAL); 105296047Soshogbo 106296047Soshogbo data = malloc(size); 107296047Soshogbo if (data == NULL) 108296047Soshogbo return (ENOMEM); 109296047Soshogbo 110296047Soshogbo arc4random_buf(data, size); 111296047Soshogbo 112296047Soshogbo nvlist_move_binary(nvlout, "data", data, size); 113296047Soshogbo 114296047Soshogbo return (0); 115296047Soshogbo} 116296047Soshogbo 117301572SoshogboCREATE_SERVICE("system.random", NULL, random_command, 0); 118