Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 25 Apr 1999 19:45:54 -0700
From:      David Honig <honig@sprynet.com>
To:        freebsd-doc@freebsd.org
Subject:   How To Verify your IPsec functionality
Message-ID:  <3723D362.851D7619@sprynet.com>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------ABFFCDE9F2B656406114F78D
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit


I've attached an HTML doc describing how to use tcpdump
and an entropy measurment to verify that IPsec is working.



--------------ABFFCDE9F2B656406114F78D
Content-Type: text/html; charset=us-ascii;
 name="ipsecmust.html"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="ipsecmust.html"

<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
   <meta name="GENERATOR" content="Mozilla/4.5 [en] (X11; U; FreeBSD 3.0-RELEASE i386) [Netscape]">
</head>
<body text="#000000" bgcolor="#FFCCCC" link="#0000EE" vlink="#551A8B" alink="#FF0000">

<center>
<h1>
Independent Verification of IPsec Functionality Under FreeBSD 3.0
<hr WIDTH="100%"></h1></center>

<center><i>You&nbsp; installed IPsec and it seems to be working.&nbsp;
How do you know?&nbsp; I describe a method for experimentally verifying
that IPsec is working</i></center>

<p><br>
<h2>
The Problem</h2>
First, let's assume you have <a href="#Installing IPsec">installed <i>IPsec</i></a>.&nbsp;
How do you know its <a href="#Caveat">working</a>?&nbsp; Sure, your connection
won't work if its misconfigured, and it will work when you finally get
it right.&nbsp; <i>Netstat</i> will list it.&nbsp; But can you independently
confirm it?
<h2>
The Solution</h2>
First, some crypto-relevent info theory:
<ol>
<li>
Encrypted data is uniformly distributed, ie, has maximal entropy per symbol.</li>

<li>
Raw, uncompressed data is typically redundant, i.e., has sub-maximal entropy.</li>
</ol>
Suppose you could measure the entropy of the data to- and from-&nbsp; your
network interface.&nbsp; Then you could see the difference between unencrypted
data and encrypted data.&nbsp; This would be true even if some of the data
in "encrypted mode" was not encrypted ---as the outermost IP header must
be, if the packet is to be routable.
<h4>
<a NAME="MUST"></a>MUST</h4>
Ueli Maurer's "Universal Statistical Test for Random Bit Generators" ("MUST")
quickly measures the entropy of a sample.&nbsp; It uses a compression-like
algorithm.&nbsp; <a href="#Maurer's Universal Statistical Test">The code&nbsp;
is given below for a variant which measures successive (~quarter megabyte)
chunks of a file</a>.
<h4>
<a NAME="Tcpdump"></a>Tcpdump</h4>
We also need a way to capture the raw network data.&nbsp; A program called
"<i>tcpdump</i>" lets you do this, if you have enabled the <i>Berkeley
Packet Filter</i> interface in your <a href="#usr/src/sys/i386/conf/KERNELNAME">kernel's
config file</a>.
<p>The command
<blockquote><b>tcpdump</b> <b>-c</b> 4000 <b>-s</b> 10000 <b>-w</b> <i>dumpfile.bin</i></blockquote>
will capture 4000 raw packets to <i>dumpfile.bin</i>.&nbsp; Up to 10,000
bytes per packet will be captured in this example.
<br>&nbsp;
<br>&nbsp;
<h2>
The Experiment</h2>
Here's the experiment.&nbsp; Open a window to an IPsec host and another
window to an insecure host.
<p>Now start <a href="#Tcpdump">capturing packets</a>.
<p>In the "secure" window, run the unix command "yes", which will stream
the "y" character.&nbsp;&nbsp;&nbsp; After a while, stop this.&nbsp; Switch
to the insecure window, and repeat.&nbsp; After a while, stop.
<p>Now run <a href="#Maurer's Universal Statistical Test">MUST</a> on the
captured packets.&nbsp; You should see something like the the following.&nbsp;
The important thing to note is that the secure connection has 93% (6.7)
of the expected value (7.18), and the "normal" connection has 29% (2.1)
of the expected value.
<br>&nbsp;
<blockquote><tt>% tcpdump -c 4000 -s 10000 -w ipsecdemo.bin</tt>
<br><tt>% uliscan ipsecdemo.bin</tt></blockquote>

<blockquote><tt>Uliscan 21 Dec 98</tt>
<br><tt>L=8 256 258560</tt>
<br><tt>Measuring file ipsecdemo.bin</tt>
<br><tt>Init done</tt>
<br><tt>Expected value for L=8 is 7.1836656</tt>
<br><tt>6.9396 <b>--------------------------------------------------------</b></tt>
<br><tt>6.6177 -----------------------------------------------------</tt>
<br><tt>6.4100 ---------------------------------------------------</tt>
<br><tt>2.1101 -----------------</tt>
<br><tt>2.0838 -----------------</tt>
<br><tt>2.0983 -----------------</tt></blockquote>

