From owner-freebsd-doc Sun Apr 25 19:46:40 1999 Delivered-To: freebsd-doc@freebsd.org Received: from mail01-oak.pilot.net (mail-oak-1.pilot.net [198.232.147.16]) by hub.freebsd.org (Postfix) with ESMTP id 36E2C14C29 for ; Sun, 25 Apr 1999 19:46:31 -0700 (PDT) (envelope-from honig@sprynet.com) Received: from idt.com (unknown-5-20.idt.com [157.165.5.20] (may be forged)) by mail01-oak.pilot.net with ESMTP id TAA23778 for ; Sun, 25 Apr 1999 19:46:30 -0700 (PDT) Received: from stgsmtp.corp.idt.com ([157.165.146.162]) by idt.com (8.8.5/8.7.5) with SMTP id TAA05425 for ; Sun, 25 Apr 1999 19:46:17 -0700 (PDT) Received: from [157.165.146.225] (HELO sprynet.com) by stgsmtp.corp.idt.com (Stalker SMTP Server 1.7) with ESMTP id S.0000101469 for ; Sun, 25 Apr 1999 18:49:18 -0800 Message-ID: <3723D362.851D7619@sprynet.com> Date: Sun, 25 Apr 1999 19:45:54 -0700 From: David Honig X-Mailer: Mozilla 4.5 [en] (X11; U; FreeBSD 3.0-RELEASE i386) X-Accept-Language: en MIME-Version: 1.0 To: freebsd-doc@freebsd.org Subject: How To Verify your IPsec functionality Content-Type: multipart/mixed; boundary="------------ABFFCDE9F2B656406114F78D" Sender: owner-freebsd-doc@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org 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"

Independent Verification of IPsec Functionality Under FreeBSD 3.0

You  installed IPsec and it seems to be working.  How do you know?  I describe a method for experimentally verifying that IPsec is working


The Problem

First, let's assume you have installed IPsec.  How do you know its working?  Sure, your connection won't work if its misconfigured, and it will work when you finally get it right.  Netstat will list it.  But can you independently confirm it?

The Solution

First, some crypto-relevent info theory:
  1. Encrypted data is uniformly distributed, ie, has maximal entropy per symbol.
  2. Raw, uncompressed data is typically redundant, i.e., has sub-maximal entropy.
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.

MUST

Ueli Maurer's "Universal Statistical Test for Random Bit Generators" ("MUST") quickly measures the entropy of a sample.  It uses a compression-like algorithm.  The code  is given below for a variant which measures successive (~quarter megabyte) chunks of a file.

Tcpdump

We also need a way to capture the raw network data.  A program called "tcpdump" lets you do this, if you have enabled the Berkeley Packet Filter interface in your kernel's config file.

The command

tcpdump -c 4000 -s 10000 -w dumpfile.bin
will capture 4000 raw packets to dumpfile.bin.  Up to 10,000 bytes per packet will be captured in this example.
 
 

The Experiment

Here's the experiment.  Open a window to an IPsec host and another window to an insecure host.

Now start capturing packets.

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.

Now run MUST 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.
 

% tcpdump -c 4000 -s 10000 -w ipsecdemo.bin
% uliscan ipsecdemo.bin
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 -----------------

Caveat

This experiment shows that IPsec does seem to be distributing the payload data uniformly, as encryption should.   However,  the experiment described here can not 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.

IPsec -Definition

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.

Installing IPsec

Starting from the BSD 3.0 stable release,
  1. install IPsec v0.04, rebuild, reinstall
  2. run the administration tools (e.g, ipsecadm) and distribute keys (or use Photuris for key exchange)
  3. set the routes (rt) up appropriately
You may want to make an "ipsec_setup" script containing the ipsecadm and rt commands which establish your IPsec tunnel.  You can run this script automatically at boottime from your /etc/rc.local   The ipsec_setup script will have to contain at least two ipsecadm commands and one rt command to be useful.
 
 

/usr/src/sys/i386/conf/KERNELNAME

This needs to be present in the kernel config file in order to run IPsec.  After adding it, run config, etc. and rebuild and reinstall.

#  The `bpfilter' pseudo-device enables the Berkeley Packet Filter.  Be
#  aware of the legal and administrative consequences of enabling this
#  option. Heh heh. The number of devices determines the maximum number of
#  simultaneous BPF clients programs runnable.

pseudo-device   bpfilter        2       #Berkeley packet filter ELSINORE

# IPSEC
options IPSEC
options "MD5"
pseudo-device   enc     1
 
 

Maurer's Universal Statistical Test (for block size=8 bits)


/*
   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;
                }
   }
}



honig@sprynet.com
25 Apr 99
 
  --------------ABFFCDE9F2B656406114F78D-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-doc" in the body of the message