/*
 *
 *			   IPSEC for Linux
 *		         Preliminary Release
 * 
 *	 Copyright (C) 1996, 1997, John Ioannidis <ji@hol.gr>
 * 
 * Changes by Angelos D. Keromytis and Niels Provos
 * ported from OpenBSD 2.2 by Petr Novak, <pn@i.cz>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 *
 */

/*
 * $Id: ipsec_esp.h,v 0.5 1997/06/03 04:24:48 ji Rel $
 *
 * $Log: ipsec_esp.h,v $
 * Revision 0.5  1997/06/03 04:24:48  ji
 * Added ESP-3DES-MD5-96 transform.
 *
 * Revision 0.4  1997/01/15 01:28:15  ji
 * Added definitions for new ESP transforms.
 *
 * Revision 0.3  1996/11/20 14:35:48  ji
 * Minor Cleanup.
 * Rationalized debugging code.
 *
 * Revision 0.2  1996/11/02 00:18:33  ji
 * First limited release.
 *
 *
 */

#ifndef	IPPROTO_ESP
#define	IPPROTO_ESP	50
#endif

#include "hashes/ipsec_md5h.h"
#include "hashes/ipsec_sha1.h"
#include "hashes/ipsec_rmd160.h"
#include "ciphers/ipsec_blf.h"
#include "ciphers/ipsec_cast.h"

/* IV lengths */
#define ESP_DES_IVS             8
#define ESP_3DES_IVS            8
#define ESP_BLF_IVS             8
#define ESP_CAST_IVS            8

#define ESP_MAX_IVS             ESP_3DES_IVS

/* Block sizes -- it is assumed that they're powers of 2 */
#define ESP_DES_BLKS            8
#define ESP_3DES_BLKS           8
#define ESP_BLF_BLKS            8
#define ESP_CAST_BLKS           8

#define ESP_MAX_BLKS            ESP_3DES_BLKS

/* Various defines for the "new" ESP */
#define ESP_NEW_ALEN            12      /* 96bits authenticator */
#define ESP_NEW_IPAD_VAL        0x36
#define ESP_NEW_OPAD_VAL        0x5C

struct esp_hash {
    int type;
    char *name;
    __u16 hashsize;
    __u16 ctxsize;
    void (*Init)(void *);
    void (*Update)(void *, __u8 *, __u16);
    void (*Final)(__u8 *, void *);
};

struct esp_xform {
    int type;
    char *name;
    __u16 blocksize, ivsize;
    __u16 minkey, maxkey;
    __u32 ivmask;           /* Or all possible modes, zero iv = 1 */
    void (*encrypt)(void *, __u8 *);
    void (*decrypt)(void *, __u8 *);
};

struct esp_old
{
	__u32	esp_spi;		/* Security Parameters Index */
	__u8	esp_iv[8];		/* iv[4] may actually be data! */
};

struct esp_new
{
    __u32   esp_spi;        /* Security Parameter Index */
    __u32   esp_rpl;        /* Sequence Number, Replay Counter */
    __u8    esp_iv[8];      /* Data may start already at iv[0]! */
};

extern struct inet_protocol esp_protocol;


struct esp_old_xdata
{
	__u32	edx_enc_algorithm;
	int	edx_ivlen;		/* 4 or 8 */
	struct esp_xform *edx_xform;
	union
	{
		__u8	Iv[ESP_3DES_IVS];	/* that's enough space */
		__u32	Ivl;
		__u64	Ivq;
	} Iu;
#define edx_iv	Iu.Iv
#define edx_ivl Iu.Ivl
#define edx_ivq Iu.Ivq
	union
	{
		__u8 Rk[3][8];
		__u32 Eks[3][16][2];
	} Xu;
#define edx_rk	Xu.Rk
#define edx_eks	Xu.Eks
};

struct esp_new_xdata
{
	__u32	edx_enc_algorithm;
	__u32	edx_hash_algorithm;
	__u32	edx_ivlen;		/* 0 or 8 */
	__u32	edx_rpl;		/* Replay counter */
	__s32	edx_wnd;		/* Replay window */
	__u32	edx_bitmap;
	__u32	edx_flags;
	__u32	edx_initial;		/* initial replay value */
	struct esp_hash	*edx_hash;
	struct esp_xform *edx_xform;
	union
	{
		__u8		Iv[ESP_MAX_IVS];	/* That's enough space */
		__u32		Ivl;
		__u64		Ivq;
	} Iu;
	union
	{
		__u8		Rk[3][8];
		__u32		Eks[3][16][2];
		blf_ctx		Bks;
		cast_key	Cks;
	} Xu;
	union
	{
		MD5_CTX		edx_MD5_ictx;
		SHA1_CTX	edx_SHA1_ictx;
		RMD160_CTX	edx_RMD160_ictx;
	} edx_ictx;
	union
	{
		MD5_CTX		edx_MD5_octx;
		SHA1_CTX	edx_SHA1_octx;
		RMD160_CTX	edx_RMD160_octx;
	} edx_octx;
};

#define edx_bks         Xu.Bks
#define edx_cks         Xu.Cks
#define edx_md5_ictx    edx_ictx.edx_MD5_ictx
#define edx_md5_octx    edx_octx.edx_MD5_octx
#define edx_sha1_ictx   edx_ictx.edx_SHA1_ictx
#define edx_sha1_octx   edx_octx.edx_SHA1_octx
#define edx_rmd160_ictx edx_ictx.edx_RMD160_ictx
#define edx_rmd160_octx edx_octx.edx_RMD160_octx

#define ESP_OLD_FLENGTH         12
#define ESP_NEW_FLENGTH         16

#define ESP_NEW_FLAG_AUTH       0x00000001      /* Doing authentication too */
#define ESP_NEW_FLAG_NPADDING   0x00000002      /* New style padding */

struct esp_old_xencap
{
    __u32   edx_enc_algorithm;
    __u32   edx_ivlen;
    __u32   edx_keylen;
    __u8    edx_data[1];    /* IV + key material */
};

#define ESP_OLD_XENCAP_LEN      (3 * sizeof(__u32))

struct esp_new_xencap
{
    __u32   edx_enc_algorithm;
    __u32   edx_hash_algorithm;
    __u32   edx_ivlen;      /* 0 or 8 */
    __u16   edx_confkeylen;
    __u16   edx_authkeylen;
    __s32     edx_wnd;
    __u32   edx_flags;
    __u8    edx_data[1];    /* IV + key material */
};

#define ESP_NEW_XENCAP_LEN      (6 * sizeof(__u32))

#ifdef DEBUG_IPSEC_ESP

extern int debug_esp;

#define DB_ES_PKTRX	0x0001
#define DB_ES_PKTRX2	0x0002
#define DB_ES_TDB	0x0010
#define DB_ES_XF	0x0020
#define DB_ES_IPAD	0x0040
#define DB_ES_INAU	0x0080
#define DB_ES_OINFO	0x0100
#define DB_ES_OINFO2	0x0200
#define DB_ES_OH	0x0400
#define DB_ES_REPLAY	0x0800
#endif
