File: better-randomness.patch

package info (click to toggle)
makepasswd 1.10-16
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 328 kB
  • sloc: perl: 4,063; makefile: 2
file content (194 lines) | stat: -rw-r--r-- 6,066 bytes parent folder | download | duplicates (2)
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
From aaad308ef7f6785072eaf05948a6944074794f3f Mon Sep 17 00:00:00 2001
From: Colin Watson <cjwatson@debian.org>
Date: Sat, 17 Dec 2022 12:33:06 +0000
Subject: Use Bytes::Random::Secure to generate random bytes

Bug-Debian: https://bugs.debian.org/307700
Bug-Debian: https://bugs.debian.org/320310
Bug-Debian: https://bugs.debian.org/564559
Bug-Debian: https://bugs.debian.org/642410
Bug-Debian: https://bugs.debian.org/792535
Bug-Ubuntu: https://bugs.launchpad.net/bugs/1573974
Forwarded: no
Last-Update: 2022-12-17

Patch-Name: better-randomness.patch
---
 makepasswd   | 73 +++++++++++++++++++++++++++++++++++++++-------------
 makepasswd.1 | 18 ++++++++-----
 2 files changed, 67 insertions(+), 24 deletions(-)

diff --git a/makepasswd b/makepasswd
index f0792f6..ad7a051 100755
--- a/makepasswd
+++ b/makepasswd
@@ -20,6 +20,7 @@ use	Getopt::Long;
 use	FileHandle;
 use	integer;
 use	bytes;
+use	Bytes::Random::Secure;
 
 #
 # Set default values for options ("" to indicate not-specified).
@@ -56,6 +57,7 @@ $Randomize = 1;
 $RandSeed = 0;
 $RerandomCount = -1;
 $RerandomNow = 1;
+$RNG = undef;
 $SeedValue = 0;
 
 #
@@ -457,10 +459,6 @@ Last modified on $Date.
 
 Format:          $Program [option...]
 
-For low (nonzero) values of --rerandom, tap the CONTROL key at random
-intervals if the program seems to stall.  The entropy base for /dev/random
-is depleted easily.
-
 Options are:
 
 --chars=N        Generate passwords with exactly N characters (do not use with
@@ -482,7 +480,9 @@ Options are:
 --nocrypt        Do not encrypt the generated password(s) (the default).
 --noverbose      Display no labels on output (the default).
 --randomseed=N   Use random number seed N, between 0 and 2^32 inclusive.  A zero
-                       value results in a real-random seed.
+                       value results in a real-random seed.  This option
+                       generates predictable passwords, and should normally
+                       be avoided.
 --rerandom=N     Set the random seed value every N values used.  Specify zero
                        to use a single seed value (the default).  Specify
                        one to get true-random passwords, but plan on hitting
@@ -494,6 +494,15 @@ Options are:
 ";
 }
 
+#
+# sub NumBits(N):  Number of significant bits in N.
+#
+
+sub NumBits
+{
+	return length(sprintf('%b', $_[0]));
+}
+
 #
 # sub Random(A, B):  Produce a random integer from A to B, inclusive.
 #
@@ -510,7 +519,40 @@ sub Random
 	{
 		$RerandomNow = $RerandomCount;
 	};
-	my $RandomOutputVal=rand($_[1]-$_[0]+1);
+	my $RandomOutputVal;
+	if ($RandSeed)
+	{
+		$RandomOutputVal = rand($_[1]-$_[0]+1);
+	}
+	else
+	{
+		# Repeatedly generate n-bit random byte sequences (with n =
+		# number of significant bits in range) until we get
+		# something less than range.
+		my $range = $_[1]-$_[0]+1;
+		my $bits = NumBits($range);
+		my $bytes = ($bits - 1) / 8 + 1;
+		my $max = 1 << ($bytes * 8);
+		$max -= $max % $range;
+		while (1)
+		{
+			my $buf = $RNG->bytes($bytes);
+			my $val = 0;
+			for my $byte (unpack('C*', $buf))
+			{
+				$val = ($val << 8) + $byte;
+			}
+			if ($val < $max)
+			{
+				# Using the modulus is OK here; we're
+				# working with a byte stream, so the
+				# low-order bits are no worse than any of
+				# the others.
+				$RandomOutputVal = $val % $range;
+				last;
+			}
+		}
+	}
 	$RandomOutputVal=$RandomOutputVal+$_[0];
 	$RandomOutputVal =~ s/\..*$//;
 	$RandomOutputVal;
@@ -524,19 +566,14 @@ sub SeedRandom
 {
 	my $i;
 	my $SeedOutput = $RandSeed;
-	$SeedOutput or do
+	if ($SeedOutput)
 	{
-		open(RANDOMSEED, "</dev/random") or die "Could not access a seed value.\n";
-		$SeedOutput=0;
-		for (my $i=0; $i < 4; $i++)
-		{
-			$Char=getc(RANDOMSEED);
-		        $NumChar=ord($Char);
-			$SeedOutput = ($SeedOutput*256)+$NumChar;
-		}
-		close(RANDOMSEED);
-	};
-	srand $SeedOutput;
+		srand $SeedOutput;
+	}
+	else
+	{
+		$RNG = Bytes::Random::Secure->new(NonBlocking => 1);
+	}
 }
 
 #
diff --git a/makepasswd.1 b/makepasswd.1
index 122f9b0..32bc1b7 100644
--- a/makepasswd.1
+++ b/makepasswd.1
@@ -72,9 +72,9 @@ makepasswd \- generate and/or encrypt passwords
 .SH DESCRIPTION
 .LP
 .B makepasswd
-generates true random passwords by using the /dev/random feature of
-Linux, with the emphasis on security over pronounceability.  It can
-also encrypt plaintext passwords given on the command line.
+generates true random passwords using /dev/urandom, with the emphasis on
+security over pronounceability.
+It can also encrypt plaintext passwords given on the command line.
 .SH OPTIONS
 .TP
 .B --chars N
@@ -119,13 +119,17 @@ Display no labels on output (the default).
 .B --randomseed N
 Use random number seed N, between 0 and 2^32 inclusive.  A zero value
 results in a real-random seed.
+This generates much less secure passwords than the default; not only does it
+generate predictable passwords due to the fixed seed, but the range of
+available seeds is 32 bits rather than the default of 256 bits, and cannot
+be changed without breaking expectations of previous users of this option.
+If possible, do not use this option.
 .TP
 .B --rerandom N
 Set the random seed value every N values used.  Specify zero to use a
 single seed value (the default). Specify one to get true-random
-passwords, but plan on hitting the CONTROL key a lot while it's
-running.  The Linux entropy device is quickly depleted and keystroke
-intervals are one source of new randomness.
+passwords, though note that doing this too frequently will deplete the
+supply of entropy available in the kernel's entropy pool.
 .TP
 .B --repeatpass N
 Use each password N times (4096 maximum, --crypt must be set and
@@ -145,6 +149,8 @@ program used to centrally administer the Linux Internet Support
 Cooperative IRC network.  It may potentially be of use in any
 situation where passwords must be secure and need not be memorized by
 humans.
+.LP
+Colin Watson modified it to use Bytes::Random::Secure.
 .SH COPYRIGHT
 .LP
 Copyright (c) 1997-1998 by lilo <lilo@linpeople.org>.  All rights are