summaryrefslogtreecommitdiffstats
path: root/contrib/tcpdump/print-esp.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tcpdump/print-esp.c')
-rw-r--r--contrib/tcpdump/print-esp.c229
1 files changed, 167 insertions, 62 deletions
diff --git a/contrib/tcpdump/print-esp.c b/contrib/tcpdump/print-esp.c
index 7ebad59..1bdf76a 100644
--- a/contrib/tcpdump/print-esp.c
+++ b/contrib/tcpdump/print-esp.c
@@ -23,7 +23,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-esp.c,v 1.17 2000/12/12 09:58:41 itojun Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-esp.c,v 1.20 2002/01/21 11:39:59 mcr Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -39,13 +39,13 @@ static const char rcsid[] =
#include <netinet/in.h>
#ifdef HAVE_LIBCRYPTO
-#include <des.h>
-#include <blowfish.h>
+#include <openssl/des.h>
+#include <openssl/blowfish.h>
#ifdef HAVE_RC5_H
-#include <rc5.h>
+#include <openssl/rc5.h>
#endif
#ifdef HAVE_CAST_H
-#include <cast.h>
+#include <openssl/cast.h>
#endif
#endif
@@ -57,28 +57,153 @@ static const char rcsid[] =
#include "ip6.h"
#endif
+#define AVOID_CHURN 1
#include "interface.h"
#include "addrtoname.h"
+static struct esp_algorithm *espsecret_xform=NULL; /* cache of decoded alg. */
+static char *espsecret_key=NULL;
+
+
+enum cipher { NONE,
+ DESCBC,
+ BLOWFISH,
+ RC5,
+ CAST128,
+ DES3CBC};
+
+
+
+struct esp_algorithm {
+ char *name;
+ enum cipher algo;
+ int ivlen;
+ int authlen;
+ int replaysize;
+};
+
+struct esp_algorithm esp_xforms[]={
+ {"none", NONE, 0, 0, 0},
+ {"des-cbc", DESCBC, 8, 0, 0},
+ {"des-cbc-hmac96", DESCBC, 8, 12, 4},
+ {"blowfish-cbc", BLOWFISH,8, 0, 0},
+ {"blowfish-cbc-hmac96", BLOWFISH,8, 12, 4},
+ {"rc5-cbc", RC5, 8, 0, 0},
+ {"rc5-cbc-hmac96", RC5, 8, 12, 4},
+ {"cast128-cbc", CAST128, 8, 0, 0},
+ {"cast128-cbc-hmac96", CAST128, 8, 12, 4},
+ {"3des-cbc-hmac96", DES3CBC, 8, 12, 4},
+};
+
+static int hexdigit(char hex)
+{
+ if(hex >= '0' && hex <= '9') {
+ return (hex - '0');
+ } else if(hex >= 'A' && hex <= 'F') {
+ return (hex - 'A' + 10);
+ } else if(hex >= 'a' && hex <= 'f') {
+ return (hex - 'a' + 10);
+ } else {
+ printf("invalid hex digit %c in espsecret\n", hex);
+ return 0;
+ }
+}
+
+static int hex2byte(char *hexstring)
+{
+ int byte;
+
+ byte = (hexdigit(hexstring[0]) << 4) +
+ hexdigit(hexstring[1]);
+ return byte;
+}
+
+
+void esp_print_decodesecret()
+{
+ char *colon;
+ int len, i;
+ struct esp_algorithm *xf;
+
+ if(espsecret == NULL) {
+ /* set to NONE transform */
+ espsecret_xform = esp_xforms;
+ return;
+ }
+
+ if(espsecret_key != NULL) {
+ return;
+ }
+
+ colon = strchr(espsecret, ':');
+ if(colon == NULL) {
+ printf("failed to decode espsecret: %s\n",
+ espsecret);
+ /* set to NONE transform */
+ espsecret_xform = esp_xforms;
+ }
+
+ len = colon - espsecret;
+ xf = esp_xforms;
+ while(xf->name && strncasecmp(espsecret, xf->name, len)!=0) {
+ xf++;
+ }
+ if(xf->name == NULL) {
+ printf("failed to find cipher algo %s\n",
+ espsecret);
+ espsecret_xform = esp_xforms;
+ return;
+ }
+ espsecret_xform = xf;
+
+ colon++;
+ if(colon[0]=='0' && colon[1]=='x') {
+ /* decode some hex! */
+ colon+=2;
+ len = strlen(colon) / 2;
+ espsecret_key = (char *)malloc(len);
+ if(espsecret_key == NULL) {
+ fprintf(stderr, "%s: ran out of memory (%d) to allocate secret key\n",
+ program_name, len);
+ exit(2);
+ }
+ i = 0;
+ while(colon[0] != '\0' && colon[1]!='\0') {
+ espsecret_key[i]=hex2byte(colon);
+ colon+=2;
+ i++;
+ }
+ } else {
+ espsecret_key = colon;
+ }
+}
+
int
-esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr)
+esp_print(register const u_char *bp, register const u_char *bp2,
+ int *nhdr, int *padlen)
{
register const struct esp *esp;
register const u_char *ep;
u_int32_t spi;
- enum { NONE, DESCBC, BLOWFISH, RC5, CAST128, DES3CBC } algo = NONE;
struct ip *ip = NULL;
#ifdef INET6
struct ip6_hdr *ip6 = NULL;
#endif
int advance;
int len;
- char *secret = NULL;
+ char *secret;
int ivlen = 0;
u_char *ivoff;
-
+ u_char *p;
+
esp = (struct esp *)bp;
spi = (u_int32_t)ntohl(esp->esp_spi);
+ secret = NULL;
+
+#if 0
+ /* keep secret out of a register */
+ p = (u_char *)&secret;
+#endif
/* 'ep' points to the end of available data. */
ep = snapend;
@@ -95,40 +220,11 @@ esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr)
if (!espsecret)
goto fail;
- if (strncmp(espsecret, "des-cbc:", 8) == 0
- && strlen(espsecret + 8) == 8) {
- algo = DESCBC;
- ivlen = 8;
- secret = espsecret + 8;
- } else if (strncmp(espsecret, "blowfish-cbc:", 13) == 0) {
- algo = BLOWFISH;
- ivlen = 8;
- secret = espsecret + 13;
- } else if (strncmp(espsecret, "rc5-cbc:", 8) == 0) {
- algo = RC5;
- ivlen = 8;
- secret = espsecret + 8;
- } else if (strncmp(espsecret, "cast128-cbc:", 12) == 0) {
- algo = CAST128;
- ivlen = 8;
- secret = espsecret + 12;
- } else if (strncmp(espsecret, "3des-cbc:", 9) == 0
- && strlen(espsecret + 9) == 24) {
- algo = DES3CBC;
- ivlen = 8;
- secret = espsecret + 9;
- } else if (strncmp(espsecret, "none:", 5) == 0) {
- algo = NONE;
- ivlen = 0;
- secret = espsecret + 5;
- } else if (strlen(espsecret) == 8) {
- algo = DESCBC;
- ivlen = 8;
- secret = espsecret;
- } else {
- algo = NONE;
- ivlen = 0;
- secret = espsecret;
+ if(!espsecret_xform) {
+ esp_print_decodesecret();
+ }
+ if(espsecret_xform->algo == NONE) {
+ goto fail;
}
ip = (struct ip *)bp2;
@@ -145,6 +241,9 @@ esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr)
break;
#endif /*INET6*/
case 4:
+ /* nexthdr & padding are in the last fragment */
+ if (ntohs(ip->ip_off) & IP_MF)
+ goto fail;
#ifdef INET6
ip6 = NULL;
#endif
@@ -158,18 +257,16 @@ esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr)
if (ep - bp2 < len)
goto fail;
- if (Rflag)
- ivoff = (u_char *)(esp + 1) + sizeof(u_int32_t);
- else
- ivoff = (u_char *)(esp + 1);
+ ivoff = (u_char *)(esp + 1) + espsecret_xform->replaysize;
+ ivlen = espsecret_xform->ivlen;
+ secret = espsecret_key;
- switch (algo) {
+ switch (espsecret_xform->algo) {
case DESCBC:
#ifdef HAVE_LIBCRYPTO
{
u_char iv[8];
des_key_schedule schedule;
- u_char *p;
switch (ivlen) {
case 4:
@@ -206,7 +303,6 @@ esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr)
#ifdef HAVE_LIBCRYPTO
{
BF_KEY schedule;
- u_char *p;
BF_set_key(&schedule, strlen(secret), secret);
@@ -224,7 +320,6 @@ esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr)
#if defined(HAVE_LIBCRYPTO) && defined(HAVE_RC5_H)
{
RC5_32_KEY schedule;
- u_char *p;
RC5_32_set_key(&schedule, strlen(secret), secret,
RC5_16_ROUNDS);
@@ -243,7 +338,6 @@ esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr)
#if defined(HAVE_LIBCRYPTO) && defined(HAVE_CAST_H) && !defined(HAVE_BUGGY_CAST128)
{
CAST_KEY schedule;
- u_char *p;
CAST_set_key(&schedule, strlen(secret), secret);
@@ -261,16 +355,26 @@ esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr)
#if defined(HAVE_LIBCRYPTO)
{
des_key_schedule s1, s2, s3;
- u_char *p;
- des_check_key = 0;
- des_set_key((void *)secret, s1);
- des_set_key((void *)(secret + 8), s2);
- des_set_key((void *)(secret + 16), s3);
+ des_check_key = 1;
+ des_set_odd_parity((void *)secret);
+ des_set_odd_parity((void *)secret+8);
+ des_set_odd_parity((void *)secret+16);
+ if(des_set_key((void *)secret, s1) != 0) {
+ printf("failed to schedule key 1\n");
+ }
+ if(des_set_key((void *)(secret + 8), s2)!=0) {
+ printf("failed to schedule key 2\n");
+ }
+ if(des_set_key((void *)(secret + 16), s3)!=0) {
+ printf("failed to schedule key 3\n");
+ }
p = ivoff + ivlen;
des_ede3_cbc_encrypt((void *)p, (void *)p,
- (long)(ep - p), s1, s2, s3, (void *)ivoff, DES_DECRYPT);
+ (long)(ep - p),
+ s1, s2, s3,
+ (void *)ivoff, DES_DECRYPT);
advance = ivoff - (u_char *)esp + ivlen;
break;
}
@@ -280,17 +384,18 @@ esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr)
case NONE:
default:
- if (Rflag)
- advance = sizeof(struct esp) + sizeof(u_int32_t);
- else
- advance = sizeof(struct esp);
+ advance = sizeof(struct esp) + espsecret_xform->replaysize;
break;
}
+ ep = ep - espsecret_xform->authlen;
/* sanity check for pad length */
if (ep - bp < *(ep - 2))
goto fail;
+ if (padlen)
+ *padlen = *(ep - 2) + 2;
+
if (nhdr)
*nhdr = *(ep - 1);
OpenPOWER on IntegriCloud