<h2>
<a NAME="Caveat"></a>Caveat</h2>
This experiment shows that IPsec <i>does</i> seem to be distributing the
payload data <i>uniformly</i>, as encryption should.&nbsp;&nbsp; However,&nbsp;
the experiment described here <i>can not </i>detect many possible flaws
in a system (none of which do I have any evidence for).&nbsp; These include
poor key generation or exchange, data or keys being visible to others,
use of weak algorithms, kernel subversion, etc.&nbsp;&nbsp;&nbsp; Study
the source; know the code.
<h2>
<a NAME="IPsec"></a>IPsec -Definition</h2>
Internet Protocol security extensions to IP v 4; required for IP v6.&nbsp;
A protocol for negotiating encryption and authentication at the IP (host-to-host)
level.&nbsp; SSL secures only one application socket; SSH secures only
a login; PGP secures only a specified file or message.&nbsp; IPsec encrypts
everything between two hosts.
<h2>
<a NAME="Installing IPsec"></a>Installing IPsec</h2>
Starting from the BSD 3.0 stable release,
<ol>
<li>
install IPsec v0.04, rebuild, reinstall</li>

<li>
run the administration tools (e.g, <i>ipsecadm</i>) and distribute keys
(or use <i>Photuris</i> for key exchange)</li>

<li>
set the routes (<i>rt</i>) up appropriately</li>
</ol>
You may want to make an "ipsec_setup" script containing the <i>ipsecadm</i>
and <i>rt</i> commands which establish your IPsec tunnel.&nbsp; You can
run this script automatically at boottime from your <i>/etc/rc.local</i>&nbsp;&nbsp;
The ipsec_setup script will have to contain at least two <i>ipsecadm</i>
commands and one <i>rt</i> command to be useful.
<br>&nbsp;
<br>&nbsp;
<h2>
/<a NAME="usr/src/sys/i386/conf/KERNELNAME"></a>usr/src/sys/i386/conf/KERNELNAME</h2>
This needs to be present in the kernel config file in order to run IPsec.&nbsp;
After adding it, run <i>config</i>, etc. and rebuild and reinstall.
<p><tt>#&nbsp; The `bpfilter' pseudo-device enables the Berkeley Packet
Filter.&nbsp; Be</tt>
<br><tt>#&nbsp; aware of the legal and administrative consequences of enabling
this</tt>
<br><tt>#&nbsp; option. Heh heh. The number of devices determines the maximum
number of</tt>
<br><tt>#&nbsp; simultaneous BPF clients programs runnable.</tt>
<p><tt><b>pseudo-device&nbsp;&nbsp; bpfilter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
2&nbsp;</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #Berkeley packet filter ELSINORE</tt>
<p><b><tt># IPSEC</tt></b>
<br><b><tt>options IPSEC</tt></b>
<br><b><tt>options "MD5"</tt></b>
<br><b><tt>pseudo-device&nbsp;&nbsp; enc&nbsp;&nbsp;&nbsp;&nbsp; 1</tt></b>
<br>&nbsp;
<br>&nbsp;
<h2>
<a NAME="Maurer's Universal Statistical Test"></a>Maurer's Universal Statistical
Test (for block size=8 bits)</h2>

