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 installed IPsec and it seems to be working. How do you know? 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>. How do you know its <a href="#Caveat">working</a>? Sure, your connection won't work if its misconfigured, and it will work when you finally get it right. <i>Netstat</i> will list it. 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- your network interface. Then you could see the difference between unencrypted data and encrypted data. 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. It uses a compression-like algorithm. <a href="#Maurer's Universal Statistical Test">The code 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. 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>. Up to 10,000 bytes per packet will be captured in this example. <br> <br> <h2> The Experiment</h2> Here's the experiment. 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. After a while, stop this. Switch to the insecure window, and repeat. After a while, stop. <p>Now run <a href="#Maurer's Universal Statistical Test">MUST</a> on the captured packets. You should see something like the the following. 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> <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. However, the experiment described here <i>can not </i>detect many possible flaws in a system (none of which do I have any evidence for). These include poor key generation or exchange, data or keys being visible to others, use of weak algorithms, kernel subversion, etc. 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. A protocol for negotiating encryption and authentication at the IP (host-to-host) level. SSL secures only one application socket; SSH secures only a login; PGP secures only a specified file or message. 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. You can run this script automatically at boottime from your <i>/etc/rc.local</i> 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> <br> <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. After adding it, run <i>config</i>, etc. and rebuild and reinstall. <p><tt># The `bpfilter' pseudo-device enables the Berkeley Packet Filter. Be</tt> <br><tt># aware of the legal and administrative consequences of enabling this</tt> <br><tt># option. Heh heh. The number of devices determines the maximum number of</tt> <br><tt># simultaneous BPF clients programs runnable.</tt> <p><tt><b>pseudo-device bpfilter 2 </b> #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 enc 1</tt></b> <br> <br> <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> ULISCAN.c ---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 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> ULISCAN filename</font></tt> <br><tt><font size=-1> 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<<L)</font></tt> <br><tt><font size=-1>#define Q (10*V)</font></tt> <br><tt><font size=-1>#define K (100 *Q)</font></tt> <br><tt><font size=-1>#define MAXSAMP (Q + K)</font></tt> <p><tt><font size=-1>#include <stdio.h></font></tt> <br><tt><font size=-1>#include <math.h></font></tt> <p><tt><font size=-1>int main( 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 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 <2)</font></tt> <br><tt><font size=-1> {printf("Usage: Uliscan filename\n"); exit(-1); }</font></tt> <br><tt><font size=-1>else</font></tt> <br><tt><font size=-1> printf("Measuring file %s\n", argv[1]);</font></tt> <br> <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> <p><tt><font size=-1>for (i=0; i<V; i++) table[i]=0;</font></tt> <br><tt><font size=-1>for (i=0; i<Q; i++) {</font></tt> <br><tt><font size=-1> b= fgetc(fptr);</font></tt> <br><tt><font size=-1> 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 7.1836656\n");</font></tt> <p><tt><font size=-1>run=1;</font></tt> <br><tt><font size=-1> while (run)</font></tt> <br><tt><font size=-1> { sum=0.0;</font></tt> <br><tt><font size=-1> iproduct=1;</font></tt> <p><tt><font size=-1> if (run)</font></tt> <br><tt><font size=-1> for (i=Q; run && i<Q+K; i++)</font></tt> <br><tt><font size=-1> {j=i;</font></tt> <br><tt><font size=-1> b=fgetc(fptr); if (b<0) run=0;</font></tt> <br><tt><font size=-1> if (run) {</font></tt> <br><tt><font size=-1> if (table[b] > j) j += K;</font></tt> <br><tt><font size=-1> sum += log( (double) ( j-table[b] ) ) ;</font></tt> <p><tt><font size=-1> table[ b ]=i;</font></tt> <br><tt><font size=-1> }</font></tt> <br><tt><font size=-1> }</font></tt> <p><tt><font size=-1> if (!run) printf("Premature end of file; read %d blocks.\n", i-Q);</font></tt> <p><tt><font size=-1> sum = (sum/( (double) (i-Q) ) ) / log(2.0);</font></tt> <br><tt><font size=-1> printf("%4.4f ", sum);</font></tt> <br><tt><font size=-1> for (i=0; i< (int) (sum*8.0 + 0.50 ) ; i++)</font></tt> <br><tt><font size=-1> printf("-");</font></tt> <br><tt><font size=-1> printf("\n");</font></tt> <p><tt><font size=-1> /* refill initial table */</font></tt> <br><tt><font size=-1> if (0) for (i=0; i<Q; i++) {</font></tt> <br><tt><font size=-1> b= fgetc(fptr);</font></tt> <br><tt><font size=-1> if (b<0) run=0;</font></tt> <br><tt><font size=-1> else table[ b ]=i;</font></tt> <br><tt><font size=-1> }</font></tt> <br><tt><font size=-1> }</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> <br> </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>