diff -Naur libreswan-3.12-orig/include/ipsecconf/keywords.h libreswan-3.12/include/ipsecconf/keywords.h
--- libreswan-3.12-orig/include/ipsecconf/keywords.h 2015-02-26 21:24:52.037000000 -0600
+++ libreswan-3.12/include/ipsecconf/keywords.h 2015-02-26 21:25:39.297000000 -0600
@@ -83,6 +83,7 @@
KBF_STRICTCRLPOLICY,
KBF_SEND_CA,
KBF_NATIKEPORT,
+ KBF_SEEDBITS,
KBF_KEEPALIVE,
KBF_PLUTORESTARTONCRASH,
KBF_CRLCHECKINTERVAL,
diff -Naur libreswan-3.12-orig/lib/libipsecconf/confread.c libreswan-3.12/lib/libipsecconf/confread.c
--- libreswan-3.12-orig/lib/libipsecconf/confread.c 2015-02-26 21:24:52.038000000 -0600
+++ libreswan-3.12/lib/libipsecconf/confread.c 2015-02-26 21:25:39.297000000 -0600
@@ -98,6 +98,10 @@
cfg->setup.options[KBF_KEEPALIVE] = 0; /* config setup */
cfg->setup.options[KBF_NATIKEPORT] = NAT_IKE_UDP_PORT;
+
+ /* Don't inflict BSI requirements on everyone */
+ cfg->setup.options[KBF_SEEDBITS] = 0;
+
#ifdef HAVE_LABELED_IPSEC
cfg->setup.options[KBF_SECCTX] = SECCTX;
#endif
diff -Naur libreswan-3.12-orig/lib/libipsecconf/keywords.c libreswan-3.12/lib/libipsecconf/keywords.c
--- libreswan-3.12-orig/lib/libipsecconf/keywords.c 2015-02-26 21:24:52.038000000 -0600
+++ libreswan-3.12/lib/libipsecconf/keywords.c 2015-02-26 21:25:39.298000000 -0600
@@ -369,6 +369,7 @@
{ "virtual-private", kv_config, kt_string, KSF_VIRTUALPRIVATE, NOT_ENUM },
{ "nat_ikeport", kv_config | kv_alias, kt_number, KBF_NATIKEPORT, NOT_ENUM }, /* obsolete _ */
{ "nat-ikeport", kv_config, kt_number, KBF_NATIKEPORT, NOT_ENUM },
+ { "seedbits", kv_config, kt_number, KBF_SEEDBITS, NOT_ENUM },
{ "keep_alive", kv_config | kv_alias, kt_number, KBF_KEEPALIVE, NOT_ENUM }, /* obsolete _ */
{ "keep-alive", kv_config, kt_number, KBF_KEEPALIVE, NOT_ENUM },
{ "nat_traversal", kv_config, kt_obsolete_quiet, KBF_WARNIGNORE, NOT_ENUM },
diff -Naur libreswan-3.12-orig/programs/configs/d.ipsec.conf/order.txt libreswan-3.12/programs/configs/d.ipsec.conf/order.txt
--- libreswan-3.12-orig/programs/configs/d.ipsec.conf/order.txt 2015-02-26 21:24:52.040000000 -0600
+++ libreswan-3.12/programs/configs/d.ipsec.conf/order.txt 2015-02-26 21:25:39.298000000 -0600
@@ -89,6 +89,7 @@
d.ipsec.conf/myvendorid.xml
d.ipsec.conf/oe.xml
d.ipsec.conf/nhelpers.xml
+d.ipsec.conf/seedbits.xml
d.ipsec.conf/secctx-attr-value.xml
d.ipsec.conf/plutofork.xml
d.ipsec.conf/crlcheckinterval.xml
diff -Naur libreswan-3.12-orig/programs/configs/d.ipsec.conf/seedbits.xml libreswan-3.12/programs/configs/d.ipsec.conf/seedbits.xml
--- libreswan-3.12-orig/programs/configs/d.ipsec.conf/seedbits.xml 1969-12-31 18:00:00.000000000 -0600
+++ libreswan-3.12/programs/configs/d.ipsec.conf/seedbits.xml 2015-02-26 21:25:39.299000000 -0600
@@ -0,0 +1,15 @@
+ <varlistentry>
+ <term><emphasis remap='B'>seedbits</emphasis></term>
+ <listitem>
+<para>
+Pluto uses the NSS crypto library as its random source. Some government
+Three Letter Agencies require that pluto reads additional bits from /dev/random
+and feed these into the NSS RNG before drawing random from the NSS library,
+despite the NSS library itself already seeding its internal state. This
+process can block pluto for an extended time during startup, depending on
+the entropy of the system. Therefor, the default is to not perform this
+redundant seeding. If specifying a value, it is recommended to specify at
+least 460 bits (for FIPS) or 440 bits (for BSI).
+</para>
+ </listitem>
+ </varlistentry>
diff -Naur libreswan-3.12-orig/programs/pluto/pluto.8 libreswan-3.12/programs/pluto/pluto.8
--- libreswan-3.12-orig/programs/pluto/pluto.8 2014-11-06 21:52:50.000000000 -0600
+++ libreswan-3.12/programs/pluto/pluto.8 2015-02-26 21:25:39.299000000 -0600
@@ -2,12 +2,12 @@
.\" Title: IPSEC_PLUTO
.\" Author: Paul Wouters
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 10/22/2014
+.\" Date: 01/14/2015
.\" Manual: Executable programs
.\" Source: libreswan
.\" Language: English
.\"
-.TH "IPSEC_PLUTO" "8" "10/22/2014" "libreswan" "Executable programs"
+.TH "IPSEC_PLUTO" "8" "01/14/2015" "libreswan" "Executable programs"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -31,7 +31,7 @@
pluto \- ipsec whack : IPsec IKE keying daemon and control interface
.SH "SYNOPSIS"
.HP \w'\fBipsec\fR\ 'u
-\fBipsec\fR \fIpluto\fR [\-\-help] [\-\-version] [\-\-leak\-detective] [\-\-config\ \fIfilename\fR] [\-\-vendorid\ \fIVID\fR] [\-\-nofork] [\-\-stderrlog] [\-\-\-\-plutostderrlogtime] [\-\-logfile\ \fIfilename\fR] [\-\-use\-klips] [\-\-use\-mast] [\-\-use\-netkey] [\-\-use\-nostack] [\-\-uniqueids] [\-\-virtual\-private\ \fInetwork_list\fR] [\-\-keep\-alive\ \fIdelay_sec\fR] [\-\-force\-busy] [\-\-nocrsend] [\-\-strictcrlpolicy] [\-\-crlcheckinterval] [\-\-interface\ \fIinterfacename\fR] [\-\-listen\ \fIipaddr\fR] [\-\-ikeport\ \fIportnumber\fR] [\-\-natikeport\ \fIportnumber\fR] [\-\-ctlbase\ \fIpath\fR] [\-\-secretsfile\ \fIsecrets\-file\fR] [\-\-adns\ \fIpathname\fR] [\-\-nhelpers\ \fInumber\fR] [\-\-perpeerlog] [\-\-perpeerlogbase\ \fIdirname\fR] [\-\-ipsecdir\ \fIdirname\fR] [\-\-coredir\ \fIdirname\fR] [\-\-statsbin\ \fIfilename\fR] [\-\-secctx\-attr\-value\ \fInumber\fR]
+\fBipsec\fR \fIpluto\fR [\-\-help] [\-\-version] [\-\-leak\-detective] [\-\-config\ \fIfilename\fR] [\-\-vendorid\ \fIVID\fR] [\-\-nofork] [\-\-stderrlog] [\-\-\-\-plutostderrlogtime] [\-\-logfile\ \fIfilename\fR] [\-\-use\-klips] [\-\-use\-mast] [\-\-use\-netkey] [\-\-use\-nostack] [\-\-uniqueids] [\-\-virtual\-private\ \fInetwork_list\fR] [\-\-keep\-alive\ \fIdelay_sec\fR] [\-\-force\-busy] [\-\-nocrsend] [\-\-strictcrlpolicy] [\-\-crlcheckinterval] [\-\-interface\ \fIinterfacename\fR] [\-\-listen\ \fIipaddr\fR] [\-\-ikeport\ \fIportnumber\fR] [\-\-natikeport\ \fIportnumber\fR] [\-\-ctlbase\ \fIpath\fR] [\-\-secretsfile\ \fIsecrets\-file\fR] [\-\-adns\ \fIpathname\fR] [\-\-nhelpers\ \fInumber\fR] [\-\-seedbits\ \fInumbits\fR] [\-\-perpeerlog] [\-\-perpeerlogbase\ \fIdirname\fR] [\-\-ipsecdir\ \fIdirname\fR] [\-\-coredir\ \fIdirname\fR] [\-\-statsbin\ \fIfilename\fR] [\-\-secctx\-attr\-value\ \fInumber\fR]
.HP \w'\fBipsec\fR\ 'u
\fBipsec\fR \fIwhack\fR [\-\-help] [\-\-version]
.HP \w'\fBipsec\fR\ 'u
@@ -317,6 +317,10 @@
\fI\-1\fR
tells pluto to perform the above calculation\&. Any other value forces the number to that amount\&.
.PP
+Pluto uses the NSS crypto library as its random source\&. Some government Three Letter Agency requires that pluto reads 440 bits from /dev/random and feed this into the NSS RNG before drawing random from the NSS library, despite the NSS library itself already seeding its internal state\&. As this process can block pluto for an extended time, the default is to not perform this redundant seeding\&. The
+\fB\-\-seedbits\fR
+option can be used to specify the number of bits that will be pulled from /dev/random and seeded into the NSS RNG\&. This can also be accomplished by specifying seedbits in the "config setup" section of ipsec\&.conf\&. This option should not be used by most people\&.
+.PP
\fBpluto\fR
attempts to create a lockfile with the name
/var/run/pluto/pluto\&.pid\&. If the lockfile cannot be created,
diff -Naur libreswan-3.12-orig/programs/pluto/pluto.8.xml libreswan-3.12/programs/pluto/pluto.8.xml
--- libreswan-3.12-orig/programs/pluto/pluto.8.xml 2014-11-06 21:52:50.000000000 -0600
+++ libreswan-3.12/programs/pluto/pluto.8.xml 2015-02-26 21:25:39.300000000 -0600
@@ -57,6 +57,7 @@
<arg choice="opt">--secretsfile <replaceable>secrets-file</replaceable></arg>
<arg choice="opt">--adns <replaceable>pathname</replaceable></arg>
<arg choice="opt">--nhelpers <replaceable>number</replaceable></arg>
+ <arg choice="opt">--seedbits <replaceable>numbits</replaceable></arg>
<arg choice="opt">--perpeerlog</arg>
<arg choice="opt">--perpeerlogbase <replaceable>dirname</replaceable></arg>
<arg choice="opt">--ipsecdir <replaceable>dirname</replaceable></arg>
@@ -984,6 +985,18 @@
<emphasis remap="I">-1</emphasis> tells pluto to perform the above
calculation. Any other value forces the number to that amount.</para>
+ <para>Pluto uses the NSS crypto library as its random source. Some
+ government Three Letter Agency requires that pluto reads 440 bits
+ from /dev/random and feed this into the NSS RNG before drawing
+ random from the NSS library, despite the NSS library itself
+ already seeding its internal state. As this process can block
+ pluto for an extended time, the default is to not perform this
+ redundant seeding. The <emphasis remap="B">--seedbits</emphasis>
+ option can be used to specify the number of bits that will be
+ pulled from /dev/random and seeded into the NSS RNG. This can
+ also be accomplished by specifying seedbits in the "config setup"
+ section of ipsec.conf. This option should not be used by most people.</para>
+
<para><emphasis remap="B">pluto</emphasis> attempts to create a lockfile
with the name <filename>/var/run/pluto/pluto.pid</filename>. If the
lockfile cannot be created, <emphasis remap="B">pluto</emphasis> exits -
diff -Naur libreswan-3.12-orig/programs/pluto/plutomain.c libreswan-3.12/programs/pluto/plutomain.c
--- libreswan-3.12-orig/programs/pluto/plutomain.c 2015-02-26 21:24:52.012000000 -0600
+++ libreswan-3.12/programs/pluto/plutomain.c 2015-02-26 21:25:39.301000000 -0600
@@ -111,6 +111,7 @@
/* pulled from main for show_setup_plutomain() */
static const struct lsw_conf_options *oco;
static char *coredir;
+static int pluto_nss_seedbits;
static int nhelpers = -1;
libreswan_passert_fail_t libreswan_passert_fail = passert_fail;
@@ -314,6 +315,49 @@
*target = strdup(value);
}
+/*
+ * This function MUST NOT be used for anything else!
+ * It is used to seed the NSS PRNG based on --seedbits pluto argument
+ * or the seedbits= * config setup option in ipsec.conf.
+ * Everything else that needs random MUST use get_rnd_bytes()
+ * This function MUST NOT be changed to use /dev/urandom.
+ */
+static void get_bsi_random(size_t nbytes, unsigned char *buf)
+{
+ size_t ndone;
+ int dev;
+ ssize_t got;
+ const char *device = "/dev/random";
+
+ dev = open(device, 0);
+ if (dev < 0) {
+ loglog(RC_LOG_SERIOUS, "could not open %s (%s)\n",
+ device, strerror(errno));
+ exit_pluto(6);
+ }
+
+ ndone = 0;
+ DBG(DBG_CONTROL,DBG_log("need %d bits random for extra seeding of the NSS PRNG",
+ (int) nbytes * BITS_PER_BYTE));
+
+ while (ndone < nbytes) {
+ got = read(dev, buf + ndone, nbytes - ndone);
+ if (got < 0) {
+ loglog(RC_LOG_SERIOUS,"read error on %s (%s)\n",
+ device, strerror(errno));
+ exit_pluto(6);
+ }
+ if (got == 0) {
+ loglog(RC_LOG_SERIOUS,"EOF on %s!?!\n", device);
+ exit_pluto(6);
+ }
+ ndone += got;
+ }
+ close(dev);
+ DBG(DBG_CONTROL,DBG_log("read %ld bytes from /dev/random for NSS PRNG",
+ nbytes));
+}
+
static void pluto_init_nss(char *confddir)
{
SECStatus nss_init_status;
@@ -328,6 +372,23 @@
libreswan_log("NSS Initialized");
PK11_SetPasswordFunc(getNSSPassword);
}
+
+ /*
+ * This exists purely to make the BSI happy.
+ * We do not infliect this on other users
+ */
+ if (pluto_nss_seedbits != 0) {
+ SECStatus rv;
+ int seedbytes = BYTES_FOR_BITS(pluto_nss_seedbits);
+ unsigned char *buf = alloc_bytes(seedbytes,"TLA seedmix");
+
+ get_bsi_random(seedbytes, buf); /* much TLA, very blocking */
+ rv = PK11_RandomUpdate(buf, seedbytes);
+ libreswan_log("seeded %d bytes into the NSS PRNG", seedbytes);
+ passert(rv == SECSuccess);
+ zero(&buf);
+ pfree(buf);
+ }
}
/* by default the CRL policy is lenient */
@@ -417,6 +478,7 @@
{ "virtual_private\0_", required_argument, NULL, '6' }, /* _ */
{ "virtual-private\0<network_list>", required_argument, NULL, '6' },
{ "nhelpers\0<number>", required_argument, NULL, 'j' },
+ { "seedbits\0<number>", required_argument, NULL, 'c' },
#ifdef HAVE_LABELED_IPSEC
{ "secctx_attr_value\0_", required_argument, NULL, 'w' }, /* _ */
{ "secctx-attr-value\0<number>", required_argument, NULL, 'w' },
@@ -692,6 +754,14 @@
nhelpers = u;
}
continue;
+ case 'c': /* --seedbits */
+ pluto_nss_seedbits = atoi(optarg);
+ if (pluto_nss_seedbits == 0) {
+ printf("pluto: seedbits must be an integer > 0");
+ /* not exit_pluto because we are not initialized yet */
+ exit(6);
+ }
+ continue;
#ifdef HAVE_LABELED_IPSEC
case 'w': /* --secctx-attr-value */
@@ -969,6 +1039,7 @@
}
}
+ pluto_nss_seedbits = cfg->setup.options[KBF_SEEDBITS];
pluto_nat_port =
cfg->setup.options[KBF_NATIKEPORT];
keep_alive = cfg->setup.options[KBF_KEEPALIVE];
@@ -1473,3 +1544,4 @@
whack_log(RC_COMMENT, "secctx-attr-value=<unsupported>");
#endif
}
+
diff -Naur libreswan-3.12-orig/programs/rsasigkey/Makefile libreswan-3.12/programs/rsasigkey/Makefile
--- libreswan-3.12-orig/programs/rsasigkey/Makefile 2014-11-06 21:52:50.000000000 -0600
+++ libreswan-3.12/programs/rsasigkey/Makefile 2015-02-26 21:25:39.301000000 -0600
@@ -16,7 +16,7 @@
include ${LIBRESWANSRCDIR}/Makefile.inc
PROGRAM=rsasigkey
-LIBS=${LIBRESWANLIB} -lgmp
+LIBS=${LSWLOGLIB} ${LIBRESWANLIB} -lgmp
LIBS+=${NSSLIBS}
ifeq ($(USE_FIPSCHECK),true)
diff -Naur libreswan-3.12-orig/programs/rsasigkey/rsasigkey.8 libreswan-3.12/programs/rsasigkey/rsasigkey.8
--- libreswan-3.12-orig/programs/rsasigkey/rsasigkey.8 2014-11-06 21:52:50.000000000 -0600
+++ libreswan-3.12/programs/rsasigkey/rsasigkey.8 2015-02-26 21:25:39.302000000 -0600
@@ -2,12 +2,12 @@
.\" Title: IPSEC_RSASIGKEY
.\" Author: Paul Wouters
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 09/06/2013
+.\" Date: 01/14/2015
.\" Manual: Executable programs
.\" Source: libreswan
.\" Language: English
.\"
-.TH "IPSEC_RSASIGKEY" "8" "09/06/2013" "libreswan" "Executable programs"
+.TH "IPSEC_RSASIGKEY" "8" "01/14/2015" "libreswan" "Executable programs"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -31,9 +31,7 @@
ipsec_rsasigkey \- generate RSA signature key
.SH "SYNOPSIS"
.HP \w'\fBipsec\fR\ 'u
-\fBipsec\fR \fIrsasigkey\fR [\-\-verbose] [\-\-random\ \fIfilename\fR] [\-\-configdir\ \fInssdbdir\fR] [\-\-password\ \fInsspassword\fR] [\-\-hostname\ \fIhostname\fR] [nbits]
-.HP \w'\fBipsec\fR\ 'u
-\fBipsec\fR \fIrsasigkey\fR [\-\-verbose] [\-\-configdir\ \fInssdbdir\fR] [\-\-password\ \fInsspassword\fR] [\-\-hostname\ \fIhostname\fR]
+\fBipsec\fR \fIrsasigkey\fR [\-\-verbose] [\-\-random\ \fIdevice\fR] [\-\-seed\ \fInumbits\fR] [\-\-configdir\ \fInssdbdir\fR] [\-\-password\ \fInsspassword\fR] [\-\-hostname\ \fIhostname\fR] [nbits]
.SH "DESCRIPTION"
.PP
\fIRsasigkey\fR
@@ -50,7 +48,8 @@
.PP
The
\fB\-\-verbose\fR
-option makes\fIrsasigkey\fR
+option makes
+\fIrsasigkey\fR
give a running commentary on standard error\&. By default, it works in silence until it is ready to generate output\&.
.PP
The
@@ -58,9 +57,15 @@
option specifies a source for random bits used to seed the crypto library\*(Aqs RNG\&. The default is
/dev/random
(see
-\fBrandom\fR(4))\&. FreeS/WAN and Openswan without NSS support used this option to specify the random source used to directly create keys\&. Libreswan only uses it to seed the crypto libraries RNG\&. Under Linux with hardware random support, special devices might show up as
+\fBrandom\fR(4))\&. FreeS/WAN and Openswan without NSS support use this option to specify the random source used to directly create keys\&. Libreswan only uses it to seed the NSS crypto libraries RNG\&. Under Linux with hardware random support, special devices might show up as
/dev/*rng*
-devices\&. However, these should never be access directly using this option, as hardware failures could lead to extremely non\-random values (streams of zeroes have been observed in the wild)
+devices\&. However, these should never be accessed directly using this option, as hardware failures could lead to extremely non\-random values (streams of zeroes have been observed in the wild)
+.PP
+The
+\fB\-\-seedbits\fR
+option specifies how many seed bits are pulled from the random device to seed the NSS PRNG\&. The default of 480bit comes from FIPS requirements\&. Seed bits are rounded up to a multiple of 8\&.
+.PP
+The use of a different random device or a reduction of seedbits from the default value is prevented when the system is running in FIPS mode\&.
.PP
The
\fB\-\-configdir\fR
@@ -69,7 +74,8 @@
.PP
The
\fB\-\-password\fR
-option specifies the nss cryptographic module authentication password if the NSS module has been configured to require it\&. A password is required by hardware tokens and also by the internal softotken module when configured to run in FIPS mode\&.
+option specifies the nss cryptographic module authentication password if the NSS module has been configured to require it\&. A password is required by hardware tokens and also by the internal software token module when configured to run in FIPS mode\&. If the argument is
+\fIconfigdir\fR/nsspassword, the password comes from that file; otherwise argument is the password\&.
.PP
The
\fB\-\-hostname\fR
@@ -140,7 +146,7 @@
\fBCoefficient\fR
line gives the Chinese Remainder Theorem coefficient, which is the inverse of
\fIq\fR, mod
-\fIp\fR\&. These additional numbers (which must all be kept as secret as the private exponent) are precomputed aids to rapid signature generation\&. When NSS is used, these values are not available outside the NSS security database (softtoken or hardware token) and are instead filled in with the CKA_ID\&.
+\fIp\fR\&. These additional numbers (which must all be kept as secret as the private exponent) are precomputed aids to rapid signature generation\&. When NSS is used, these values are not available outside the NSS security database (software token or hardware token) and are instead filled in with the CKA_ID\&.
.PP
No attempt is made to break long lines\&.
.PP
diff -Naur libreswan-3.12-orig/programs/rsasigkey/rsasigkey.8.xml libreswan-3.12/programs/rsasigkey/rsasigkey.8.xml
--- libreswan-3.12-orig/programs/rsasigkey/rsasigkey.8.xml 2014-11-06 21:52:50.000000000 -0600
+++ libreswan-3.12/programs/rsasigkey/rsasigkey.8.xml 2015-02-26 21:25:39.302000000 -0600
@@ -23,20 +23,13 @@
<command>ipsec</command>
<arg choice='plain'><replaceable>rsasigkey</replaceable></arg>
<arg choice='opt'>--verbose </arg>
- <arg choice='opt'>--random <replaceable>filename</replaceable></arg>
+ <arg choice='opt'>--random <replaceable>device</replaceable></arg>
+ <arg choice='opt'>--seed <replaceable>numbits</replaceable></arg>
<arg choice='opt'>--configdir <replaceable>nssdbdir</replaceable></arg>
<arg choice='opt'>--password <replaceable>nsspassword</replaceable></arg>
<arg choice='opt'>--hostname <replaceable>hostname</replaceable></arg>
<arg choice='opt'>nbits </arg>
</cmdsynopsis>
-<cmdsynopsis>
- <command>ipsec</command>
- <arg choice='plain'><replaceable>rsasigkey</replaceable></arg>
- <arg choice='opt'>--verbose </arg>
- <arg choice='opt'>--configdir <replaceable>nssdbdir</replaceable></arg>
- <arg choice='opt'>--password <replaceable>nsspassword</replaceable></arg>
- <arg choice='opt'>--hostname <replaceable>hostname</replaceable></arg>
-</cmdsynopsis>
</refsynopsisdiv>
@@ -61,14 +54,22 @@
source for random bits used to seed the crypto library's
RNG. The default is <filename>/dev/random</filename> (see
<citerefentry><refentrytitle>random</refentrytitle><manvolnum>4</manvolnum></citerefentry>).
-FreeS/WAN and Openswan without NSS support used this option to specify
+FreeS/WAN and Openswan without NSS support use this option to specify
the random source used to directly create keys. Libreswan only uses
-it to seed the crypto libraries RNG. Under Linux with hardware random
+it to seed the NSS crypto libraries RNG. Under Linux with hardware random
support, special devices might show up as <filename>/dev/*rng*</filename>
-devices. However, these should never be access directly using this option,
+devices. However, these should never be accessed directly using this option,
as hardware failures could lead to extremely non-random values (streams
of zeroes have been observed in the wild) </para>
+<para>The <option>--seedbits</option> option specifies how many seed bits are pulled from
+the random device to seed the NSS PRNG. The default of 480bit comes from FIPS requirements.
+Seed bits are rounded up to a multiple of 8.
+</para>
+
+<para>The use of a different random device or a reduction of seedbits from the default value is
+prevented when the system is running in FIPS mode.</para>
+
<para>The <option>--configdir</option> option specifies the nss configuration directory to use.
This is the directory where the NSS certificate, key and security modules databases reside. The
default value is <filename>/etc/ipsec.d</filename>.</para>
diff -Naur libreswan-3.12-orig/programs/rsasigkey/rsasigkey.c libreswan-3.12/programs/rsasigkey/rsasigkey.c
--- libreswan-3.12-orig/programs/rsasigkey/rsasigkey.c 2014-11-06 21:52:50.000000000 -0600
+++ libreswan-3.12/programs/rsasigkey/rsasigkey.c 2015-02-26 21:25:39.303000000 -0600
@@ -4,7 +4,7 @@
* Copyright (C) 2003-2008 Michael C Richardson <mcr@xelerance.com>
* Copyright (C) 2003-2009 Paul Wouters <paul@xelerance.com>
* Copyright (C) 2009 Avesh Agarwal <avagarwa@redhat.com>
- * Copyright (C) 2012-2013 Paul Wouters <paul@libreswan.org>
+ * Copyright (C) 2012-2015 Paul Wouters <paul@libreswan.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -64,26 +64,22 @@
#define MIN_KEYBIT 2192
#ifndef DEVICE
-/* To the openwrt people: Do not change /dev/random to /dev/urandom. The
- * /dev/random device is ONLY used for generating long term keys, which
- * should NEVER be done with /dev/urandom. If people use X.509, PSK or
- * even raw RSA keys generated on other systems, changing this will have
- * 0 effect. It's better to fail or bail out of generating a key, then
- * generate a bad one.
- */
# define DEVICE "/dev/random"
#endif
#ifndef MAXBITS
# define MAXBITS 20000
#endif
+#define DEFAULT_SEED_BITS 60 /* 480 bits of random seed */
+
#define E 3 /* standard public exponent */
/* #define F4 65537 */ /* possible future public exponent, Fermat's 4th number */
#define NSSDIR "/etc/ipsec.d"
+char *progname;
char usage[] =
- "rsasigkey [--verbose] [--random <device>] [--configdir <dir>] [--password <password>] [--hostname host] [<nbits>]";
+ "rsasigkey [--verbose] [--random <device>] [--configdir <dir>] [--password <password>] [--hostname host] [--seedbits bits] [<keybits>]";
struct option opts[] = {
{ "rounds", 1, NULL, 'p', }, /* obsoleted */
{ "noopt", 0, NULL, 'n', }, /* obsoleted */
@@ -96,6 +92,7 @@
{ "configdir", 1, NULL, 'c' },
{ "configdir2", 1, NULL, 'd' }, /* nss tools use -d */
{ "password", 1, NULL, 'P' },
+ { "seedbits", 1, NULL, 's' },
{ 0, 0, NULL, 0, }
};
int verbose = 0; /* narrate the action? */
@@ -106,14 +103,13 @@
char me[] = "ipsec rsasigkey"; /* for messages */
/* forwards */
-void rsasigkey(int nbits, char *configdir, char *password);
+void rsasigkey(int nbits, int seedbits, char *configdir, char *password);
void getrandom(size_t nbytes, unsigned char *buf);
static const unsigned char *bundle(int e, mpz_t n, size_t *sizep);
static const char *conv(const unsigned char *bits, size_t nbytes, int format);
static const char *hexout(mpz_t var);
void report(char *msg);
-#define RAND_BUF_SIZE 60
/* getModulus - returns modulus of the RSA public key */
static SECItem *getModulus(SECKEYPublicKey *pk)
@@ -163,15 +159,17 @@
}
/* UpdateRNG - Updates NSS's PRNG with user generated entropy. */
-static void UpdateNSS_RNG(void)
+static void UpdateNSS_RNG(int seedbits)
{
SECStatus rv;
- unsigned char buf[RAND_BUF_SIZE];
+ int seedbytes = BYTES_FOR_BITS(seedbits);
+ unsigned char *buf = alloc_bytes(seedbytes,"TLA seedmix");
- getrandom(RAND_BUF_SIZE, buf);
- rv = PK11_RandomUpdate(buf, sizeof buf);
+ getrandom(seedbytes, buf);
+ rv = PK11_RandomUpdate(buf, seedbytes);
assert(rv == SECSuccess);
zero(&buf);
+ pfree(buf);
}
/* Returns the password passed in in the text file.
@@ -303,6 +301,7 @@
{
int opt;
int nbits = 0;
+ int seedbits = DEFAULT_SEED_BITS;
char *configdir = NULL; /* where the NSS databases reside */
char *password = NULL; /* password for token authentication */
@@ -344,6 +343,16 @@
case 'P': /* token authentication password */
password = optarg;
break;
+ case 's': /* seed bits */
+ seedbits = atoi(optarg);
+ if (PK11_IsFIPS()) {
+ if (seedbits < DEFAULT_SEED_BITS) {
+ fprintf(stderr, "%s: FIPS mode does not allow < %d seed bits\n",
+ me, DEFAULT_SEED_BITS);
+ exit(1);
+ }
+ }
+ break;
case '?':
default:
printf("Usage:\t%s\n", usage);
@@ -393,7 +402,7 @@
exit(1);
}
- rsasigkey(nbits, configdir, password);
+ rsasigkey(nbits, seedbits, configdir, password);
exit(0);
}
@@ -405,7 +414,7 @@
* real speed advantages.
* See also: https://www.imperialviolet.org/2012/03/16/rsae.html
*/
-void rsasigkey(int nbits, char *configdir, char *password)
+void rsasigkey(int nbits, int seedbits, char *configdir, char *password)
{
SECStatus rv;
PK11RSAGenParams rsaparams = { nbits, (long) E };
@@ -483,7 +492,7 @@
#endif /* 0 */
/* Do some random-number initialization. */
- UpdateNSS_RNG();
+ UpdateNSS_RNG(seedbits);
/* Log in to the token */
if (password) {
rv = PK11_Authenticate(slot, PR_FALSE, &pwdata);
@@ -553,9 +562,7 @@
/*
- getrandom - get some random bytes from /dev/random (or wherever)
*/
-void getrandom(nbytes, buf)
-size_t nbytes;
-unsigned char *buf; /* known to be big enough */
+void getrandom(size_t nbytes, unsigned char *buf)
{
size_t ndone;
int dev;
@@ -570,8 +577,8 @@
ndone = 0;
if (verbose) {
- fprintf(stderr, "getting %d random bytes from %s...\n",
- (int) nbytes,
+ fprintf(stderr, "getting %d random seed bytes for NSS from %s...\n",
+ (int) nbytes * BITS_PER_BYTE,
device);
}
while (ndone < nbytes) {
@@ -683,3 +690,12 @@
fprintf(stderr, "%s\n", msg);
}
+/* exit_tool() is needed if the library was compiled with DEBUG, even if we are not.
+ * The odd-looking parens are to prevent macro expansion:
+ * lswlog.h without DEBUG define a macro exit_tool().
+ */
+void (exit_tool)(int x)
+{
+ exit(x);
+}
+