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
|