/*****************************************************************************
 *
 * ESP engine test.
 * Copyright (C) 2001  Bart Trojanowski <bart@jukie.net>.
 *
 * 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.  See <http://www.fsf.org/copyleft/gpl.txt>.
 * 
 * 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.
 *
 *****************************************************************************/

#include <linux/module.h>
#include <linux/init.h>
#include <linux/string.h>
#include "engine.h"
#include "engine-debug.h"
#include "proto-esp.h"
#include "cipher-des_ede3.h"
#include "digest-hmac_md5.h"

static int src_length = 124;
static u8 src_packet[256] = { 
  0x45, 0x00, 0x00, 0x7c, 0xc7, 0xc1, 0x00, 0x00, 
  0x40, 0x11, 0x1c, 0x5f, 0xc0, 0xa8, 0x0a, 0xfe, 
  0xc0, 0xa8, 0x0a, 0x02, 0x08, 0x01, 0x03, 0x1e, 
  0x00, 0x68, 0x00, 0x25, 0xb6, 0x26, 0x29, 0x12, 
  0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x81, 0x80, 
  0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0xf4, 
  0x00, 0x00, 0x01, 0xf4, 0x00, 0x07, 0xba, 0xce, 
  0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x21, 0x01, 
  0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0x02, 
  0x00, 0x00, 0x80, 0x79, 0x3b, 0x11, 0x5e, 0x47, 
  0x00, 0x00, 0x00, 0x00, 0x3b, 0x23, 0xbb, 0x05, 
  0x00, 0x00, 0x00, 0x00, 0x3b, 0x23, 0xbb, 0x05, 
  0x00, 0x00, 0x00, 0x00 
};

static int dst_length = 256;
static u8 dst_packet[256] = { 0, };

static u8 des_ede3_iv[DES_EDE3_IV_SZ] =
  {0,1,2,3,4,5,6,7};
static u8 des_ede3_key[DES_EDE3_KEY_SZ] = 
  {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23};
static u8 hmac_md5_key[HMAC_MD5_KEY_SZ] =
  {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};


static struct generic_engine *engine = NULL;

static void test_proto_esp_callback( struct generic_job * );

static int 
test_proto_esp( void )
{
  int ret;
  struct generic_context *con;
  struct proto_esp_context_definition defn;
  struct cipher_des_ede3_context_definition des_ede3_defn;
  struct digest_hmac_md5_context_definition hmac_md5_defn;
  struct generic_job *job;
  
  FIN();
  
  des_ede3_defn.operation = ENCRYPT_CBC;
  des_ede3_defn.key_ptr = des_ede3_key;
  des_ede3_defn.key_len = DES_EDE3_KEY_SZ;
  des_ede3_defn.iv_ptr = des_ede3_iv;
  des_ede3_defn.iv_len = DES_EDE3_IV_SZ;
  
  hmac_md5_defn.key_ptr = hmac_md5_key;
  hmac_md5_defn.key_len = HMAC_MD5_KEY_SZ;
  
  defn.operation = ENCAPSULATE;
  defn.spi_num = 0x100;
  defn.ip_ver = PF_INET;
  defn.tun_src.v4.s_addr = htonl(INADDR_LOOPBACK);
  defn.tun_dst.v4.s_addr = htonl(INADDR_LOOPBACK);
  defn.cipher_name = "cipher-des_ede3";
  defn.cipher_defn = &des_ede3_defn;
  defn.digest_name = "digest-hmac_md5";
  defn.digest_defn = &hmac_md5_defn;
  
  ret = create_context( engine, &defn, GFP_ATOMIC, &con);
  if( ret ) goto done;
  
  ret = create_job( con, GFP_ATOMIC, &job );
  if( ret ) goto bail_has_con;
  
  job->data.in_ptr = src_packet;
  job->data.in_len = src_length;
  job->data.out_ptr = dst_packet;
  job->data.out_len = dst_length;
  job->callback = test_proto_esp_callback;
  job->opaque = con;
  
  ret = execute_job( job );
  if( ret )
    goto bail_has_job;
  
  /* all the releasing is done in the callback */
  goto done;

 bail_has_job:
  release_job( &job );
  
 bail_has_con:
  release_context(&con);
  
 done:
  FEXIT(ret==0);
  return ret;
}

static void 
test_proto_esp_callback( struct generic_job *job )
{
  struct generic_context *con = (void*)job->opaque;
  
  FIN();

  /* dump it */
  
  ge_data_dump("src", job->data.in_ptr, job->data.in_len);
  ge_data_dump("dst", job->data.out_ptr, job->data.out_len);
  
  /* release the stuff */
  release_job( &job );
  release_context( &con );
  
  FOUT();
}


/* -------------------------------------------------------------------------
 * MODULE FUNCTIONS
 * ------------------------------------------------------------------------- */

static int __init
test_init(void)
{
  int ret = 0;

  FIN();
  
  printk(KERN_INFO "ESP engine test\n");
  
  ret = -ENODEV;
  engine = get_engine_by_name("proto-esp");
  if( !engine ) goto done;
  
  ret = test_proto_esp();
  
  FOUT();

 done:
  return ret;
}

static void __init
test_cleanup(void)
{
  FIN();

  if( engine )
    put_engine(engine);
  
  FOUT();
}

module_init(test_init);
module_exit(test_cleanup);

/*****************************************************************************
 *
 * $Log: test-proto-esp.c,v $
 * Revision 1.1  2001/06/13 02:02:48  bart
 * simple test for ESP
 *
 *
 *****************************************************************************/

