4 * @brief Class used to get random and pseudo random values
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 #include <sys/types.h>
29 #include "randomizer.h"
31 #include <utils/allocator.h>
34 * Default random device used when no device is given.
36 #define DEFAULT_RANDOM_DEVICE "/dev/random"
39 * Pseudo random device used when no device is given.
41 #define DEFAULT_PSEUDO_RANDOM_DEVICE "/dev/urandom"
43 typedef struct private_randomizer_t private_randomizer_t
;
45 struct private_randomizer_t
{
52 * @brief Reads a specific number of bytes from random or pseudo random device
54 * @param pseudo_random TRUE, if pseudo random bytes should be read,
55 * FALSE for true random bytes
56 * @param bytes Number of bytes to read
57 * @param[out] buffer Pointer to buffer where to write the data in.
58 * Size of buffer has to be at least bytes.
63 status_t (*get_bytes_from_device
) (private_randomizer_t
*this,bool pseudo_random
, size_t bytes
, u_int8_t
*buffer
);
68 char *random_dev_name
;
71 * Pseudo random device name
73 char *pseudo_random_dev_name
;
78 * Implements private_randomizer_t's get_bytes_from_device function.
79 * See #private_randomizer_t.get_bytes_from_device for description.
81 static status_t
get_bytes_from_device(private_randomizer_t
*this,bool pseudo_random
, size_t bytes
, u_int8_t
*buffer
)
83 /* number of bytes already done */
85 /* device file descriptor */
90 device_name
= (pseudo_random
) ?
this->pseudo_random_dev_name
: this->random_dev_name
;
93 device
= open(device_name
, 0);
99 // read until nbytes are read
100 while (ndone
< bytes
)
102 got
= read(device
, buffer
+ ndone
, bytes
- ndone
);
117 * Implements randomizer_t's get_random_bytes function.
118 * See #randomizer_t.get_random_bytes for description.
120 static status_t
get_random_bytes(private_randomizer_t
*this,size_t bytes
, u_int8_t
*buffer
)
122 return (this->get_bytes_from_device(this, FALSE
, bytes
, buffer
));
125 * Implements randomizer_t's allocate_random_bytes function.
126 * See #randomizer_t.allocate_random_bytes for description.
128 static status_t
allocate_random_bytes(private_randomizer_t
*this, size_t bytes
, chunk_t
*chunk
)
131 chunk
->ptr
= allocator_alloc(bytes
);
132 if (chunk
->ptr
== NULL
)
136 return (this->get_bytes_from_device(this, FALSE
, bytes
, chunk
->ptr
));
140 * Implements randomizer_t's get_pseudo_random_bytes function.
141 * See #randomizer_t.get_pseudo_random_bytes for description.
143 static status_t
get_pseudo_random_bytes(private_randomizer_t
*this,size_t bytes
, u_int8_t
*buffer
)
145 return (this->get_bytes_from_device(this, TRUE
, bytes
, buffer
));
150 * Implements randomizer_t's allocate_random_bytes function.
151 * See #randomizer_t.allocate_random_bytes for description.
153 static status_t
allocate_pseudo_random_bytes(private_randomizer_t
*this, size_t bytes
, chunk_t
*chunk
)
156 chunk
->ptr
= allocator_alloc(bytes
);
157 if (chunk
->ptr
== NULL
)
161 return (this->get_bytes_from_device(this, TRUE
, bytes
, chunk
->ptr
));
166 * Implements randomizer_t's destroy function.
167 * See #randomizer_t.destroy for description.
169 static status_t
destroy(private_randomizer_t
*this)
171 allocator_free(this->random_dev_name
);
172 allocator_free(this->pseudo_random_dev_name
);
173 allocator_free(this);
179 * Described in header.
181 randomizer_t
*randomizer_create(void)
183 return randomizer_create_on_devices(DEFAULT_RANDOM_DEVICE
,DEFAULT_PSEUDO_RANDOM_DEVICE
);
187 * Described in header.
189 randomizer_t
*randomizer_create_on_devices(char * random_dev_name
,char * prandom_dev_name
)
191 private_randomizer_t
*this = allocator_alloc_thing(private_randomizer_t
);
196 if ((random_dev_name
== NULL
) || (prandom_dev_name
== NULL
))
201 /* public functions */
202 this->public.get_random_bytes
= (status_t (*) (randomizer_t
*,size_t, u_int8_t
*)) get_random_bytes
;
203 this->public.allocate_random_bytes
= (status_t (*) (randomizer_t
*,size_t, chunk_t
*)) allocate_random_bytes
;
204 this->public.get_pseudo_random_bytes
= (status_t (*) (randomizer_t
*,size_t, u_int8_t
*)) get_pseudo_random_bytes
;
205 this->public.allocate_pseudo_random_bytes
= (status_t (*) (randomizer_t
*,size_t, chunk_t
*)) allocate_pseudo_random_bytes
;
206 this->public.destroy
= (status_t (*) (randomizer_t
*))destroy
;
208 /* private functions */
209 this->get_bytes_from_device
= get_bytes_from_device
;
212 this->random_dev_name
= allocator_alloc(strlen(random_dev_name
) + 1);
213 if (this->random_dev_name
== NULL
)
215 allocator_free(this);
218 strcpy(this->random_dev_name
,random_dev_name
);
220 this->pseudo_random_dev_name
= allocator_alloc(strlen(prandom_dev_name
) + 1);
221 if (this->pseudo_random_dev_name
== NULL
)
223 allocator_free(this->random_dev_name
);
224 allocator_free(this);
227 strcpy(this->pseudo_random_dev_name
,prandom_dev_name
);
229 return &(this->public);