summaryrefslogtreecommitdiffabout
path: root/pwmanager/pwmanager/randomizer.cpp
Unidiff
Diffstat (limited to 'pwmanager/pwmanager/randomizer.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--pwmanager/pwmanager/randomizer.cpp207
1 files changed, 152 insertions, 55 deletions
diff --git a/pwmanager/pwmanager/randomizer.cpp b/pwmanager/pwmanager/randomizer.cpp
index e623f51..1269c53 100644
--- a/pwmanager/pwmanager/randomizer.cpp
+++ b/pwmanager/pwmanager/randomizer.cpp
@@ -11,7 +11,7 @@
11 11
12/*************************************************************************** 12/***************************************************************************
13 * copyright (C) 2004 by Ulf Schenk 13 * copyright (C) 2004 by Ulf Schenk
14 * This file is originaly based on version 1.0.1 of pwmanager 14 * This file is originaly based on version 2.0 of pwmanager
15 * and was modified to run on embedded devices that run microkde 15 * and was modified to run on embedded devices that run microkde
16 * 16 *
17 * $Id$ 17 * $Id$
@@ -20,105 +20,202 @@
20#include "randomizer.h" 20#include "randomizer.h"
21#include "pwmexception.h" 21#include "pwmexception.h"
22 22
23#include <qfile.h>
24
25#include <kapplication.h>
26
23#include <stdlib.h> 27#include <stdlib.h>
24#include <time.h> 28#include <time.h>
25 29
26 30
31#ifdef PWM_EMBEDDED
32
33#ifndef Q_LONG
34#define Q_LONG long
35#endif
36
37#endif //PWM_EMBEDDED
38
39
27Randomizer * Randomizer::rndObj (0); 40Randomizer * Randomizer::rndObj (0);
28 41
29Randomizer::Randomizer() 42Randomizer::Randomizer()
30{ 43{
31 // probe for random devices 44 rndDev = new QFile;
32 rndDev = fopen("/dev/urandom", "r"); 45 seed = time(0);
33 if (rndDev) 46
47#if 1 // set to 0 to test rand_r() fallback
48
49 // probe for /dev/urandom
50 rndDev->setName("/dev/urandom");
51 if (rndDev->exists() &&
52 rndDev->open(IO_ReadOnly)) {
53 printDebug("Randomizer: using /dev/urandom");
34 return; 54 return;
35 rndDev = fopen("/dev/random", "r"); 55 }
36 if (rndDev) 56
57 // probe for /dev/random
58 rndDev->setName("/dev/random");
59 if (rndDev->exists() &&
60 rndDev->open(IO_ReadOnly)) {
61 printDebug("Randomizer: using /dev/random");
37 return; 62 return;
38 // fall back to rand_r() 63 }
39 seed = time(0); 64
65 // probe for EGD
66 char *fn = getenv("RANDFILE");
67 if (fn) {
68 rndDev->setName(fn);
69 if (rndDev->exists() &&
70 rndDev->open(IO_ReadOnly)) {
71 printDebug(string("Randomizer: using $RANDFILE \"")
72 + fn
73 + "\" (aka EGD)");
74 return;
75 }
76 }
77#endif
78
79 /* no secure randomizer found.
80 * Fall back to stdlib randomizer.
81 */
82 delete_and_null(rndDev);
83 printWarn("neither /dev/*random nor EGD found! "
84 "Falling back to insecure rand_r()!");
40} 85}
41 86
42Randomizer::~Randomizer() 87Randomizer::~Randomizer()
43{ 88{
89#ifndef PWM_EMBEDDED
90 while (mutex.locked()) {
91 /* wait for the mutex to unlock.
92 * Don't block the GUI here, so processEvents()
93 */
94 kapp->processEvents();
95 }
96#endif
44 if (rndDev) { 97 if (rndDev) {
45 if (fclose(rndDev)) { 98 rndDev->close();
46 printWarn("failed closing the random-device!"); 99 delete rndDev;
47 }
48 } 100 }
49} 101}
50 102
51char Randomizer::genRndChar() 103char Randomizer::genRndChar()
52{ 104{
105 char ret;
106#ifndef PWM_EMBEDDED
107 mutex.lock();
108#endif
53 if (rndDev) { 109 if (rndDev) {
54 /* we have a rand-device-node */ 110 /* we have a file which provides random data.
55 return (getc(rndDev)); 111 * Simply read it.
56 } else {
57 /* we don't have a random-device-node.
58 * so fall back to rand_r()
59 */ 112 */
60 return (rand_r(&seed) % 0xFF); 113 ret = rndDev->getch();
114 } else {
115 /* fall back to rand_r() */
116 ret = rand_r(&seed) % 0xFF;
61 } 117 }
118#ifndef PWM_EMBEDDED
119 mutex->unlock();
120#endif
121 return ret;
62} 122}
63 123
64int Randomizer::genRndInt() 124int Randomizer::genRndInt()
65{ 125{
66 if(rndDev) { 126 int ret;
67 int ret; 127#ifndef PWM_EMBEDDED
128 mutex->lock();
129#endif
130 if (rndDev) {
68 if (sizeof(int) == 4) { 131 if (sizeof(int) == 4) {
69 (reinterpret_cast<char *>(&ret))[0] = getc(rndDev); 132 (reinterpret_cast<char *>(&ret))[0] = rndDev->getch();
70 (reinterpret_cast<char *>(&ret))[1] = getc(rndDev); 133 (reinterpret_cast<char *>(&ret))[1] = rndDev->getch();
71 (reinterpret_cast<char *>(&ret))[2] = getc(rndDev); 134 (reinterpret_cast<char *>(&ret))[2] = rndDev->getch();
72 (reinterpret_cast<char *>(&ret))[3] = getc(rndDev); 135 (reinterpret_cast<char *>(&ret))[3] = rndDev->getch();
73 } else if (sizeof(int) == 8) { 136 } else if (sizeof(int) == 8) {
74 (reinterpret_cast<char *>(&ret))[0] = getc(rndDev); 137 (reinterpret_cast<char *>(&ret))[0] = rndDev->getch();
75 (reinterpret_cast<char *>(&ret))[1] = getc(rndDev); 138 (reinterpret_cast<char *>(&ret))[1] = rndDev->getch();
76 (reinterpret_cast<char *>(&ret))[2] = getc(rndDev); 139 (reinterpret_cast<char *>(&ret))[2] = rndDev->getch();
77 (reinterpret_cast<char *>(&ret))[3] = getc(rndDev); 140 (reinterpret_cast<char *>(&ret))[3] = rndDev->getch();
78 (reinterpret_cast<char *>(&ret))[4] = getc(rndDev); 141 (reinterpret_cast<char *>(&ret))[4] = rndDev->getch();
79 (reinterpret_cast<char *>(&ret))[5] = getc(rndDev); 142 (reinterpret_cast<char *>(&ret))[5] = rndDev->getch();
80 (reinterpret_cast<char *>(&ret))[6] = getc(rndDev); 143 (reinterpret_cast<char *>(&ret))[6] = rndDev->getch();
81 (reinterpret_cast<char *>(&ret))[7] = getc(rndDev); 144 (reinterpret_cast<char *>(&ret))[7] = rndDev->getch();
82 } else { 145 } else {
83 printWarn(string(__FILE__) + ":" + tostr(__LINE__) 146 printWarn(string(__FILE__) + ":" + tostr(__LINE__)
84 + ": sizeof(int) != 4 && sizeof(int) != 8"); 147 + ": sizeof(int) != 4 && sizeof(int) != 8");
85 rndDev = 0; 148 ret = rand_r(&seed);
86 seed = time(0);
87 return genRndInt();
88 } 149 }
89 return ret;
90 } else { 150 } else {
91 return rand_r(&seed); 151 ret = rand_r(&seed);
92 } 152 }
153#ifndef PWM_EMBEDDED
154 mutex->unlock();
155#endif
156 return ret;
93} 157}
94 158
95unsigned int Randomizer::genRndUInt() 159unsigned int Randomizer::genRndUInt()
96{ 160{
97 if(rndDev) { 161 unsigned int ret;
98 unsigned int ret; 162#ifndef PWM_EMBEDDED
163 mutex->lock();
164#endif
165 if (rndDev) {
99 if (sizeof(unsigned int) == 4) { 166 if (sizeof(unsigned int) == 4) {
100 (reinterpret_cast<char *>(&ret))[0] = getc(rndDev); 167 (reinterpret_cast<char *>(&ret))[0] = rndDev->getch();
101 (reinterpret_cast<char *>(&ret))[1] = getc(rndDev); 168 (reinterpret_cast<char *>(&ret))[1] = rndDev->getch();
102 (reinterpret_cast<char *>(&ret))[2] = getc(rndDev); 169 (reinterpret_cast<char *>(&ret))[2] = rndDev->getch();
103 (reinterpret_cast<char *>(&ret))[3] = getc(rndDev); 170 (reinterpret_cast<char *>(&ret))[3] = rndDev->getch();
104 } else if (sizeof(unsigned int) == 8) { 171 } else if (sizeof(unsigned int) == 8) {
105 (reinterpret_cast<char *>(&ret))[0] = getc(rndDev); 172 (reinterpret_cast<char *>(&ret))[0] = rndDev->getch();
106 (reinterpret_cast<char *>(&ret))[1] = getc(rndDev); 173 (reinterpret_cast<char *>(&ret))[1] = rndDev->getch();
107 (reinterpret_cast<char *>(&ret))[2] = getc(rndDev); 174 (reinterpret_cast<char *>(&ret))[2] = rndDev->getch();
108 (reinterpret_cast<char *>(&ret))[3] = getc(rndDev); 175 (reinterpret_cast<char *>(&ret))[3] = rndDev->getch();
109 (reinterpret_cast<char *>(&ret))[4] = getc(rndDev); 176 (reinterpret_cast<char *>(&ret))[4] = rndDev->getch();
110 (reinterpret_cast<char *>(&ret))[5] = getc(rndDev); 177 (reinterpret_cast<char *>(&ret))[5] = rndDev->getch();
111 (reinterpret_cast<char *>(&ret))[6] = getc(rndDev); 178 (reinterpret_cast<char *>(&ret))[6] = rndDev->getch();
112 (reinterpret_cast<char *>(&ret))[7] = getc(rndDev); 179 (reinterpret_cast<char *>(&ret))[7] = rndDev->getch();
113 } else { 180 } else {
114 printWarn(string(__FILE__) + ":" + tostr(__LINE__) 181 printWarn(string(__FILE__) + ":" + tostr(__LINE__)
115 + ": sizeof(unsigned int) != 4 && sizeof(unsigned int) != 8"); 182 + ": sizeof(unsigned int) != 4 && sizeof(unsigned int) != 8");
116 rndDev = 0; 183 ret = rand_r(&seed);
117 seed = time(0);
118 return genRndUInt();
119 } 184 }
120 return ret;
121 } else { 185 } else {
122 return static_cast<unsigned int>(rand_r(&seed)); 186 ret = rand_r(&seed);
187 }
188#ifndef PWM_EMBEDDED
189 mutex->unlock();
190#endif
191 return ret;
192}
193
194void Randomizer::genRndBuf(unsigned char *buf, size_t len)
195{
196#ifndef PWM_EMBEDDED
197 mutex->lock();
198#endif
199 if (rndDev) {
200 Q_LONG n;
201 n = rndDev->readBlock(reinterpret_cast<char *>(buf), len);
202 WARN_ON(n != static_cast<Q_LONG>(len));
203 } else {
204 size_t i;
205 for (i = 0; i < len; ++i)
206 buf[i] = rand_r(&seed) % 0xFF;
123 } 207 }
208#ifndef PWM_EMBEDDED
209 mutex->unlock();
210#endif
211}
212
213string Randomizer::genRndBuf(size_t len)
214{
215 string ret;
216 unsigned char *buf;
217 buf = new unsigned char[len];
218 genRndBuf(buf, len);
219 ret.assign(reinterpret_cast<const char *>(buf), len);
220 return ret;
124} 221}