/src/strongswan/src/libstrongswan/plugins/random/random_rng.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2005-2008 Martin Willi |
3 | | * Copyright (C) 2005 Jan Hutter |
4 | | * |
5 | | * Copyright (C) secunet Security Networks AG |
6 | | * |
7 | | * This program is free software; you can redistribute it and/or modify it |
8 | | * under the terms of the GNU General Public License as published by the |
9 | | * Free Software Foundation; either version 2 of the License, or (at your |
10 | | * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. |
11 | | * |
12 | | * This program is distributed in the hope that it will be useful, but |
13 | | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
14 | | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
15 | | * for more details. |
16 | | */ |
17 | | |
18 | | #include <string.h> |
19 | | #include <unistd.h> |
20 | | #include <errno.h> |
21 | | #include <utils/debug.h> |
22 | | |
23 | | #include "random_rng.h" |
24 | | #include "random_plugin.h" |
25 | | |
26 | | typedef struct private_random_rng_t private_random_rng_t; |
27 | | |
28 | | /** |
29 | | * Private data of an random_rng_t object. |
30 | | */ |
31 | | struct private_random_rng_t { |
32 | | |
33 | | /** |
34 | | * Public random_rng_t interface. |
35 | | */ |
36 | | random_rng_t public; |
37 | | |
38 | | /** |
39 | | * random device, depends on quality |
40 | | */ |
41 | | int fd; |
42 | | }; |
43 | | |
44 | | METHOD(rng_t, get_bytes, bool, |
45 | | private_random_rng_t *this, size_t bytes, uint8_t *buffer) |
46 | 0 | { |
47 | 0 | size_t done; |
48 | 0 | ssize_t got; |
49 | |
|
50 | 0 | done = 0; |
51 | |
|
52 | 0 | while (done < bytes) |
53 | 0 | { |
54 | 0 | got = read(this->fd, buffer + done, bytes - done); |
55 | 0 | if (got <= 0) |
56 | 0 | { |
57 | 0 | DBG1(DBG_LIB, "reading from random FD %d failed: %s, retrying...", |
58 | 0 | this->fd, strerror(errno)); |
59 | 0 | sleep(1); |
60 | 0 | continue; |
61 | 0 | } |
62 | 0 | done += got; |
63 | 0 | } |
64 | 0 | return TRUE; |
65 | 0 | } |
66 | | |
67 | | METHOD(rng_t, allocate_bytes, bool, |
68 | | private_random_rng_t *this, size_t bytes, chunk_t *chunk) |
69 | 0 | { |
70 | 0 | *chunk = chunk_alloc(bytes); |
71 | 0 | get_bytes(this, chunk->len, chunk->ptr); |
72 | 0 | return TRUE; |
73 | 0 | } |
74 | | |
75 | | METHOD(rng_t, destroy, void, |
76 | | private_random_rng_t *this) |
77 | 0 | { |
78 | 0 | free(this); |
79 | 0 | } |
80 | | |
81 | | /* |
82 | | * Described in header. |
83 | | */ |
84 | | random_rng_t *random_rng_create(rng_quality_t quality) |
85 | 0 | { |
86 | 0 | private_random_rng_t *this; |
87 | |
|
88 | 0 | INIT(this, |
89 | 0 | .public = { |
90 | 0 | .rng = { |
91 | 0 | .get_bytes = _get_bytes, |
92 | 0 | .allocate_bytes = _allocate_bytes, |
93 | 0 | .destroy = _destroy, |
94 | 0 | }, |
95 | 0 | }, |
96 | 0 | ); |
97 | |
|
98 | 0 | switch (quality) |
99 | 0 | { |
100 | 0 | case RNG_TRUE: |
101 | 0 | this->fd = random_plugin_get_dev_random(); |
102 | 0 | break; |
103 | 0 | case RNG_STRONG: |
104 | 0 | this->fd = random_plugin_get_strong_equals_true() ? |
105 | 0 | random_plugin_get_dev_random() : |
106 | 0 | random_plugin_get_dev_urandom(); |
107 | 0 | break; |
108 | 0 | case RNG_WEAK: |
109 | 0 | default: |
110 | 0 | this->fd = random_plugin_get_dev_urandom(); |
111 | 0 | break; |
112 | 0 | } |
113 | | |
114 | 0 | return &this->public; |
115 | 0 | } |
116 | | |