File: krnlop.c

package info (click to toggle)
ekeyd 1.1.3-3
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 628 kB
  • ctags: 859
  • sloc: ansic: 5,189; sh: 271; makefile: 199; perl: 148
file content (153 lines) | stat: -rw-r--r-- 2,943 bytes parent folder | download | duplicates (5)
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