5df509eaa2
always work and is no use anyway
345 lines
9.4 KiB
XML
345 lines
9.4 KiB
XML
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V4.5-Based Extension//EN"
|
|
"../../../share/xml/freebsd45.dtd">
|
|
|
|
<!--
|
|
The FreeBSD Documentation Project
|
|
|
|
$FreeBSD$
|
|
-->
|
|
|
|
<article lang='en'>
|
|
<articleinfo>
|
|
<title>Independent Verification of IPsec Functionality in FreeBSD</title>
|
|
|
|
<author>
|
|
<firstname>David</firstname>
|
|
<surname>Honig</surname>
|
|
|
|
<affiliation>
|
|
<address><email>honig@sprynet.com</email></address>
|
|
</affiliation>
|
|
</author>
|
|
|
|
<pubdate>3 May 1999</pubdate>
|
|
|
|
<legalnotice id="trademarks" role="trademarks">
|
|
&tm-attrib.freebsd;
|
|
&tm-attrib.opengroup;
|
|
&tm-attrib.general;
|
|
</legalnotice>
|
|
|
|
<releaseinfo>$FreeBSD$</releaseinfo>
|
|
|
|
<abstract>
|
|
<para>You installed IPsec and it seems to be working. How do you
|
|
know? I describe a method for experimentally verifying that IPsec is
|
|
working.</para>
|
|
</abstract>
|
|
</articleinfo>
|
|
|
|
<sect1 id="problem">
|
|
<title>The Problem</title>
|
|
|
|
<para>First, lets assume you have <link linkend="ipsec-install">
|
|
installed <emphasis>IPsec</emphasis></link>. How do you know
|
|
it is <link linkend="caveat">working</link>? Sure, your
|
|
connection will not work if it is misconfigured, and it will work
|
|
when you finally get it right. &man.netstat.1; will list it.
|
|
But can you independently confirm it?</para>
|
|
</sect1>
|
|
|
|
<sect1 id="solution">
|
|
<title>The Solution</title>
|
|
|
|
<para>First, some crypto-relevant info theory:</para>
|
|
|
|
<orderedlist>
|
|
<listitem>
|
|
<para>Encrypted data is uniformly distributed, i.e., has maximal
|
|
entropy per symbol;</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Raw, uncompressed data is typically redundant, i.e., has
|
|
sub-maximal entropy.</para>
|
|
</listitem>
|
|
</orderedlist>
|
|
|
|
<para>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 <quote>encrypted mode</quote> was
|
|
not encrypted---as the outermost IP header must be if the
|
|
packet is to be routable.</para>
|
|
|
|
<sect2 id="MUST">
|
|
<title>MUST</title>
|
|
|
|
<para>Ueli Maurer's <quote>Universal Statistical Test for Random
|
|
Bit Generators</quote>(<ulink
|
|
url="http://www.geocities.com/SiliconValley/Code/4704/universal.pdf">
|
|
<acronym>MUST</acronym></ulink>) quickly measures the entropy
|
|
of a sample. It uses a compression-like algorithm. <link
|
|
linkend="code">The code is given below</link> for a variant
|
|
which measures successive (~quarter megabyte) chunks of a
|
|
file.</para>
|
|
</sect2>
|
|
|
|
<sect2 id="tcpdump">
|
|
<title>Tcpdump</title>
|
|
|
|
<para>We also need a way to capture the raw network data. A
|
|
program called &man.tcpdump.1; lets you do this, if you have
|
|
enabled the <emphasis>Berkeley Packet Filter</emphasis>
|
|
interface in your <link linkend="kernel">kernel's config
|
|
file</link>.</para>
|
|
|
|
<para>The command:</para>
|
|
|
|
<screen><userinput><command>tcpdump</command> -c 4000 -s 10000 -w <replaceable>dumpfile.bin</replaceable></userinput></screen>
|
|
|
|
<para>will capture 4000 raw packets to
|
|
<replaceable>dumpfile.bin</replaceable>. Up to 10,000 bytes per
|
|
packet will be captured in this example.</para>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 id="experiment">
|
|
<title>The Experiment</title>
|
|
|
|
<para>Here is the experiment:</para>
|
|
|
|
<procedure>
|
|
<step>
|
|
<para>Open a window to an IPsec host and another window to an
|
|
insecure host.</para>
|
|
</step>
|
|
|
|
<step>
|
|
<para>Now start <link linkend="tcpdump">capturing
|
|
packets</link>.</para>
|
|
</step>
|
|
|
|
<step>
|
|
<para>In the <quote>secure</quote> window, run the &unix;
|
|
command &man.yes.1;, which will stream the <literal>y</literal>
|
|
character. After a while, stop this. Switch to the
|
|
insecure window, and repeat. After a while, stop.</para>
|
|
</step>
|
|
|
|
<step>
|
|
<para>Now run <link linkend="code">MUST</link> on the
|
|
captured packets. You should see something like the
|
|
following. The important thing to note is that the secure
|
|
connection has 93% (6.7) of the expected value (7.18), and
|
|
the <quote>normal</quote> connection has 29% (2.1) of the
|
|
expected value.</para>
|
|
|
|
<screen>&prompt.user; <userinput>tcpdump -c 4000 -s 10000 -w <replaceable>ipsecdemo.bin</replaceable></userinput>
|
|
&prompt.user; <userinput>uliscan <replaceable>ipsecdemo.bin</replaceable></userinput>
|
|
|
|
Uliscan 21 Dec 98
|
|
L=8 256 258560
|
|
Measuring file ipsecdemo.bin
|
|
Init done
|
|
Expected value for L=8 is 7.1836656
|
|
6.9396 --------------------------------------------------------
|
|
6.6177 -----------------------------------------------------
|
|
6.4100 ---------------------------------------------------
|
|
2.1101 -----------------
|
|
2.0838 -----------------
|
|
2.0983 -----------------</screen>
|
|
</step>
|
|
</procedure>
|
|
</sect1>
|
|
|
|
<sect1 id="caveat">
|
|
<title>Caveat</title>
|
|
|
|
<para>This experiment shows that IPsec <emphasis>does</emphasis>
|
|
seem to be distributing the payload data
|
|
<emphasis>uniformly</emphasis>, as encryption should. However,
|
|
the experiment described here <emphasis>cannot</emphasis>
|
|
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.</para>
|
|
</sect1>
|
|
|
|
<sect1 id="IPsec">
|
|
<title>IPsec---Definition</title>
|
|
|
|
<para>Internet Protocol security extensions to IPv4; required for
|
|
IPv6. A protocol for negotiating encryption and authentication
|
|
at the IP (host-to-host) level. SSL secures only one application
|
|
socket; <application>SSH</application> secures only a login;
|
|
<application>PGP</application> secures only a specified file or
|
|
message. IPsec encrypts everything between two hosts.</para>
|
|
</sect1>
|
|
|
|
<sect1 id="ipsec-install">
|
|
<title>Installing IPsec</title>
|
|
|
|
<para>Most of the modern versions of FreeBSD have IPsec support
|
|
in their base source. So you will need to include the
|
|
<option>IPSEC</option> option in your kernel config and, after
|
|
kernel rebuild and reinstall, configure IPsec connections using
|
|
&man.setkey.8; command.</para>
|
|
|
|
<para>A comprehensive guide on running IPsec on FreeBSD is
|
|
provided in <ulink
|
|
url="&url.books.handbook;/ipsec.html">FreeBSD
|
|
Handbook</ulink>.</para>
|
|
</sect1>
|
|
|
|
<sect1 id="kernel">
|
|
<title>src/sys/i386/conf/KERNELNAME</title>
|
|
|
|
<para>This needs to be present in the kernel config file in order
|
|
to capture network data with &man.tcpdump.1;. Be sure
|
|
to run &man.config.8; after adding this, and rebuild and
|
|
reinstall.</para>
|
|
|
|
<programlisting>device bpf</programlisting>
|
|
</sect1>
|
|
|
|
<sect1 id="code">
|
|
<title>Maurer's Universal Statistical Test (for block size=8
|
|
bits)</title>
|
|
|
|
<para>You can find the same code at <ulink
|
|
url="http://www.geocities.com/SiliconValley/Code/4704/uliscanc.txt">
|
|
this link</ulink>.</para>
|
|
|
|
<programlisting>/*
|
|
ULISCAN.c ---blocksize of 8
|
|
|
|
1 Oct 98
|
|
1 Dec 98
|
|
21 Dec 98 uliscan.c derived from ueli8.c
|
|
|
|
This version has // comments removed for Sun cc
|
|
|
|
This implements Ueli M Maurer's "Universal Statistical Test for Random
|
|
Bit Generators" using L=8
|
|
|
|
Accepts a filename on the command line; writes its results, with other
|
|
info, to stdout.
|
|
|
|
Handles input file exhaustion gracefully.
|
|
|
|
Ref: J. Cryptology v 5 no 2, 1992 pp 89-105
|
|
also on the web somewhere, which is where I found it.
|
|
|
|
-David Honig
|
|
honig@sprynet.com
|
|
|
|
Usage:
|
|
ULISCAN filename
|
|
outputs to stdout
|
|
*/
|
|
|
|
#define L 8
|
|
#define V (1<<L)
|
|
#define Q (10*V)
|
|
#define K (100 *Q)
|
|
#define MAXSAMP (Q + K)
|
|
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
|
|
int main(argc, argv)
|
|
int argc;
|
|
char **argv;
|
|
{
|
|
FILE *fptr;
|
|
int i,j;
|
|
int b, c;
|
|
int table[V];
|
|
double sum = 0.0;
|
|
int iproduct = 1;
|
|
int run;
|
|
|
|
extern double log(/* double x */);
|
|
|
|
printf("Uliscan 21 Dec 98 \nL=%d %d %d \n", L, V, MAXSAMP);
|
|
|
|
if (argc < 2) {
|
|
printf("Usage: Uliscan filename\n");
|
|
exit(-1);
|
|
} else {
|
|
printf("Measuring file %s\n", argv[1]);
|
|
}
|
|
|
|
fptr = fopen(argv[1],"rb");
|
|
|
|
if (fptr == NULL) {
|
|
printf("Can't find %s\n", argv[1]);
|
|
exit(-1);
|
|
}
|
|
|
|
for (i = 0; i < V; i++) {
|
|
table[i] = 0;
|
|
}
|
|
|
|
for (i = 0; i < Q; i++) {
|
|
b = fgetc(fptr);
|
|
table[b] = i;
|
|
}
|
|
|
|
printf("Init done\n");
|
|
|
|
printf("Expected value for L=8 is 7.1836656\n");
|
|
|
|
run = 1;
|
|
|
|
while (run) {
|
|
sum = 0.0;
|
|
iproduct = 1;
|
|
|
|
if (run)
|
|
for (i = Q; run && i < Q + K; i++) {
|
|
j = i;
|
|
b = fgetc(fptr);
|
|
|
|
if (b < 0)
|
|
run = 0;
|
|
|
|
if (run) {
|
|
if (table[b] > j)
|
|
j += K;
|
|
|
|
sum += log((double)(j-table[b]));
|
|
|
|
table[b] = i;
|
|
}
|
|
}
|
|
|
|
if (!run)
|
|
printf("Premature end of file; read %d blocks.\n", i - Q);
|
|
|
|
sum = (sum/((double)(i - Q))) / log(2.0);
|
|
printf("%4.4f ", sum);
|
|
|
|
for (i = 0; i < (int)(sum*8.0 + 0.50); i++)
|
|
printf("-");
|
|
|
|
printf("\n");
|
|
|
|
/* refill initial table */
|
|
if (0) {
|
|
for (i = 0; i < Q; i++) {
|
|
b = fgetc(fptr);
|
|
if (b < 0) {
|
|
run = 0;
|
|
} else {
|
|
table[b] = i;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}</programlisting>
|
|
</sect1>
|
|
</article>
|