fixed typo
[strongswan.git] / src / libstrongswan / utils / randomizer.c
1 /**
2 * @file randomizer.c
3 *
4 * @brief Implementation of randomizer_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005-2006 Martin Willi
10 * Copyright (C) 2005 Jan Hutter
11 * Hochschule fuer Technik Rapperswil
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
22 */
23
24 #include <string.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <unistd.h>
29
30 #include "randomizer.h"
31
32
33 typedef struct private_randomizer_t private_randomizer_t;
34
35 /**
36 * Private data of an randomizer_t object.
37 */
38 struct private_randomizer_t {
39
40 /**
41 * Public randomizer_t interface.
42 */
43 randomizer_t public;
44
45 /**
46 * @brief Reads a specific number of bytes from random or pseudo random device.
47 *
48 * @param this calling object
49 * @param pseudo_random TRUE, if from pseudo random bytes should be read,
50 * FALSE for true random bytes
51 * @param bytes number of bytes to read
52 * @param[out] buffer pointer to buffer where to write the data in.
53 * Size of buffer has to be at least bytes.
54 */
55 status_t (*get_bytes_from_device) (private_randomizer_t *this,bool pseudo_random, size_t bytes, u_int8_t *buffer);
56 };
57
58
59 /**
60 * Implementation of private_randomizer_t.get_bytes_from_device.
61 */
62 static status_t get_bytes_from_device(private_randomizer_t *this,bool pseudo_random, size_t bytes, u_int8_t *buffer)
63 {
64 size_t ndone;
65 int device;
66 size_t got;
67 char * device_name;
68
69 device_name = pseudo_random ? DEV_URANDOM : DEV_RANDOM;
70
71 device = open(device_name, 0);
72 if (device < 0) {
73 return FAILED;
74 }
75 ndone = 0;
76
77 /* read until nbytes are read */
78 while (ndone < bytes)
79 {
80 got = read(device, buffer + ndone, bytes - ndone);
81 if (got <= 0) {
82 close(device);
83 return FAILED;
84 }
85 ndone += got;
86 }
87 close(device);
88 return SUCCESS;
89 }
90
91 /**
92 * Implementation of randomizer_t.get_random_bytes.
93 */
94 static status_t get_random_bytes(private_randomizer_t *this,size_t bytes, u_int8_t *buffer)
95 {
96 return this->get_bytes_from_device(this, FALSE, bytes, buffer);
97 }
98
99 /**
100 * Implementation of randomizer_t.allocate_random_bytes.
101 */
102 static status_t allocate_random_bytes(private_randomizer_t *this, size_t bytes, chunk_t *chunk)
103 {
104 status_t status;
105 chunk->len = bytes;
106 chunk->ptr = malloc(bytes);
107 status = this->get_bytes_from_device(this, FALSE, bytes, chunk->ptr);
108 if (status != SUCCESS)
109 {
110 free(chunk->ptr);
111 }
112 return status;
113 }
114
115 /**
116 * Implementation of randomizer_t.get_pseudo_random_bytes.
117 */
118 static status_t get_pseudo_random_bytes(private_randomizer_t *this,size_t bytes, u_int8_t *buffer)
119 {
120 return (this->get_bytes_from_device(this, TRUE, bytes, buffer));
121 }
122
123 /**
124 * Implementation of randomizer_t.allocate_pseudo_random_bytes.
125 */
126 static status_t allocate_pseudo_random_bytes(private_randomizer_t *this, size_t bytes, chunk_t *chunk)
127 {
128 status_t status;
129 chunk->len = bytes;
130 chunk->ptr = malloc(bytes);
131 status = this->get_bytes_from_device(this, TRUE, bytes, chunk->ptr);
132 if (status != SUCCESS)
133 {
134 free(chunk->ptr);
135 }
136 return status;
137 }
138
139 /**
140 * Implementation of randomizer_t.destroy.
141 */
142 static void destroy(private_randomizer_t *this)
143 {
144 free(this);
145 }
146
147 /*
148 * Described in header.
149 */
150 randomizer_t *randomizer_create(void)
151 {
152 private_randomizer_t *this = malloc_thing(private_randomizer_t);
153
154 /* public functions */
155 this->public.get_random_bytes = (status_t (*) (randomizer_t *,size_t, u_int8_t *)) get_random_bytes;
156 this->public.allocate_random_bytes = (status_t (*) (randomizer_t *,size_t, chunk_t *)) allocate_random_bytes;
157 this->public.get_pseudo_random_bytes = (status_t (*) (randomizer_t *,size_t, u_int8_t *)) get_pseudo_random_bytes;
158 this->public.allocate_pseudo_random_bytes = (status_t (*) (randomizer_t *,size_t, chunk_t *)) allocate_pseudo_random_bytes;
159 this->public.destroy = (void (*) (randomizer_t *))destroy;
160
161 /* private functions */
162 this->get_bytes_from_device = get_bytes_from_device;
163
164 return &(this->public);
165 }