1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
/* daemon/krnlop.c
*
* Entropy key kernel output
*
* Copyright 2009 Simtec Electronics
*
* For licence terms refer to the COPYING file.
*/
#include <stdint.h>
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include "stream.h"
#include "krnlop.h"
static int krnlop_bpb;
#if defined(EKEY_OS_LINUX)
/* Linux kernel entropy injection */
#include <alloca.h>
#include <linux/types.h>
#include <linux/random.h>
#include <sys/ioctl.h>
static ssize_t
krnl_write(int fd, const void *buf, size_t count)
{
struct rand_pool_info *rndpool;
rndpool = alloca(sizeof(struct rand_pool_info) + count);
rndpool->entropy_count = count * krnlop_bpb;
rndpool->buf_size = count;
memcpy(rndpool->buf, buf, count);
if (ioctl(fd, RNDADDENTROPY, rndpool) == -1) {
perror("ioctl");
return -1;
}
return count;
}
estream_state_t *
estream_krnl_open(const char *path, int bpb)
{
estream_state_t *stream_state = NULL;
int fd;
fd = open(path, O_RDWR | O_NOCTTY);
if (fd < 0)
return NULL;
stream_state = calloc(1, sizeof(estream_state_t));
if (stream_state == NULL) {
close(fd);
return NULL;
}
stream_state->fd = fd;
stream_state->estream_read = read;
stream_state->estream_write = krnl_write;
krnlop_bpb = bpb;
return stream_state;
}
#elif defined(EKEY_OS_OPENBSD) || defined(EKEY_OS_MIRBSD)
/* OpenBSD and MirBSD kernel entropy injection */
#include <sys/ioctl.h>
#include <dev/rndvar.h>
#include <dev/rndioctl.h>
#include <errno.h>
static ssize_t
krnl_write(int fd, const void *buf, size_t count)
{
size_t ofs = 0;
ssize_t n;
unsigned int u;
while (ofs < count) {
n = write(fd, (const char *)buf + ofs, count - ofs);
if (n == -1) {
if (errno == EINTR)
continue;
perror("write");
return -1;
}
ofs += n;
}
/* from MirOS: src/libexec/cprng/cprng.c,v 1.14 */
u = count * krnlop_bpb;
if (ioctl(fd, RNDADDTOENTCNT, &u) == -1) {
perror("ioctl");
return -1;
}
return count;
}
estream_state_t *
estream_krnl_open(const char *path, int bpb)
{
estream_state_t *stream_state = NULL;
int fd;
fd = open(path, O_RDWR | O_NOCTTY);
if (fd < 0)
return NULL;
stream_state = calloc(1, sizeof(estream_state_t));
if (stream_state == NULL) {
close(fd);
return NULL;
}
stream_state->fd = fd;
stream_state->estream_read = read;
stream_state->estream_write = krnl_write;
krnlop_bpb = bpb;
return stream_state;
}
#else
/* Default implementation */
estream_state_t *
estream_krnl_open(const char *path, int bpb)
{
estream_state_t *stream_state = NULL;
krnlop_bpb = bpb;
return stream_state;
}
#endif
|