<p><br><tt><font size=-1>/*</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp; ULISCAN.c&nbsp;&nbsp; ---blocksize of
8</font></tt>
<p><tt><font size=-1>1 Oct 98</font></tt>
<br><tt><font size=-1>1 Dec 98</font></tt>
<br><tt><font size=-1>21 Dec 98&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uliscan.c
derived from ueli8.c</font></tt>
<p><tt><font size=-1>This version has // comments removed for Sun cc</font></tt>
<p><tt><font size=-1>This implements Ueli M Maurer's</font></tt>
<br><tt><font size=-1>"Universal Statistical Test for Random Bit Generators"</font></tt>
<br><tt><font size=-1>using L=8</font></tt>
<p><tt><font size=-1>Accepts a filename on the command line;</font></tt>
<br><tt><font size=-1>writes its results, with other info, to stdout.</font></tt>
<p><tt><font size=-1>Handles input file exhaustion gracefully.</font></tt>
<p><tt><font size=-1>Ref: J. Cryptology v 5 no 2, 1992 pp 89-105</font></tt>
<br><tt><font size=-1>also on the web somewhere, which is where I found
it.</font></tt>
<p><tt><font size=-1>-David Honig</font></tt>
<br><tt><font size=-1>honig@sprynet.com</font></tt>
<p><tt><font size=-1>Usage:</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ULISCAN
filename</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outputs
to stdout</font></tt>
<br><tt><font size=-1>*/</font></tt>
<p><tt><font size=-1>#define L 8</font></tt>
<br><tt><font size=-1>#define V (1&lt;&lt;L)</font></tt>
<br><tt><font size=-1>#define Q (10*V)</font></tt>
<br><tt><font size=-1>#define K (100&nbsp;&nbsp; *Q)</font></tt>
<br><tt><font size=-1>#define MAXSAMP (Q + K)</font></tt>
<p><tt><font size=-1>#include &lt;stdio.h></font></tt>
<br><tt><font size=-1>#include &lt;math.h></font></tt>
<p><tt><font size=-1>int main(&nbsp; argc, argv )</font></tt>
<br><tt><font size=-1>int argc;</font></tt>
<br><tt><font size=-1>char **argv;</font></tt>
<br><tt><font size=-1>{</font></tt>
<br><tt><font size=-1>FILE *fptr;</font></tt>
<br><tt><font size=-1>int i,j;</font></tt>
<br><tt><font size=-1>int b, c;</font></tt>
<br><tt><font size=-1>int table[V];</font></tt>
<br><tt><font size=-1>double sum=0.0;</font></tt>
<br><tt><font size=-1>int iproduct=1;</font></tt>
<br><tt><font size=-1>int run;</font></tt>
<p><tt><font size=-1>extern double&nbsp;&nbsp; log(/* double x */);</font></tt>
<p><tt><font size=-1>printf("Uliscan 21 Dec 98 \nL=%d %d %d \n", L, V,
MAXSAMP);</font></tt>
<br><tt><font size=-1>if (argc &lt;2)</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {printf("Usage:
Uliscan filename\n"); exit(-1); }</font></tt>
<br><tt><font size=-1>else</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Measuring
file %s\n", argv[1]);</font></tt>
<br>&nbsp;
<p><tt><font size=-1>fptr=fopen(argv[1],"rb");</font></tt>
<br><tt><font size=-1>if (fptr == NULL) {printf("Can't find %s\n", argv[1]);
exit(-1); }</font></tt>
<br>&nbsp;
<p><tt><font size=-1>for (i=0; i&lt;V; i++) table[i]=0;</font></tt>
<br><tt><font size=-1>for (i=0; i&lt;Q; i++)&nbsp;&nbsp;&nbsp;&nbsp; {</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b=&nbsp;
fgetc(fptr);</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table[
b ]=i;</font></tt>
<br><tt><font size=-1>}</font></tt>
<p><tt><font size=-1>printf("Init done\n");</font></tt>
<p><tt><font size=-1>printf("Expected value for L=8 is&nbsp; 7.1836656\n");</font></tt>
<p><tt><font size=-1>run=1;</font></tt>
<br><tt><font size=-1>&nbsp;while (run)</font></tt>
<br><tt><font size=-1>&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum=0.0;</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; iproduct=1;</font></tt>
<p><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (run)</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
for (i=Q;&nbsp; run &amp;&amp; i&lt;Q+K; i++)</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
{j=i;</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
b=fgetc(fptr); if (b&lt;0) run=0;</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (run) {</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (table[b] > j) j += K;</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
sum += log( (double) ( j-table[b] ) ) ;</font></tt>
<p><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
table[ b ]=i;</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></tt>
<p><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!run)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
printf("Premature end of file; read %d blocks.\n", i-Q);</font></tt>
<p><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum = (sum/(
(double) (i-Q) ) ) /&nbsp; log(2.0);</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%4.4f
", sum);</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i=0;
i&lt; (int) (sum*8.0 + 0.50 ) ; i++)</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
printf("-");</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\n");</font></tt>
<p><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* refill
initial table */</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (0)
for (i=0; i&lt;Q; i++)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
b=&nbsp; fgetc(fptr);</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (b&lt;0) run=0;</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
else table[ b ]=i;</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}</font></tt>
<br><tt><font size=-1>&nbsp;&nbsp; }</font></tt>
<br><tt><font size=-1>}</font></tt>
<p>
<hr WIDTH="100%">
<br><a href="mailto:honig@sprynet.com">honig@sprynet.com</a>
<br>25 Apr 99
<br>&nbsp;
<br>&nbsp;
</body>
</html>

--------------ABFFCDE9F2B656406114F78D--



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-doc" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3723D362.851D7619>