[lantiq] add ltq-deu
authorblogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Sat, 15 Dec 2012 02:00:05 +0000 (02:00 +0000)
committerblogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Sat, 15 Dec 2012 02:00:05 +0000 (02:00 +0000)
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@34689 3c298f89-4303-0410-b956-a3cf2f4a3e73

25 files changed:
package/platform/lantiq/ltq-deu/Makefile [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/Makefile [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_aes.c [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_arc4.c [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_async_aes.c [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_async_des.c [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_des.c [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_deu.c [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_deu.h [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_deu_ar9.c [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_deu_ar9.h [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_deu_danube.c [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_deu_danube.h [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_deu_dma.c [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_deu_dma.h [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_deu_vr9.c [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_deu_vr9.h [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_md5.c [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_md5_hmac.c [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_sha1.c [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_sha1_hmac.c [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_tcrypt.h [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ifxmips_testmgr.h [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/internal.h [new file with mode: 0644]
package/platform/lantiq/ltq-deu/src/ltq_deu_testmgr.c [new file with mode: 0644]

diff --git a/package/platform/lantiq/ltq-deu/Makefile b/package/platform/lantiq/ltq-deu/Makefile
new file mode 100644 (file)
index 0000000..4e0d955
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=ltq-deu
+PKG_RELEASE:=1
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/ltq-deu-$(BUILD_VARIANT)
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/ltq-deu-template
+  SECTION:=sys
+  CATEGORY:=Kernel modules
+  SUBMENU:=Cryptographic API modules
+  TITLE:=deu driver for $(1)
+  URL:=http://www.lantiq.com/
+  VARIANT:=$(1)
+  DEPENDS:=@TARGET_lantiq_xway
+  FILES:=$(PKG_BUILD_DIR)/ltq_deu_$(1).ko $(PKG_BUILD_DIR)/ltq_deu_testmgr.ko
+  AUTOLOAD:=$(call AutoLoad,52,ltq_deu_$(1))
+endef
+
+KernelPackage/ltq-deu-danube=$(call KernelPackage/ltq-deu-template,danube)
+KernelPackage/ltq-deu-ar9=$(call KernelPackage/ltq-deu-template,ar9)
+KernelPackage/ltq-deu-vr9=$(call KernelPackage/ltq-deu-template,vr9)
+
+define Build/Prepare
+       $(INSTALL_DIR) $(PKG_BUILD_DIR)
+       $(CP) ./src/* $(PKG_BUILD_DIR)
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+       cd $(LINUX_DIR); \
+               ARCH=mips CROSS_COMPILE="$(KERNEL_CROSS)" \
+               $(MAKE) BUILD_VARIANT=$(BUILD_VARIANT) M=$(PKG_BUILD_DIR) V=1 modules
+endef
+
+$(eval $(call KernelPackage,ltq-deu-danube))
+$(eval $(call KernelPackage,ltq-deu-ar9))
+$(eval $(call KernelPackage,ltq-deu-vr9))
diff --git a/package/platform/lantiq/ltq-deu/src/Makefile b/package/platform/lantiq/ltq-deu/src/Makefile
new file mode 100644 (file)
index 0000000..f6cb9c9
--- /dev/null
@@ -0,0 +1,26 @@
+ifeq ($(BUILD_VARIANT),danube)\r
+  CFLAGS_MODULE =-DCONFIG_DANUBE -DCONFIG_CRYPTO_DEV_DEU -DCONFIG_CRYPTO_DEV_SPEED_TEST -DCONFIG_CRYPTO_DEV_DES \\r
+               -DCONFIG_CRYPTO_DEV_AES -DCONFIG_CRYPTO_DEV_SHA1 -DCONFIG_CRYPTO_DEV_MD5\r
+  obj-m = ltq_deu_danube.o\r
+  ltq_deu_danube-objs = ifxmips_deu.o ifxmips_deu_danube.o ifxmips_des.o ifxmips_aes.o ifxmips_sha1.o ifxmips_md5.o\r
+endif\r
+\r
+ifeq ($(BUILD_VARIANT),ar9)\r
+  CFLAGS_MODULE = -DCONFIG_AR9 -DCONFIG_CRYPTO_DEV_DEU -DCONFIG_CRYPTO_DEV_SPEED_TEST -DCONFIG_CRYPTO_DEV_DES \\r
+               -DCONFIG_CRYPTO_DEV_AES -DCONFIG_CRYPTO_DEV_SHA1 -DCONFIG_CRYPTO_DEV_MD5 -DCONFIG_CRYPTO_DEV_ARC4 \\r
+               -DCONFIG_CRYPTO_DEV_SHA1_HMAC -DCONFIG_CRYPTO_DEV_MD5_HMAC\r
+  obj-m = ltq_deu_ar9.o\r
+  ltq_deu_ar9-objs = ifxmips_deu.o ifxmips_deu_ar9.o ifxmips_des.o ifxmips_aes.o ifxmips_arc4.o \\r
+                       ifxmips_sha1.o ifxmips_md5.o ifxmips_sha1_hmac.o ifxmips_md5_hmac.o\r
+endif\r
+\r
+ifeq ($(BUILD_VARIANT),vr9)\r
+  CFLAGS_MODULE = -DCONFIG_VR9 -DCONFIG_CRYPTO_DEV_DEU -DCONFIG_CRYPTO_DEV_SPEED_TEST -DCONFIG_CRYPTO_DEV_DES \\r
+               -DCONFIG_CRYPTO_DEV_AES -DCONFIG_CRYPTO_DEV_SHA1 -DCONFIG_CRYPTO_DEV_MD5 -DCONFIG_CRYPTO_DEV_ARC4 \\r
+               -DCONFIG_CRYPTO_DEV_SHA1_HMAC -DCONFIG_CRYPTO_DEV_MD5_HMAC\r
+  obj-m = ltq_deu_vr9.o\r
+  ltq_deu_vr9-objs = ifxmips_deu.o ifxmips_deu_vr9.o ifxmips_des.o ifxmips_aes.o ifxmips_arc4.o \\r
+                       ifxmips_sha1.o ifxmips_md5.o ifxmips_sha1_hmac.o ifxmips_md5_hmac.o\r
+endif\r
+\r
+obj-m += ltq_deu_testmgr.o\r
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_aes.c b/package/platform/lantiq/ltq-deu/src/ifxmips_aes.c
new file mode 100644 (file)
index 0000000..bf77537
--- /dev/null
@@ -0,0 +1,904 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_aes.c
+** PROJECT      : IFX UEIP
+** MODULES      : DEU Module
+**
+** DATE         : September 8, 2009
+** AUTHOR       : Mohammad Firdaus
+** DESCRIPTION  : Data Encryption Unit Driver for AES Algorithm
+** COPYRIGHT    :       Copyright (c) 2009
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author             $Comment
+** 08,Sept 2009 Mohammad Firdaus    Initial UEIP release
+*******************************************************************************/
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief ifx DEU driver module
+*/
+
+/*!
+  \file        ifxmips_aes.c
+  \ingroup IFX_DEU
+  \brief AES Encryption Driver main file
+*/
+
+/*!
+ \defgroup IFX_AES_FUNCTIONS IFX_AES_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief IFX AES driver Functions 
+*/
+
+
+/* Project Header Files */
+#if defined(CONFIG_MODVERSIONS)
+#define MODVERSIONS
+#include <linux/modeversions>
+#endif
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/crypto.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+#include <crypto/algapi.h>
+
+#include "ifxmips_deu.h"
+
+#if defined(CONFIG_DANUBE) 
+#include "ifxmips_deu_danube.h"
+extern int ifx_danube_pre_1_4;
+#elif defined(CONFIG_AR9)
+#include "ifxmips_deu_ar9.h"
+#elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
+#include "ifxmips_deu_vr9.h"
+#else
+#error "Unkown platform"
+#endif
+
+/* DMA related header and variables */
+
+spinlock_t aes_lock;
+#define CRTCL_SECT_INIT        spin_lock_init(&aes_lock)
+#define CRTCL_SECT_START       spin_lock_irqsave(&aes_lock, flag)
+#define CRTCL_SECT_END         spin_unlock_irqrestore(&aes_lock, flag)
+
+/* Definition of constants */
+#define AES_START   IFX_AES_CON
+#define AES_MIN_KEY_SIZE    16
+#define AES_MAX_KEY_SIZE    32
+#define AES_BLOCK_SIZE      16
+#define CTR_RFC3686_NONCE_SIZE    4
+#define CTR_RFC3686_IV_SIZE       8
+#define CTR_RFC3686_MAX_KEY_SIZE  (AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE)
+
+#ifdef CRYPTO_DEBUG
+extern char debug_level;
+#define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
+#else
+#define DPRINTF(level, format, args...)
+#endif /* CRYPTO_DEBUG */
+
+/* Function decleration */
+int aes_chip_init(void);
+u32 endian_swap(u32 input);
+u32 input_swap(u32 input);
+u32* memory_alignment(const u8 *arg, u32 *buff_alloc, int in_out, int nbytes);
+void aes_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+void des_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+int aes_memory_allocate(int value);
+int des_memory_allocate(int value);
+void memory_release(u32 *addr); 
+
+
+extern void ifx_deu_aes (void *ctx_arg, uint8_t *out_arg, const uint8_t *in_arg,
+        uint8_t *iv_arg, size_t nbytes, int encdec, int mode);
+/* End of function decleration */
+
+struct aes_ctx {
+    int key_length;
+    u32 buf[AES_MAX_KEY_SIZE];
+    u8 nonce[CTR_RFC3686_NONCE_SIZE];
+};
+
+extern int disable_deudma;
+extern int disable_multiblock; 
+
+/*! \fn int aes_set_key (struct crypto_tfm *tfm, const uint8_t *in_key, unsigned int key_len)
+ *  \ingroup IFX_AES_FUNCTIONS 
+ *  \brief sets the AES keys    
+ *  \param tfm linux crypto algo transform  
+ *  \param in_key input key  
+ *  \param key_len key lengths of 16, 24 and 32 bytes supported  
+ *  \return -EINVAL - bad key length, 0 - SUCCESS
+*/                                 
+int aes_set_key (struct crypto_tfm *tfm, const u8 *in_key, unsigned int key_len)
+{
+    struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
+    unsigned long *flags = (unsigned long *) &tfm->crt_flags;
+
+    //printk("set_key in %s\n", __FILE__);
+
+    //aes_chip_init();
+
+    if (key_len != 16 && key_len != 24 && key_len != 32) {
+        *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+        return -EINVAL;
+    }
+
+    ctx->key_length = key_len;
+    DPRINTF(0, "ctx @%p, key_len %d, ctx->key_length %d\n", ctx, key_len, ctx->key_length);
+    memcpy ((u8 *) (ctx->buf), in_key, key_len);
+
+    return 0;
+}
+
+
+/*! \fn void ifx_deu_aes (void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, size_t nbytes, int encdec, int mode)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief main interface to AES hardware
+ *  \param ctx_arg crypto algo context  
+ *  \param out_arg output bytestream  
+ *  \param in_arg input bytestream   
+ *  \param iv_arg initialization vector  
+ *  \param nbytes length of bytestream  
+ *  \param encdec 1 for encrypt; 0 for decrypt  
+ *  \param mode operation mode such as ebc, cbc, ctr  
+ *
+*/                                 
+void ifx_deu_aes (void *ctx_arg, u8 *out_arg, const u8 *in_arg,
+        u8 *iv_arg, size_t nbytes, int encdec, int mode)
+
+{
+    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+    volatile struct aes_t *aes = (volatile struct aes_t *) AES_START;
+    struct aes_ctx *ctx = (struct aes_ctx *)ctx_arg;
+    u32 *in_key = ctx->buf;
+    unsigned long flag;
+    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+    int key_len = ctx->key_length;
+
+    int i = 0;
+    int byte_cnt = nbytes; 
+
+
+    CRTCL_SECT_START;
+    /* 128, 192 or 256 bit key length */
+    aes->controlr.K = key_len / 8 - 2;
+        if (key_len == 128 / 8) {
+        aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0));
+        aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1));
+        aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2));
+        aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3));
+    }
+    else if (key_len == 192 / 8) {
+        aes->K5R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0));
+        aes->K4R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1));
+        aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2));
+        aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3));
+        aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 4));
+        aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 5));
+    }
+    else if (key_len == 256 / 8) {
+        aes->K7R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0));
+        aes->K6R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1));
+        aes->K5R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2));
+        aes->K4R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3));
+        aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 4));
+        aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 5));
+        aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 6));
+        aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 7));
+    }
+    else {
+        printk (KERN_ERR "[%s %s %d]: Invalid key_len : %d\n", __FILE__, __func__, __LINE__, key_len);
+        CRTCL_SECT_END;
+        return;// -EINVAL;
+    }
+
+    /* let HW pre-process DEcryption key in any case (even if
+       ENcryption is used). Key Valid (KV) bit is then only
+       checked in decryption routine! */
+    aes->controlr.PNK = 1;
+
+
+    aes->controlr.E_D = !encdec;    //encryption
+    aes->controlr.O = mode; //0 ECB 1 CBC 2 OFB 3 CFB 4 CTR 
+
+    //aes->controlr.F = 128; //default; only for CFB and OFB modes; change only for customer-specific apps
+    if (mode > 0) {
+        aes->IV3R = DEU_ENDIAN_SWAP(*(u32 *) iv_arg);
+        aes->IV2R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1));
+        aes->IV1R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 2));
+        aes->IV0R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 3));
+    };
+
+
+    i = 0;
+    while (byte_cnt >= 16) {
+
+        aes->ID3R = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + (i * 4) + 0));
+        aes->ID2R = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + (i * 4) + 1));
+        aes->ID1R = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + (i * 4) + 2));
+        aes->ID0R = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + (i * 4) + 3));    /* start crypto */
+        
+        while (aes->controlr.BUS) {
+            // this will not take long
+        }
+
+        *((volatile u32 *) out_arg + (i * 4) + 0) = aes->OD3R;
+        *((volatile u32 *) out_arg + (i * 4) + 1) = aes->OD2R;
+        *((volatile u32 *) out_arg + (i * 4) + 2) = aes->OD1R;
+        *((volatile u32 *) out_arg + (i * 4) + 3) = aes->OD0R;
+
+        i++;
+        byte_cnt -= 16;
+    }
+
+
+    //tc.chen : copy iv_arg back
+    if (mode > 0) {
+        *((u32 *) iv_arg) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg));
+        *((u32 *) iv_arg + 1) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1));             
+        *((u32 *) iv_arg + 2) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 2));             
+        *((u32 *) iv_arg + 3) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 3));              
+    }
+
+    CRTCL_SECT_END;
+}
+
+/*!
+ *  \fn int ctr_rfc3686_aes_set_key (struct crypto_tfm *tfm, const uint8_t *in_key, unsigned int key_len)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief sets RFC3686 key   
+ *  \param tfm linux crypto algo transform  
+ *  \param in_key input key  
+ *  \param key_len key lengths of 20, 28 and 36 bytes supported; last 4 bytes is nonce 
+ *  \return 0 - SUCCESS
+ *          -EINVAL - bad key length
+*/                                 
+int ctr_rfc3686_aes_set_key (struct crypto_tfm *tfm, const uint8_t *in_key, unsigned int key_len)
+{
+    struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
+    unsigned long *flags = (unsigned long *)&tfm->crt_flags;
+
+    //printk("ctr_rfc3686_aes_set_key in %s\n", __FILE__);
+
+    memcpy(ctx->nonce, in_key + (key_len - CTR_RFC3686_NONCE_SIZE),
+           CTR_RFC3686_NONCE_SIZE);
+
+    key_len -= CTR_RFC3686_NONCE_SIZE; // remove 4 bytes of nonce
+
+    if (key_len != 16 && key_len != 24 && key_len != 32) {
+        *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+        return -EINVAL;
+    }
+
+    ctx->key_length = key_len;
+    
+    memcpy ((u8 *) (ctx->buf), in_key, key_len);
+
+    return 0;
+}
+
+/*! \fn void ifx_deu_aes (void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief main interface with deu hardware in DMA mode
+ *  \param ctx_arg crypto algo context 
+ *  \param out_arg output bytestream   
+ *  \param in_arg input bytestream   
+ *  \param iv_arg initialization vector  
+ *  \param nbytes length of bytestream  
+ *  \param encdec 1 for encrypt; 0 for decrypt  
+ *  \param mode operation mode such as ebc, cbc, ctr  
+*/
+
+
+//definitions from linux/include/crypto.h:
+//#define CRYPTO_TFM_MODE_ECB       0x00000001
+//#define CRYPTO_TFM_MODE_CBC       0x00000002
+//#define CRYPTO_TFM_MODE_CFB       0x00000004
+//#define CRYPTO_TFM_MODE_CTR       0x00000008
+//#define CRYPTO_TFM_MODE_OFB       0x00000010 // not even defined
+//but hardware definition: 0 ECB 1 CBC 2 OFB 3 CFB 4 CTR
+
+/*! \fn void ifx_deu_aes_ecb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief sets AES hardware to ECB mode   
+ *  \param ctx crypto algo context  
+ *  \param dst output bytestream  
+ *  \param src input bytestream  
+ *  \param iv initialization vector   
+ *  \param nbytes length of bytestream  
+ *  \param encdec 1 for encrypt; 0 for decrypt  
+ *  \param inplace not used  
+*/                                 
+void ifx_deu_aes_ecb (void *ctx, uint8_t *dst, const uint8_t *src,
+        uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+     ifx_deu_aes (ctx, dst, src, NULL, nbytes, encdec, 0);
+}
+
+/*! \fn void ifx_deu_aes_cbc (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief sets AES hardware to CBC mode   
+ *  \param ctx crypto algo context  
+ *  \param dst output bytestream  
+ *  \param src input bytestream  
+ *  \param iv initialization vector   
+ *  \param nbytes length of bytestream  
+ *  \param encdec 1 for encrypt; 0 for decrypt  
+ *  \param inplace not used  
+*/                                 
+void ifx_deu_aes_cbc (void *ctx, uint8_t *dst, const uint8_t *src,
+        uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+     ifx_deu_aes (ctx, dst, src, iv, nbytes, encdec, 1);
+}
+
+/*! \fn void ifx_deu_aes_ofb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief sets AES hardware to OFB mode   
+ *  \param ctx crypto algo context  
+ *  \param dst output bytestream  
+ *  \param src input bytestream  
+ *  \param iv initialization vector   
+ *  \param nbytes length of bytestream  
+ *  \param encdec 1 for encrypt; 0 for decrypt  
+ *  \param inplace not used  
+*/                                 
+void ifx_deu_aes_ofb (void *ctx, uint8_t *dst, const uint8_t *src,
+        uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+     ifx_deu_aes (ctx, dst, src, iv, nbytes, encdec, 2);
+}
+
+/*! \fn void ifx_deu_aes_cfb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief sets AES hardware to CFB mode   
+ *  \param ctx crypto algo context  
+ *  \param dst output bytestream  
+ *  \param src input bytestream  
+ *  \param iv initialization vector   
+ *  \param nbytes length of bytestream  
+ *  \param encdec 1 for encrypt; 0 for decrypt  
+ *  \param inplace not used  
+*/                                 
+void ifx_deu_aes_cfb (void *ctx, uint8_t *dst, const uint8_t *src,
+        uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+     ifx_deu_aes (ctx, dst, src, iv, nbytes, encdec, 3);
+}
+
+/*! \fn void ifx_deu_aes_ctr (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief sets AES hardware to CTR mode   
+ *  \param ctx crypto algo context  
+ *  \param dst output bytestream  
+ *  \param src input bytestream  
+ *  \param iv initialization vector   
+ *  \param nbytes length of bytestream  
+ *  \param encdec 1 for encrypt; 0 for decrypt  
+ *  \param inplace not used  
+*/                                 
+void ifx_deu_aes_ctr (void *ctx, uint8_t *dst, const uint8_t *src,
+        uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+     ifx_deu_aes (ctx, dst, src, iv, nbytes, encdec, 4);
+}
+
+/*! \fn void aes_encrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief encrypt AES_BLOCK_SIZE of data   
+ *  \param tfm linux crypto algo transform  
+ *  \param out output bytestream  
+ *  \param in input bytestream  
+*/                                 
+void aes_encrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
+{
+    struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
+    ifx_deu_aes (ctx, out, in, NULL, AES_BLOCK_SIZE,
+            CRYPTO_DIR_ENCRYPT, 0);
+}
+
+/*! \fn void aes_decrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief decrypt AES_BLOCK_SIZE of data   
+ *  \param tfm linux crypto algo transform  
+ *  \param out output bytestream  
+ *  \param in input bytestream  
+*/                                 
+void aes_decrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
+{
+    struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
+    ifx_deu_aes (ctx, out, in, NULL, AES_BLOCK_SIZE,
+            CRYPTO_DIR_DECRYPT, 0);
+}
+
+/* 
+ * \brief AES function mappings 
+*/
+struct crypto_alg ifxdeu_aes_alg = {
+    .cra_name       =   "aes",
+    .cra_driver_name    =   "ifxdeu-aes",
+    .cra_flags      =   CRYPTO_ALG_TYPE_CIPHER,
+    .cra_blocksize      =   AES_BLOCK_SIZE,
+    .cra_ctxsize        =   sizeof(struct aes_ctx),
+    .cra_module     =   THIS_MODULE,
+    .cra_list       =   LIST_HEAD_INIT(ifxdeu_aes_alg.cra_list),
+    .cra_u          =   {
+        .cipher = {
+            .cia_min_keysize    =   AES_MIN_KEY_SIZE,
+            .cia_max_keysize    =   AES_MAX_KEY_SIZE,
+            .cia_setkey     =   aes_set_key,
+            .cia_encrypt        =   aes_encrypt,
+            .cia_decrypt        =   aes_decrypt,
+        }
+    }
+};
+
+/*! \fn int ecb_aes_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief ECB AES encrypt using linux crypto blkcipher    
+ *  \param desc blkcipher descriptor  
+ *  \param dst output scatterlist  
+ *  \param src input scatterlist  
+ *  \param nbytes data size in bytes  
+ *  \return err
+*/                                 
+int ecb_aes_encrypt(struct blkcipher_desc *desc,
+               struct scatterlist *dst, struct scatterlist *src,
+               unsigned int nbytes)
+{
+    struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+    struct blkcipher_walk walk;
+    int err;
+    
+    blkcipher_walk_init(&walk, dst, src, nbytes);
+    err = blkcipher_walk_virt(desc, &walk);
+
+    while ((nbytes = walk.nbytes)) {
+            nbytes -= (nbytes % AES_BLOCK_SIZE); 
+        ifx_deu_aes_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
+                       NULL, nbytes, CRYPTO_DIR_ENCRYPT, 0);
+                nbytes &= AES_BLOCK_SIZE - 1;
+        err = blkcipher_walk_done(desc, &walk, nbytes);
+    }
+
+    return err;
+}
+
+/*! \fn int ecb_aes_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief ECB AES decrypt using linux crypto blkcipher    
+ *  \param desc blkcipher descriptor  
+ *  \param dst output scatterlist  
+ *  \param src input scatterlist  
+ *  \param nbytes data size in bytes  
+ *  \return err
+*/                                 
+int ecb_aes_decrypt(struct blkcipher_desc *desc,
+               struct scatterlist *dst, struct scatterlist *src,
+               unsigned int nbytes)
+{
+    struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+    struct blkcipher_walk walk;
+    int err;
+
+    blkcipher_walk_init(&walk, dst, src, nbytes);
+    err = blkcipher_walk_virt(desc, &walk);
+
+    while ((nbytes = walk.nbytes)) {
+            nbytes -= (nbytes % AES_BLOCK_SIZE); 
+        ifx_deu_aes_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
+                       NULL, nbytes, CRYPTO_DIR_DECRYPT, 0);
+        nbytes &= AES_BLOCK_SIZE - 1;
+        err = blkcipher_walk_done(desc, &walk, nbytes);
+    }
+
+    return err;
+}
+
+/* 
+ * \brief AES function mappings
+*/
+struct crypto_alg ifxdeu_ecb_aes_alg = {
+    .cra_name       =   "ecb(aes)",
+    .cra_driver_name    =   "ifxdeu-ecb(aes)",
+    .cra_flags      =   CRYPTO_ALG_TYPE_BLKCIPHER,
+    .cra_blocksize      =   AES_BLOCK_SIZE,
+    .cra_ctxsize        =   sizeof(struct aes_ctx),
+    .cra_type       =   &crypto_blkcipher_type,
+    .cra_module     =   THIS_MODULE,
+    .cra_list       =   LIST_HEAD_INIT(ifxdeu_ecb_aes_alg.cra_list),
+    .cra_u          =   {
+        .blkcipher = {
+            .min_keysize        =   AES_MIN_KEY_SIZE,
+            .max_keysize        =   AES_MAX_KEY_SIZE,
+            .setkey         =   aes_set_key,
+            .encrypt        =   ecb_aes_encrypt,
+            .decrypt        =   ecb_aes_decrypt,
+        }
+    }
+};
+
+
+/*! \fn int cbc_aes_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief CBC AES encrypt using linux crypto blkcipher    
+ *  \param desc blkcipher descriptor  
+ *  \param dst output scatterlist  
+ *  \param src input scatterlist  
+ *  \param nbytes data size in bytes  
+ *  \return err
+*/                                 
+int cbc_aes_encrypt(struct blkcipher_desc *desc,
+               struct scatterlist *dst, struct scatterlist *src,
+               unsigned int nbytes)
+{
+    struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+    struct blkcipher_walk walk;
+    int err;
+
+    blkcipher_walk_init(&walk, dst, src, nbytes);
+    err = blkcipher_walk_virt(desc, &walk);
+
+    while ((nbytes = walk.nbytes)) {
+            u8 *iv = walk.iv;
+            nbytes -= (nbytes % AES_BLOCK_SIZE);            
+            ifx_deu_aes_cbc(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
+                       iv, nbytes, CRYPTO_DIR_ENCRYPT, 0);  
+        nbytes &= AES_BLOCK_SIZE - 1;
+        err = blkcipher_walk_done(desc, &walk, nbytes);
+    }
+
+    return err;
+}
+
+/*! \fn int cbc_aes_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief CBC AES decrypt using linux crypto blkcipher    
+ *  \param desc blkcipher descriptor  
+ *  \param dst output scatterlist  
+ *  \param src input scatterlist  
+ *  \param nbytes data size in bytes  
+ *  \return err
+*/                                 
+int cbc_aes_decrypt(struct blkcipher_desc *desc,
+               struct scatterlist *dst, struct scatterlist *src,
+               unsigned int nbytes)
+{
+    struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+    struct blkcipher_walk walk;
+    int err;
+
+    blkcipher_walk_init(&walk, dst, src, nbytes);
+    err = blkcipher_walk_virt(desc, &walk);
+
+    while ((nbytes = walk.nbytes)) {
+        u8 *iv = walk.iv;
+            nbytes -= (nbytes % AES_BLOCK_SIZE);        
+            ifx_deu_aes_cbc(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
+                       iv, nbytes, CRYPTO_DIR_DECRYPT, 0);
+        nbytes &= AES_BLOCK_SIZE - 1;
+        err = blkcipher_walk_done(desc, &walk, nbytes);
+    }
+
+    return err;
+}
+
+/*
+ * \brief AES function mappings
+*/
+struct crypto_alg ifxdeu_cbc_aes_alg = {
+    .cra_name       =   "cbc(aes)",
+    .cra_driver_name    =   "ifxdeu-cbc(aes)",
+    .cra_flags      =   CRYPTO_ALG_TYPE_BLKCIPHER,
+    .cra_blocksize      =   AES_BLOCK_SIZE,
+    .cra_ctxsize        =   sizeof(struct aes_ctx),
+    .cra_type       =   &crypto_blkcipher_type,
+    .cra_module     =   THIS_MODULE,
+    .cra_list       =   LIST_HEAD_INIT(ifxdeu_cbc_aes_alg.cra_list),
+    .cra_u          =   {
+        .blkcipher = {
+            .min_keysize        =   AES_MIN_KEY_SIZE,
+            .max_keysize        =   AES_MAX_KEY_SIZE,
+            .ivsize         =   AES_BLOCK_SIZE,
+            .setkey         =   aes_set_key,
+            .encrypt        =   cbc_aes_encrypt,
+            .decrypt        =   cbc_aes_decrypt,
+        }
+    }
+};
+
+
+/*! \fn int ctr_basic_aes_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief Counter mode AES encrypt using linux crypto blkcipher    
+ *  \param desc blkcipher descriptor  
+ *  \param dst output scatterlist  
+ *  \param src input scatterlist  
+ *  \param nbytes data size in bytes  
+ *  \return err
+*/                                 
+int ctr_basic_aes_encrypt(struct blkcipher_desc *desc,
+               struct scatterlist *dst, struct scatterlist *src,
+               unsigned int nbytes)
+{
+    struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+    struct blkcipher_walk walk;
+    int err;
+
+    blkcipher_walk_init(&walk, dst, src, nbytes);
+    err = blkcipher_walk_virt(desc, &walk);
+
+    while ((nbytes = walk.nbytes)) {
+            u8 *iv = walk.iv;
+            nbytes -= (nbytes % AES_BLOCK_SIZE);            
+            ifx_deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
+                       iv, nbytes, CRYPTO_DIR_ENCRYPT, 0);  
+        nbytes &= AES_BLOCK_SIZE - 1;
+        err = blkcipher_walk_done(desc, &walk, nbytes);
+    }
+
+    return err;
+}
+
+/*! \fn  int ctr_basic_aes_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief Counter mode AES decrypt using linux crypto blkcipher    
+ *  \param desc blkcipher descriptor  
+ *  \param dst output scatterlist  
+ *  \param src input scatterlist  
+ *  \param nbytes data size in bytes  
+ *  \return err
+*/                                 
+int ctr_basic_aes_decrypt(struct blkcipher_desc *desc,
+               struct scatterlist *dst, struct scatterlist *src,
+               unsigned int nbytes)
+{
+    struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+    struct blkcipher_walk walk;
+    int err;
+
+    blkcipher_walk_init(&walk, dst, src, nbytes);
+    err = blkcipher_walk_virt(desc, &walk);
+
+    while ((nbytes = walk.nbytes)) {
+        u8 *iv = walk.iv;
+            nbytes -= (nbytes % AES_BLOCK_SIZE);        
+            ifx_deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
+                       iv, nbytes, CRYPTO_DIR_DECRYPT, 0);
+        nbytes &= AES_BLOCK_SIZE - 1;
+        err = blkcipher_walk_done(desc, &walk, nbytes);
+    }
+
+    return err;
+}
+
+/* 
+ * \brief AES function mappings
+*/
+struct crypto_alg ifxdeu_ctr_basic_aes_alg = {
+    .cra_name       =   "ctr(aes)",
+    .cra_driver_name    =   "ifxdeu-ctr(aes)",
+    .cra_flags      =   CRYPTO_ALG_TYPE_BLKCIPHER,
+    .cra_blocksize      =   AES_BLOCK_SIZE,
+    .cra_ctxsize        =   sizeof(struct aes_ctx),
+    .cra_type       =   &crypto_blkcipher_type,
+    .cra_module     =   THIS_MODULE,
+    .cra_list       =   LIST_HEAD_INIT(ifxdeu_ctr_basic_aes_alg.cra_list),
+    .cra_u          =   {
+        .blkcipher = {
+            .min_keysize        =   AES_MIN_KEY_SIZE,
+            .max_keysize        =   AES_MAX_KEY_SIZE,
+            .ivsize         =   AES_BLOCK_SIZE,
+            .setkey         =   aes_set_key,
+            .encrypt        =   ctr_basic_aes_encrypt,
+            .decrypt        =   ctr_basic_aes_decrypt,
+        }
+    }
+};
+
+
+/*! \fn  int ctr_rfc3686_aes_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief Counter mode AES (rfc3686) encrypt using linux crypto blkcipher    
+ *  \param desc blkcipher descriptor  
+ *  \param dst output scatterlist  
+ *  \param src input scatterlist  
+ *  \param nbytes data size in bytes  
+ *  \return err
+*/                                 
+int ctr_rfc3686_aes_encrypt(struct blkcipher_desc *desc,
+               struct scatterlist *dst, struct scatterlist *src,
+               unsigned int nbytes)
+{
+    struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+    struct blkcipher_walk walk;
+    int err;
+    u8 rfc3686_iv[16];
+
+    blkcipher_walk_init(&walk, dst, src, nbytes);
+    err = blkcipher_walk_virt(desc, &walk);
+    
+    /* set up counter block */
+    memcpy(rfc3686_iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE); 
+    memcpy(rfc3686_iv + CTR_RFC3686_NONCE_SIZE, walk.iv, CTR_RFC3686_IV_SIZE);
+
+    /* initialize counter portion of counter block */
+    *(__be32 *)(rfc3686_iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) =
+        cpu_to_be32(1);
+
+    while ((nbytes = walk.nbytes)) {
+            nbytes -= (nbytes % AES_BLOCK_SIZE);            
+            ifx_deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
+                       rfc3686_iv, nbytes, CRYPTO_DIR_ENCRYPT, 0);  
+        nbytes &= AES_BLOCK_SIZE - 1;
+        err = blkcipher_walk_done(desc, &walk, nbytes);
+    }
+   
+    return err;
+}
+
+/*! \fn int ctr_rfc3686_aes_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief Counter mode AES (rfc3686) decrypt using linux crypto blkcipher    
+ *  \param desc blkcipher descriptor  
+ *  \param dst output scatterlist  
+ *  \param src input scatterlist  
+ *  \param nbytes data size in bytes  
+ *  \return err
+*/                                 
+int ctr_rfc3686_aes_decrypt(struct blkcipher_desc *desc,
+               struct scatterlist *dst, struct scatterlist *src,
+               unsigned int nbytes)
+{
+    struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+    struct blkcipher_walk walk;
+    int err;
+    u8 rfc3686_iv[16];
+
+    blkcipher_walk_init(&walk, dst, src, nbytes);
+    err = blkcipher_walk_virt(desc, &walk);
+
+    /* set up counter block */
+    memcpy(rfc3686_iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE); 
+    memcpy(rfc3686_iv + CTR_RFC3686_NONCE_SIZE, walk.iv, CTR_RFC3686_IV_SIZE);
+
+    /* initialize counter portion of counter block */
+    *(__be32 *)(rfc3686_iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) =
+        cpu_to_be32(1);
+
+    while ((nbytes = walk.nbytes)) {
+            nbytes -= (nbytes % AES_BLOCK_SIZE);        
+            ifx_deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
+                       rfc3686_iv, nbytes, CRYPTO_DIR_DECRYPT, 0);
+        nbytes &= AES_BLOCK_SIZE - 1;
+        err = blkcipher_walk_done(desc, &walk, nbytes);
+    }
+
+    return err;
+}
+
+/* 
+ * \brief AES function mappings
+*/
+struct crypto_alg ifxdeu_ctr_rfc3686_aes_alg = {
+    .cra_name          =   "rfc3686(ctr(aes))",
+    .cra_driver_name    =   "ifxdeu-ctr-rfc3686(aes)",
+    .cra_flags         =   CRYPTO_ALG_TYPE_BLKCIPHER,
+    .cra_blocksize      =   AES_BLOCK_SIZE,
+    .cra_ctxsize        =   sizeof(struct aes_ctx),
+    .cra_type          =   &crypto_blkcipher_type,
+    .cra_module        =   THIS_MODULE,
+    .cra_list          =   LIST_HEAD_INIT(ifxdeu_ctr_rfc3686_aes_alg.cra_list),
+    .cra_u          =   {
+        .blkcipher = {
+            .min_keysize        =   AES_MIN_KEY_SIZE,
+            .max_keysize        =   CTR_RFC3686_MAX_KEY_SIZE,
+            .ivsize         =   CTR_RFC3686_IV_SIZE,
+            .setkey         =   ctr_rfc3686_aes_set_key,
+            .encrypt        =   ctr_rfc3686_aes_encrypt,
+            .decrypt        =   ctr_rfc3686_aes_decrypt,
+        }
+    }
+};
+
+
+/*! \fn int __init ifxdeu_init_aes (void)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief function to initialize AES driver   
+ *  \return ret 
+*/                                 
+int __init ifxdeu_init_aes (void)
+{
+    int ret = -ENOSYS;
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+    if (!disable_multiblock) {
+        ifxdeu_aes_alg.cra_u.cipher.cia_max_nbytes = AES_BLOCK_SIZE;    //(size_t)-1;
+        ifxdeu_aes_alg.cra_u.cipher.cia_req_align = 16;
+        ifxdeu_aes_alg.cra_u.cipher.cia_ecb = ifx_deu_aes_ecb;
+        ifxdeu_aes_alg.cra_u.cipher.cia_cbc = ifx_deu_aes_cbc;
+        ifxdeu_aes_alg.cra_u.cipher.cia_cfb = ifx_deu_aes_cfb;
+        ifxdeu_aes_alg.cra_u.cipher.cia_ofb = ifx_deu_aes_ofb;
+    }
+#endif
+
+    if ((ret = crypto_register_alg(&ifxdeu_aes_alg)))
+        goto aes_err;
+
+    if ((ret = crypto_register_alg(&ifxdeu_ecb_aes_alg)))
+        goto ecb_aes_err;
+
+    if ((ret = crypto_register_alg(&ifxdeu_cbc_aes_alg)))
+        goto cbc_aes_err;
+
+    if ((ret = crypto_register_alg(&ifxdeu_ctr_basic_aes_alg)))
+        goto ctr_basic_aes_err;
+
+    if ((ret = crypto_register_alg(&ifxdeu_ctr_rfc3686_aes_alg)))
+        goto ctr_rfc3686_aes_err;
+
+    aes_chip_init ();
+
+    CRTCL_SECT_INIT;
+
+
+    printk (KERN_NOTICE "IFX DEU AES initialized%s%s.\n", disable_multiblock ? "" : " (multiblock)", disable_deudma ? "" : " (DMA)");
+    return ret;
+
+ctr_rfc3686_aes_err:
+    crypto_unregister_alg(&ifxdeu_ctr_rfc3686_aes_alg);
+    printk (KERN_ERR "IFX ctr_rfc3686_aes initialization failed!\n");
+    return ret;
+ctr_basic_aes_err:
+    crypto_unregister_alg(&ifxdeu_ctr_basic_aes_alg);
+    printk (KERN_ERR "IFX ctr_basic_aes initialization failed!\n");
+    return ret;
+cbc_aes_err:
+    crypto_unregister_alg(&ifxdeu_cbc_aes_alg);
+    printk (KERN_ERR "IFX cbc_aes initialization failed!\n");
+    return ret;
+ecb_aes_err:
+    crypto_unregister_alg(&ifxdeu_ecb_aes_alg);
+    printk (KERN_ERR "IFX aes initialization failed!\n");
+    return ret;
+aes_err:
+    printk(KERN_ERR "IFX DEU AES initialization failed!\n");
+
+    return ret;
+}
+
+/*! \fn void __exit ifxdeu_fini_aes (void)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief unregister aes driver   
+*/                                 
+void __exit ifxdeu_fini_aes (void)
+{
+    crypto_unregister_alg (&ifxdeu_aes_alg);
+    crypto_unregister_alg (&ifxdeu_ecb_aes_alg);
+    crypto_unregister_alg (&ifxdeu_cbc_aes_alg);
+    crypto_unregister_alg (&ifxdeu_ctr_basic_aes_alg);
+    crypto_unregister_alg (&ifxdeu_ctr_rfc3686_aes_alg);
+
+}
+
+
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_arc4.c b/package/platform/lantiq/ltq-deu/src/ifxmips_arc4.c
new file mode 100644 (file)
index 0000000..ee56187
--- /dev/null
@@ -0,0 +1,389 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_arc4.c
+** PROJECT      : IFX UEIP
+** MODULES      : DEU Module
+**
+** DATE         : September 8, 2009
+** AUTHOR       : Mohammad Firdaus
+** DESCRIPTION  : Data Encryption Unit Driver for ARC4 Algorithm
+** COPYRIGHT    :       Copyright (c) 2009
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author             $Comment
+** 08 Sept 2009 Mohammad Firdaus    Initial UEIP release
+*******************************************************************************/
+
+/*!
+  \defgroup IFX_DEU IFX_DEU_DRIVERS
+  \ingroup API
+  \brief ifx deu driver module
+*/
+
+/*!
+  \file                ifxmips_arc4.c
+  \ingroup     IFX_DEU
+  \brief       ARC4 encryption DEU driver file
+*/
+
+/*! 
+  \defgroup IFX_ARC4_FUNCTIONS IFX_ARC4_FUNCTIONS
+  \ingroup IFX_DEU
+  \brief IFX deu driver functions
+*/
+
+/* Project header */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/crypto.h>
+#include <crypto/algapi.h>
+#include <linux/interrupt.h>
+#include <asm/byteorder.h>
+#include <linux/delay.h>
+
+/* Board specific header files */
+#ifdef CONFIG_AR9
+#include "ifxmips_deu_ar9.h"
+#endif
+#ifdef CONFIG_VR9
+#include "ifxmips_deu_vr9.h"
+#endif
+static spinlock_t lock;
+#define CRTCL_SECT_INIT        spin_lock_init(&lock)
+#define CRTCL_SECT_START       spin_lock_irqsave(&lock, flag)
+#define CRTCL_SECT_END         spin_unlock_irqrestore(&lock, flag)
+
+/* Preprocessor declerations */
+#define ARC4_MIN_KEY_SIZE       1
+//#define ARC4_MAX_KEY_SIZE     256
+#define ARC4_MAX_KEY_SIZE       16
+#define ARC4_BLOCK_SIZE         1
+#define ARC4_START   IFX_ARC4_CON
+#ifdef CRYPTO_DEBUG
+extern char debug_level;
+#define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
+#else
+#define DPRINTF(level, format, args...)
+#endif
+
+/* 
+ * \brief arc4 private structure
+*/
+struct arc4_ctx {
+        int key_length;
+        u8 buf[120];
+};
+
+extern int disable_deudma;
+extern int disable_multiblock;
+
+
+/*! \fn static void _deu_arc4 (void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
+    \ingroup IFX_ARC4_FUNCTIONS
+    \brief main interface to ARC4 hardware   
+    \param ctx_arg crypto algo context  
+    \param out_arg output bytestream  
+    \param in_arg input bytestream   
+    \param iv_arg initialization vector  
+    \param nbytes length of bytestream  
+    \param encdec 1 for encrypt; 0 for decrypt  
+    \param mode operation mode such as ebc, cbc, ctr  
+*/                                 
+static void _deu_arc4 (void *ctx_arg, u8 *out_arg, const u8 *in_arg,
+            u8 *iv_arg, u32 nbytes, int encdec, int mode)
+{
+        volatile struct arc4_t *arc4 = (struct arc4_t *) ARC4_START;
+        
+        int i = 0;
+        unsigned long flag;
+        
+#if 1 // need to handle nbytes not multiple of 16       
+        volatile u32 tmp_array32[4];
+        volatile u8 *tmp_ptr8;
+        int remaining_bytes, j;
+#endif
+
+        CRTCL_SECT_START;
+
+        arc4->IDLEN = nbytes;
+
+#if 1
+        while (i < nbytes) {
+                arc4->ID3R = *((u32 *) in_arg + (i>>2) + 0);
+                arc4->ID2R = *((u32 *) in_arg + (i>>2) + 1);    
+                arc4->ID1R = *((u32 *) in_arg + (i>>2) + 2);
+                arc4->ID0R = *((u32 *) in_arg + (i>>2) + 3);    
+                
+                arc4->controlr.GO = 1; 
+                
+                while (arc4->controlr.BUS) {
+                      // this will not take long
+                }
+
+#if 1
+                // need to handle nbytes not multiple of 16 
+                tmp_array32[0] = arc4->OD3R;
+                tmp_array32[1] = arc4->OD2R;
+                tmp_array32[2] = arc4->OD1R;
+                tmp_array32[3] = arc4->OD0R;
+
+                remaining_bytes = nbytes - i;
+                if (remaining_bytes > 16)
+                     remaining_bytes = 16;
+                
+                tmp_ptr8 = (u8 *)&tmp_array32[0];
+                for (j = 0; j < remaining_bytes; j++)
+                     *out_arg++ = *tmp_ptr8++;
+#else                                
+                *((u32 *) out_arg + (i>>2) + 0) = arc4->OD3R;
+                *((u32 *) out_arg + (i>>2) + 1) = arc4->OD2R;
+                *((u32 *) out_arg + (i>>2) + 2) = arc4->OD1R;
+                *((u32 *) out_arg + (i>>2) + 3) = arc4->OD0R;
+#endif
+
+                i += 16;
+        }
+#else // dma
+
+#endif // dma
+
+        CRTCL_SECT_END;
+}
+
+/*! \fn arc4_chip_init (void)
+    \ingroup IFX_ARC4_FUNCTIONS
+    \brief initialize arc4 hardware   
+*/                                 
+static void arc4_chip_init (void)
+{
+        //do nothing
+}
+
+/*! \fn static int arc4_set_key(struct crypto_tfm *tfm, const u8 *in_key, unsigned int key_len)
+    \ingroup IFX_ARC4_FUNCTIONS
+    \brief sets ARC4 key    
+    \param tfm linux crypto algo transform  
+    \param in_key input key  
+    \param key_len key lengths less than or equal to 16 bytes supported  
+*/    
+static int arc4_set_key(struct crypto_tfm *tfm, const u8 *inkey,
+                       unsigned int key_len)
+{
+        //struct arc4_ctx *ctx = crypto_tfm_ctx(tfm);
+        volatile struct arc4_t *arc4 = (struct arc4_t *) ARC4_START;
+        u32 *in_key = (u32 *)inkey;
+                
+        // must program all bits at one go?!!!
+//#if 1
+        *IFX_ARC4_CON = ( (1<<31) | ((key_len - 1)<<27) | (1<<26) | (3<<16) );
+        //NDC=1,ENDI=1,GO=0,KSAE=1,SM=0
+
+        arc4->K3R = *((u32 *) in_key + 0);
+        arc4->K2R = *((u32 *) in_key + 1);
+        arc4->K1R = *((u32 *) in_key + 2);
+        arc4->K0R = *((u32 *) in_key + 3);
+
+#if 0 // arc4 is a ugly state machine, KSAE can only be set once per session  
+        ctx->key_length = key_len;
+
+        memcpy ((u8 *) (ctx->buf), in_key, key_len);
+#endif
+
+        return 0;
+}
+
+/*! \fn static void _deu_arc4_ecb(void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+    \ingroup IFX_ARC4_FUNCTIONS
+    \brief sets ARC4 hardware to ECB mode   
+    \param ctx crypto algo context  
+    \param dst output bytestream  
+    \param src input bytestream  
+    \param iv initialization vector   
+    \param nbytes length of bytestream  
+    \param encdec 1 for encrypt; 0 for decrypt  
+    \param inplace not used  
+*/                               
+static void _deu_arc4_ecb(void *ctx, uint8_t *dst, const uint8_t *src,
+                uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+        _deu_arc4 (ctx, dst, src, NULL, nbytes, encdec, 0);
+}
+
+/*! \fn static void arc4_crypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
+    \ingroup IFX_ARC4_FUNCTIONS
+    \brief encrypt/decrypt ARC4_BLOCK_SIZE of data   
+    \param tfm linux crypto algo transform  
+    \param out output bytestream  
+    \param in input bytestream  
+*/     
+static void arc4_crypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
+{
+        struct arc4_ctx *ctx = crypto_tfm_ctx(tfm);
+
+        _deu_arc4 (ctx, out, in, NULL, ARC4_BLOCK_SIZE,
+                    CRYPTO_DIR_DECRYPT, 0);
+
+}
+
+/*
+ * \brief ARC4 function mappings
+*/
+static struct crypto_alg ifxdeu_arc4_alg = {
+        .cra_name               =       "arc4",
+        .cra_driver_name        =       "ifxdeu-arc4",
+        .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
+        .cra_blocksize          =       ARC4_BLOCK_SIZE,
+        .cra_ctxsize            =       sizeof(struct arc4_ctx),
+        .cra_module             =       THIS_MODULE,
+        .cra_list               =       LIST_HEAD_INIT(ifxdeu_arc4_alg.cra_list),
+        .cra_u                  =       {
+                .cipher = {
+                        .cia_min_keysize        =       ARC4_MIN_KEY_SIZE,
+                        .cia_max_keysize        =       ARC4_MAX_KEY_SIZE,
+                        .cia_setkey             =       arc4_set_key,
+                        .cia_encrypt            =       arc4_crypt,
+                        .cia_decrypt            =       arc4_crypt,
+                }
+        }
+};
+
+/*! \fn static int ecb_arc4_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+    \ingroup IFX_ARC4_FUNCTIONS
+    \brief ECB ARC4 encrypt using linux crypto blkcipher    
+    \param desc blkcipher descriptor  
+    \param dst output scatterlist  
+    \param src input scatterlist  
+    \param nbytes data size in bytes  
+*/                                     
+static int ecb_arc4_encrypt(struct blkcipher_desc *desc,
+                           struct scatterlist *dst, struct scatterlist *src,
+                           unsigned int nbytes)
+{
+        struct arc4_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+        struct blkcipher_walk walk;
+        int err;
+
+        DPRINTF(1, "\n");
+        blkcipher_walk_init(&walk, dst, src, nbytes);
+        err = blkcipher_walk_virt(desc, &walk);
+
+        while ((nbytes = walk.nbytes)) {
+                _deu_arc4_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
+                               NULL, nbytes, CRYPTO_DIR_ENCRYPT, 0);
+                nbytes &= ARC4_BLOCK_SIZE - 1;
+                err = blkcipher_walk_done(desc, &walk, nbytes);
+        }
+
+        return err;
+}
+
+/*! \fn static int ecb_arc4_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+    \ingroup IFX_ARC4_FUNCTIONS
+    \brief ECB ARC4 decrypt using linux crypto blkcipher    
+    \param desc blkcipher descriptor  
+    \param dst output scatterlist  
+    \param src input scatterlist  
+    \param nbytes data size in bytes  
+*/                                     
+static int ecb_arc4_decrypt(struct blkcipher_desc *desc,
+                           struct scatterlist *dst, struct scatterlist *src,
+                           unsigned int nbytes)
+{
+        struct arc4_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+        struct blkcipher_walk walk;
+        int err;
+
+        DPRINTF(1, "\n");
+        blkcipher_walk_init(&walk, dst, src, nbytes);
+        err = blkcipher_walk_virt(desc, &walk);
+
+        while ((nbytes = walk.nbytes)) {
+                _deu_arc4_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
+                               NULL, nbytes, CRYPTO_DIR_DECRYPT, 0);
+                nbytes &= ARC4_BLOCK_SIZE - 1;
+                err = blkcipher_walk_done(desc, &walk, nbytes);
+        }
+
+        return err;
+}
+
+/*
+ * \brief ARC4 function mappings
+*/
+static struct crypto_alg ifxdeu_ecb_arc4_alg = {
+        .cra_name               =       "ecb(arc4)",
+        .cra_driver_name        =       "ifxdeu-ecb(arc4)",
+        .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
+        .cra_blocksize          =       ARC4_BLOCK_SIZE,
+        .cra_ctxsize            =       sizeof(struct arc4_ctx),
+        .cra_type               =       &crypto_blkcipher_type,
+        .cra_module             =       THIS_MODULE,
+        .cra_list               =       LIST_HEAD_INIT(ifxdeu_ecb_arc4_alg.cra_list),
+        .cra_u                  =       {
+                .blkcipher = {
+                        .min_keysize            =       ARC4_MIN_KEY_SIZE,
+                        .max_keysize            =       ARC4_MAX_KEY_SIZE,
+                        .setkey                 =       arc4_set_key,
+                        .encrypt                =       ecb_arc4_encrypt,
+                        .decrypt                =       ecb_arc4_decrypt,
+                }
+        }
+};
+
+/*! \fn int __init ifxdeu_init_arc4(void)
+    \ingroup IFX_ARC4_FUNCTIONS
+    \brief initialize arc4 driver    
+*/                                 
+int __init ifxdeu_init_arc4(void)
+{
+    int ret = -ENOSYS;
+
+
+        if ((ret = crypto_register_alg(&ifxdeu_arc4_alg)))
+                goto arc4_err;
+
+        if ((ret = crypto_register_alg(&ifxdeu_ecb_arc4_alg)))
+                goto ecb_arc4_err;
+
+        arc4_chip_init ();
+
+        CRTCL_SECT_INIT;
+
+        printk (KERN_NOTICE "IFX DEU ARC4 initialized%s%s.\n", disable_multiblock ? "" : " (multiblock)", disable_deudma ? "" : " (DMA)");
+        return ret;
+
+arc4_err:
+        crypto_unregister_alg(&ifxdeu_arc4_alg);
+        printk(KERN_ERR "IFX arc4 initialization failed!\n");
+        return ret;
+ecb_arc4_err:
+        crypto_unregister_alg(&ifxdeu_ecb_arc4_alg);
+        printk (KERN_ERR "IFX ecb_arc4 initialization failed!\n");
+        return ret;
+
+}
+
+/*! \fn void __exit ifxdeu_fini_arc4(void)
+    \ingroup IFX_ARC4_FUNCTIONS
+    \brief unregister arc4 driver   
+*/                                 
+void __exit ifxdeu_fini_arc4(void)
+{
+        crypto_unregister_alg (&ifxdeu_arc4_alg);
+        crypto_unregister_alg (&ifxdeu_ecb_arc4_alg);
+
+
+}
+
+
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_async_aes.c b/package/platform/lantiq/ltq-deu/src/ifxmips_async_aes.c
new file mode 100644 (file)
index 0000000..64536da
--- /dev/null
@@ -0,0 +1,1137 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_async_aes.c
+** PROJECT      : IFX UEIP
+** MODULES      : DEU Module
+**
+** DATE         : October 11, 2010
+** AUTHOR       : Mohammad Firdaus
+** DESCRIPTION  : Data Encryption Unit Driver for AES Algorithm
+** COPYRIGHT    :       Copyright (c) 2010
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author             $Comment
+** 08,Sept 2009 Mohammad Firdaus    Initial UEIP release
+** 11, Oct 2010 Mohammad Firdaus    Kernel Port incl. Async. Ablkcipher mode
+** 21,March 2011 Mohammad Firdaus   Changes for Kernel 2.6.32 and IPSec integration
+*******************************************************************************/
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief ifx DEU driver module
+*/
+
+/*!
+  \file ifxmips_async_aes.c
+  \ingroup IFX_DEU
+  \brief AES Encryption Driver main file
+*/
+
+/*!
+ \defgroup IFX_AES_FUNCTIONS IFX_AES_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief IFX AES driver Functions
+*/
+
+
+
+#include <linux/wait.h>
+#include <linux/crypto.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <crypto/ctr.h>
+#include <crypto/aes.h>
+#include <crypto/algapi.h>
+#include <crypto/scatterwalk.h>
+
+#include <asm/ifx/ifx_regs.h>
+#include <asm/ifx/ifx_types.h>
+#include <asm/ifx/common_routines.h>
+#include <asm/ifx/irq.h>
+#include <asm/ifx/ifx_pmu.h>
+#include <asm/ifx/ifx_gpio.h>
+#include <asm/kmap_types.h>
+
+#include "ifxmips_deu.h"
+
+#if defined(CONFIG_DANUBE)
+#include "ifxmips_deu_danube.h"
+extern int ifx_danube_pre_1_4;
+#elif defined(CONFIG_AR9)
+#include "ifxmips_deu_ar9.h"
+#elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
+#include "ifxmips_deu_vr9.h"
+#else
+#error "Unkown platform"
+#endif
+
+/* DMA related header and variables */
+
+spinlock_t aes_lock;
+#define CRTCL_SECT_INIT        spin_lock_init(&aes_lock)
+#define CRTCL_SECT_START       spin_lock_irqsave(&aes_lock, flag)
+#define CRTCL_SECT_END         spin_unlock_irqrestore(&aes_lock, flag)
+
+/* Definition of constants */
+//#define AES_START   IFX_AES_CON
+#define AES_MIN_KEY_SIZE    16
+#define AES_MAX_KEY_SIZE    32
+#define AES_BLOCK_SIZE      16
+#define CTR_RFC3686_NONCE_SIZE    4
+#define CTR_RFC3686_IV_SIZE       8
+#define CTR_RFC3686_MAX_KEY_SIZE  (AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE)
+
+#ifdef CRYPTO_DEBUG
+extern char debug_level;
+#define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
+#else
+#define DPRINTF(level, format, args...)
+#endif /* CRYPTO_DEBUG */
+
+
+static int disable_multiblock = 0;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+module_param(disable_multiblock, int, 0);
+#else
+MODULE_PARM_DESC(disable_multiblock, "Disable encryption of whole multiblock buffers");
+#endif
+
+static int disable_deudma = 1;
+
+/* Function decleration */
+int aes_chip_init(void);
+u32 endian_swap(u32 input);
+u32 input_swap(u32 input);
+u32* memory_alignment(const u8 *arg, u32 *buff_alloc, int in_out, int nbytes);
+void aes_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+int aes_memory_allocate(int value);
+int des_memory_allocate(int value);
+void memory_release(u32 *addr);
+
+
+struct aes_ctx {
+    int key_length;
+    u32 buf[AES_MAX_KEY_SIZE];
+    u8 nonce[CTR_RFC3686_NONCE_SIZE];
+
+};
+
+struct aes_container {
+    u8 *iv;
+    u8 *src_buf;
+    u8 *dst_buf;
+
+    int mode;
+    int encdec;
+    int complete;
+    int flag;
+
+    u32 bytes_processed;
+    u32 nbytes;
+
+    struct ablkcipher_request arequest;
+};
+
+aes_priv_t *aes_queue;
+extern deu_drv_priv_t deu_dma_priv;
+
+void hexdump(unsigned char *buf, unsigned int len)
+{
+        print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
+                        16, 1,
+                        buf, len, false);
+}
+
+/*! \fn void lq_deu_aes_core (void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, 
+                             size_t nbytes, int encdec, int mode)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief main interface to AES hardware
+ *  \param ctx_arg crypto algo context
+ *  \param out_arg output bytestream
+ *  \param in_arg input bytestream
+ *  \param iv_arg initialization vector
+ *  \param nbytes length of bytestream
+ *  \param encdec 1 for encrypt; 0 for decrypt
+ *  \param mode operation mode such as ebc, cbc, ctr
+ *
+*/
+
+static int lq_deu_aes_core (void *ctx_arg, u8 *out_arg, const u8 *in_arg,
+                            u8 *iv_arg, size_t nbytes, int encdec, int mode)
+{
+    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+    volatile struct aes_t *aes = (volatile struct aes_t *) AES_START;
+    struct aes_ctx *ctx = (struct aes_ctx *)ctx_arg;
+    u32 *in_key = ctx->buf;
+    unsigned long flag;
+    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+    int key_len = ctx->key_length;
+
+    volatile struct deu_dma_t *dma = (struct deu_dma_t *) IFX_DEU_DMA_CON;
+    struct dma_device_info *dma_device = ifx_deu[0].dma_device;
+    deu_drv_priv_t *deu_priv = (deu_drv_priv_t *)dma_device->priv;
+    int wlen = 0;
+    //u32 *outcopy = NULL;
+    u32 *dword_mem_aligned_in = NULL;
+
+    CRTCL_SECT_START;
+
+    /* 128, 192 or 256 bit key length */
+    aes->controlr.K = key_len / 8 - 2;
+        if (key_len == 128 / 8) {
+        aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0));
+        aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1));
+        aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2));
+        aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3));
+    }
+    else if (key_len == 192 / 8) {
+        aes->K5R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0));
+        aes->K4R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1));
+        aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2));
+        aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3));
+        aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 4));
+        aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 5));
+    }
+    else if (key_len == 256 / 8) {
+        aes->K7R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0));
+        aes->K6R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1));
+        aes->K5R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2));
+        aes->K4R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3));
+        aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 4));
+        aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 5));
+        aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 6));
+        aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 7));
+    }
+    else {
+        printk (KERN_ERR "[%s %s %d]: Invalid key_len : %d\n", __FILE__, __func__, __LINE__, key_len);
+        CRTCL_SECT_END;
+        return -EINVAL;
+    }
+
+    /* let HW pre-process DEcryption key in any case (even if
+       ENcryption is used). Key Valid (KV) bit is then only
+       checked in decryption routine! */
+    aes->controlr.PNK = 1;
+
+    while (aes->controlr.BUS) {
+        // this will not take long
+    }
+    AES_DMA_MISC_CONFIG();
+
+    aes->controlr.E_D = !encdec;    //encryption
+    aes->controlr.O = mode; //0 ECB 1 CBC 2 OFB 3 CFB 4 CTR 
+
+    //aes->controlr.F = 128; //default; only for CFB and OFB modes; change only for customer-specific apps
+    if (mode > 0) {
+        aes->IV3R = DEU_ENDIAN_SWAP(*(u32 *) iv_arg);
+        aes->IV2R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1));
+        aes->IV1R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 2));
+        aes->IV0R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 3));
+    };
+
+
+    /* Prepare Rx buf length used in dma psuedo interrupt */
+    deu_priv->deu_rx_buf = (u32 *)out_arg;
+    deu_priv->deu_rx_len = nbytes;
+   
+    /* memory alignment issue */ 
+    dword_mem_aligned_in = (u32 *) DEU_DWORD_REORDERING(in_arg, aes_buff_in, BUFFER_IN, nbytes);
+
+    dma->controlr.ALGO = 1;   //AES
+    dma->controlr.BS = 0;
+    aes->controlr.DAU = 0;
+    dma->controlr.EN = 1;
+
+    while (aes->controlr.BUS) {
+         // wait for AES to be ready
+    };
+
+    deu_priv->outcopy = (u32 *) DEU_DWORD_REORDERING(out_arg, aes_buff_out, BUFFER_OUT, nbytes);
+    deu_priv->event_src = AES_ASYNC_EVENT;
+
+    wlen = dma_device_write (dma_device, (u8 *)dword_mem_aligned_in, nbytes, NULL);
+    if (wlen != nbytes) {
+        dma->controlr.EN = 0;
+        CRTCL_SECT_END;
+        printk (KERN_ERR "[%s %s %d]: dma_device_write fail!\n", __FILE__, __func__, __LINE__);
+        return -EINVAL;
+    }
+
+   // WAIT_AES_DMA_READY();
+
+    CRTCL_SECT_END;
+
+    if (mode > 0) {
+        *((u32 *) iv_arg) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg));
+        *((u32 *) iv_arg + 1) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1));
+        *((u32 *) iv_arg + 2) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 2));
+        *((u32 *) iv_arg + 3) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 3));
+    }
+   
+    return -EINPROGRESS;       
+}
+
+/* \fn static int count_sgs(struct scatterlist *sl, unsigned int total_bytes)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Counts and return the number of scatterlists 
+ * \param *sl Function pointer to the scatterlist
+ * \param total_bytes The total number of bytes that needs to be encrypted/decrypted
+ * \return The number of scatterlists 
+*/
+
+static int count_sgs(struct scatterlist *sl, unsigned int total_bytes)
+{
+        int i = 0;
+
+        do {
+                total_bytes -= sl[i].length;
+                i++;
+
+        } while (total_bytes > 0);
+
+        return i;
+}
+
+/* \fn void lq_sg_init(struct scatterlist *src,
+ *                     struct scatterlist *dst)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Maps the scatterlists into a source/destination page. 
+ * \param *src Pointer to the source scatterlist
+ * \param *dst Pointer to the destination scatterlist
+*/
+
+static void lq_sg_init(struct aes_container *aes_con,struct scatterlist *src,
+                       struct scatterlist *dst)
+{
+
+    struct page *dst_page, *src_page;
+
+    src_page = sg_virt(src);
+    aes_con->src_buf = (char *) src_page;
+
+    dst_page = sg_virt(dst);
+    aes_con->dst_buf = (char *) dst_page;
+
+}
+
+
+/* \fn static void lq_sg_complete(struct aes_container *aes_con) 
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Free the used up memory after encryt/decrypt.
+*/
+
+static void lq_sg_complete(struct aes_container *aes_con) 
+{
+    unsigned long queue_flag;
+
+    spin_lock_irqsave(&aes_queue->lock, queue_flag);
+    kfree(aes_con);
+    spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+}
+
+/* \fn static inline struct aes_container *aes_container_cast (
+ *                     struct scatterlist *dst)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Locate the structure aes_container in memory.
+ * \param *areq Pointer to memory location where ablkcipher_request is located
+ * \return *aes_cointainer The function pointer to aes_container
+*/
+static inline struct aes_container *aes_container_cast (
+               struct ablkcipher_request *areq)
+{
+    return container_of(areq, struct aes_container, arequest);
+}
+
+
+/* \fn static int process_next_packet(struct aes_container *aes_con, struct ablkcipher_request *areq,
+ * \                                  int state)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Process next packet to be encrypt/decrypt
+ * \param *aes_con  AES container structure
+ * \param *areq Pointer to memory location where ablkcipher_request is located 
+ * \param state The state of the current packet (part of scatterlist or new packet)
+ * \return -EINVAL: error, -EINPROGRESS: Crypto still running, 1: no more scatterlist 
+*/
+
+static int process_next_packet(struct aes_container *aes_con, struct ablkcipher_request *areq,
+                               int state)
+{
+    u8 *iv;
+    int mode, dir, err = -EINVAL;
+    unsigned long queue_flag;
+    u32 inc, nbytes, remain, chunk_size;
+    struct scatterlist *src = NULL;
+    struct scatterlist *dst = NULL;
+    struct crypto_ablkcipher *cipher;
+    struct aes_ctx *ctx;
+
+    spin_lock_irqsave(&aes_queue->lock, queue_flag);
+
+    dir = aes_con->encdec;
+    mode = aes_con->mode;
+    iv = aes_con->iv;
+    if (state & PROCESS_SCATTER) {
+        src = scatterwalk_sg_next(areq->src);
+        dst = scatterwalk_sg_next(areq->dst);
+        if (!src || !dst) {
+            spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+            return 1;
+        }
+    }
+    else if (state & PROCESS_NEW_PACKET) { 
+        src = areq->src;
+        dst = areq->dst;
+    }
+
+    remain = aes_con->bytes_processed;
+    chunk_size = src->length;
+
+    if (remain > DEU_MAX_PACKET_SIZE)
+       inc = DEU_MAX_PACKET_SIZE;
+    else if (remain > chunk_size)
+       inc = chunk_size;
+    else
+       inc = remain;
+
+    remain -= inc;
+    aes_con->nbytes = inc;
+    if (state & PROCESS_SCATTER) {
+        aes_con->src_buf += aes_con->nbytes;
+        aes_con->dst_buf += aes_con->nbytes;
+    }
+
+    lq_sg_init(aes_con, src, dst);
+
+    nbytes = aes_con->nbytes;
+
+    //printk("debug - Line: %d, func: %s, reqsize: %d, scattersize: %d\n",
+    //          __LINE__, __func__, nbytes, chunk_size);
+
+    cipher = crypto_ablkcipher_reqtfm(areq);
+    ctx = crypto_ablkcipher_ctx(cipher);
+
+
+    if (aes_queue->hw_status == AES_IDLE)
+        aes_queue->hw_status = AES_STARTED;
+
+    aes_con->bytes_processed -= aes_con->nbytes;
+    err = ablkcipher_enqueue_request(&aes_queue->list, &aes_con->arequest);
+    if (err == -EBUSY) {
+        spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+        printk("Failed to enqueue request, ln: %d, err: %d\n",
+                __LINE__, err);
+        return -EINVAL;
+    }
+
+    spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+
+    err = lq_deu_aes_core(ctx, aes_con->dst_buf, aes_con->src_buf, iv, nbytes, dir, mode);
+    return err;
+
+}
+
+/* \fn static void process_queue (unsigned long data)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief tasklet to signal the dequeuing of the next packet to be processed
+ * \param unsigned long data Not used
+ * \return void 
+*/
+
+static void process_queue(unsigned long data)
+{
+
+    DEU_WAKEUP_EVENT(deu_dma_priv.deu_thread_wait, AES_ASYNC_EVENT,
+                deu_dma_priv.aes_event_flags);
+}
+
+
+/* \fn static int aes_crypto_thread (void *data)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief AES thread that handles crypto requests from upper layer & DMA
+ * \param *data Not used
+ * \return -EINVAL: DEU failure, -EBUSY: DEU HW busy, 0: exit thread
+*/
+static int aes_crypto_thread (void *data)
+{
+    struct aes_container *aes_con = NULL;
+    struct ablkcipher_request *areq = NULL;
+    int err;
+    unsigned long queue_flag;
+    
+    daemonize("lq_aes_thread");
+    printk("AES Queue Manager Starting\n");
+
+    while (1)
+    {
+        DEU_WAIT_EVENT(deu_dma_priv.deu_thread_wait, AES_ASYNC_EVENT, 
+                       deu_dma_priv.aes_event_flags);
+
+        spin_lock_irqsave(&aes_queue->lock, queue_flag);
+   
+        /* wait to prevent starting a crypto session before
+        * exiting the dma interrupt thread.
+        */
+        if (aes_queue->hw_status == AES_STARTED) {
+            areq = ablkcipher_dequeue_request(&aes_queue->list);
+            aes_con = aes_container_cast(areq);
+            aes_queue->hw_status = AES_BUSY;
+        }
+        else if (aes_queue->hw_status == AES_IDLE) {
+            areq = ablkcipher_dequeue_request(&aes_queue->list);
+            aes_con = aes_container_cast(areq);
+            aes_queue->hw_status = AES_STARTED;
+        }
+        else if (aes_queue->hw_status == AES_BUSY) {
+            areq = ablkcipher_dequeue_request(&aes_queue->list);
+            aes_con = aes_container_cast(areq);
+       }
+        else if (aes_queue->hw_status == AES_COMPLETED) {
+            lq_sg_complete(aes_con);
+            aes_queue->hw_status = AES_IDLE;
+            areq->base.complete(&areq->base, 0);
+            spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+           return 0;
+       }
+        //printk("debug ln: %d, bytes proc: %d\n", __LINE__, aes_con->bytes_processed);
+        spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+
+        if (!aes_con) {
+           printk("AES_CON return null\n");
+           goto aes_done;
+       }
+
+        if (aes_con->bytes_processed == 0) {
+            goto aes_done;
+        }
+       
+        /* Process new packet or the next packet in a scatterlist */
+        if (aes_con->flag & PROCESS_NEW_PACKET) {
+           aes_con->flag = PROCESS_SCATTER;
+           err = process_next_packet(aes_con, areq, PROCESS_NEW_PACKET);
+        }
+        else 
+            err = process_next_packet(aes_con, areq, PROCESS_SCATTER);
+        if (err == -EINVAL) {
+            areq->base.complete(&areq->base, err);
+            lq_sg_complete(aes_con);
+            printk("src/dst returned -EINVAL in func: %s\n", __func__);
+        }
+        else if (err > 0) {
+            printk("src/dst returned zero in func: %s\n", __func__);
+            goto aes_done; 
+        }
+        
+       continue;
+
+aes_done:
+        //printk("debug line - %d, func: %s, qlen: %d\n", __LINE__, __func__, aes_queue->list.qlen);
+        areq->base.complete(&areq->base, 0);    
+        lq_sg_complete(aes_con);
+
+        spin_lock_irqsave(&aes_queue->lock, queue_flag);
+        if (aes_queue->list.qlen > 0) {
+            spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+            tasklet_schedule(&aes_queue->aes_task); 
+        }
+        else {
+            aes_queue->hw_status = AES_IDLE;
+            spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+        }
+    } //while(1)
+    
+    return 0;
+} 
+
+/* \fn static int lq_aes_queue_mgr(struct aes_ctx *ctx, struct ablkcipher_request *areq, 
+                            u8 *iv, int dir, int mode)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief starts the process of queuing DEU requests
+ * \param *ctx crypto algo contax
+ * \param *areq Pointer to the balkcipher requests
+ * \param *iv Pointer to intput vector location
+ * \param dir Encrypt/Decrypt
+ * \mode The mode AES algo is running
+ * \return 0 if success
+*/
+
+static int lq_aes_queue_mgr(struct aes_ctx *ctx, struct ablkcipher_request *areq, 
+                            u8 *iv, int dir, int mode)
+{
+    int err = -EINVAL; 
+    unsigned long queue_flag;
+    struct scatterlist *src = areq->src;
+    struct scatterlist *dst = areq->dst;
+    struct aes_container *aes_con = NULL;
+    u32 remain, inc, nbytes = areq->nbytes;
+    u32 chunk_bytes = src->length;
+    
+    aes_con = (struct aes_container *)kmalloc(sizeof(struct aes_container),
+                                              GFP_KERNEL);
+
+    if (!(aes_con)) {
+        printk("Cannot allocate memory for AES container, fn %s, ln %d\n",
+               __func__, __LINE__);
+       return -ENOMEM;
+    }
+
+    /* AES encrypt/decrypt mode */
+    if (mode == 5) {
+        nbytes = AES_BLOCK_SIZE;
+        chunk_bytes = AES_BLOCK_SIZE;
+        mode = 0;
+    }
+
+    aes_con->bytes_processed = nbytes;
+    aes_con->arequest = *(areq);
+    remain = nbytes;
+
+    //printk("debug - Line: %d, func: %s, reqsize: %d, scattersize: %d\n",
+    //        __LINE__, __func__, nbytes, chunk_bytes);
+
+    if (remain > DEU_MAX_PACKET_SIZE) 
+       inc = DEU_MAX_PACKET_SIZE;
+    else if (remain > chunk_bytes)
+       inc = chunk_bytes; 
+    else
+       inc = remain;
+         
+    remain -= inc;
+    lq_sg_init(aes_con, src, dst);  
+
+    if (remain <= 0)
+        aes_con->complete = 1;
+    else
+        aes_con->complete = 0;
+
+    aes_con->nbytes = inc;
+    aes_con->iv = iv;
+    aes_con->mode = mode;
+    aes_con->encdec = dir;
+    spin_lock_irqsave(&aes_queue->lock, queue_flag);
+
+    if (aes_queue->hw_status == AES_STARTED || aes_queue->hw_status == AES_BUSY ||
+             aes_queue->list.qlen > 0) {
+
+        aes_con->flag = PROCESS_NEW_PACKET;
+        err = ablkcipher_enqueue_request(&aes_queue->list, &aes_con->arequest);
+
+         /* max queue length reached */
+        if (err == -EBUSY) {
+            spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+            printk("Unable to enqueue request ln: %d, err: %d\n", __LINE__, err);
+             return err;
+         }
+
+        spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+        return -EINPROGRESS;
+    }
+    else if (aes_queue->hw_status == AES_IDLE) 
+        aes_queue->hw_status = AES_STARTED;
+
+    aes_con->flag = PROCESS_SCATTER;
+    aes_con->bytes_processed -= aes_con->nbytes;
+    /* or enqueue the whole structure so as to get back the info 
+     * at the moment that it's queued. nbytes might be different */
+    err = ablkcipher_enqueue_request(&aes_queue->list, &aes_con->arequest);
+
+    if (err == -EBUSY) {
+        spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+        printk("Unable to enqueue request ln: %d, err: %d\n", __LINE__, err);
+        return err;
+    }
+
+    spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+    return lq_deu_aes_core(ctx, aes_con->dst_buf, aes_con->src_buf, iv, inc, dir, mode);
+
+}
+
+/* \fn static int aes_setkey(struct crypto_ablkcipher *tfm, const u8 *in_key,
+ *                     unsigned int keylen)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Sets AES key
+ * \param *tfm Pointer to the ablkcipher transform
+ * \param *in_key Pointer to input keys
+ * \param key_len Length of the AES keys
+ * \return 0 is success, -EINVAL if bad key length
+*/
+
+static int aes_setkey(struct crypto_ablkcipher *tfm, const u8 *in_key,
+                      unsigned int keylen)
+{
+    struct aes_ctx *ctx = crypto_ablkcipher_ctx(tfm); 
+    unsigned long *flags = (unsigned long *) &tfm->base.crt_flags;
+
+    DPRINTF(2, "set_key in %s\n", __FILE__);
+
+    if (keylen != 16 && keylen != 24 && keylen != 32) {
+        *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+        return -EINVAL;
+    }
+
+    ctx->key_length = keylen;
+    DPRINTF(0, "ctx @%p, keylen %d, ctx->key_length %d\n", ctx, keylen, ctx->key_length);
+    memcpy ((u8 *) (ctx->buf), in_key, keylen);
+
+    return 0;
+
+}
+
+/* \fn static int aes_generic_setkey(struct crypto_ablkcipher *tfm, const u8 *in_key,
+ *                     unsigned int keylen)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Sets AES key
+ * \param *tfm Pointer to the ablkcipher transform
+ * \param *key Pointer to input keys
+ * \param keylen Length of AES keys
+ * \return 0 is success, -EINVAL if bad key length
+*/
+
+static int aes_generic_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
+                              unsigned int keylen)
+{
+   return aes_setkey(tfm, key, keylen);
+}
+
+/* \fn static int rfc3686_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *in_key,
+ *                     unsigned int keylen)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Sets AES key
+ * \param *tfm Pointer to the ablkcipher transform
+ * \param *in_key Pointer to input keys
+ * \param key_len Length of the AES keys
+ * \return 0 is success, -EINVAL if bad key length
+*/
+
+static int rfc3686_aes_setkey(struct crypto_ablkcipher *tfm,
+                             const u8 *in_key, unsigned int keylen)
+{
+    struct aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
+    unsigned long *flags = (unsigned long *)&tfm->base.crt_flags;
+
+    DPRINTF(2, "ctr_rfc3686_aes_set_key in %s\n", __FILE__);
+
+    memcpy(ctx->nonce, in_key + (keylen - CTR_RFC3686_NONCE_SIZE),
+           CTR_RFC3686_NONCE_SIZE);
+
+    keylen -= CTR_RFC3686_NONCE_SIZE; // remove 4 bytes of nonce
+
+    if (keylen != 16 && keylen != 24 && keylen != 32) {
+        *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+        return -EINVAL;
+    }
+
+    ctx->key_length = keylen;
+
+    memcpy ((u8 *) (ctx->buf), in_key, keylen);
+
+    return 0;
+}
+
+/* \fn static int aes_encrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Encrypt function for AES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int aes_encrypt (struct ablkcipher_request *areq)
+{
+    struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+    struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+    return lq_aes_queue_mgr(ctx, areq, NULL, CRYPTO_DIR_ENCRYPT, 5);
+
+}
+
+/* \fn static int aes_decrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Decrypt function for AES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+static int aes_decrypt (struct ablkcipher_request *areq)
+{
+    struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+    struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+    return lq_aes_queue_mgr(ctx, areq, NULL, CRYPTO_DIR_DECRYPT, 5);
+}
+
+/* \fn static int ecb_aes_decrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Encrypt function for AES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int ecb_aes_encrypt (struct ablkcipher_request *areq)
+{
+    struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+    struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+    return lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_ENCRYPT, 0);
+
+}
+/* \fn static int ecb_aes_decrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Decrypt function for AES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/ 
+static int ecb_aes_decrypt(struct ablkcipher_request *areq)
+
+{
+    struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+    struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+    return lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_DECRYPT, 0);
+}
+
+/* \fn static int cbc_aes_encrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Encrypt function for AES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int cbc_aes_encrypt (struct ablkcipher_request *areq)
+{
+    struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+    struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+    return lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_ENCRYPT, 1);
+
+}
+
+/* \fn static int cbc_aes_decrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Decrypt function for AES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int cbc_aes_decrypt(struct ablkcipher_request *areq)
+{
+    struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+    struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+    return lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_DECRYPT, 1);
+}
+#if 0
+static int ofb_aes_encrypt (struct ablkcipher_request *areq)
+{
+    struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+    struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+    return lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_ENCRYPT, 2);
+
+}
+
+static int ofb_aes_decrypt(struct ablkcipher_request *areq)
+{
+    struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+    struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+    return lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_DECRYPT, 2);
+}
+
+static int cfb_aes_encrypt (struct ablkcipher_request *areq)
+{
+    struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+    struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+    return lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_ENCRYPT, 3);
+
+}
+
+static int cfb_aes_decrypt(struct ablkcipher_request *areq)
+{
+    struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+    struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+    return lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_DECRYPT, 3);
+}
+#endif 
+
+/* \fn static int ctr_aes_encrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Encrypt function for AES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int ctr_aes_encrypt (struct ablkcipher_request *areq)
+{
+    struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+    struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+   
+    return lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_ENCRYPT, 4);
+
+}
+
+/* \fn static int ctr_aes_decrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Decrypt function for AES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int ctr_aes_decrypt(struct ablkcipher_request *areq)
+{
+    struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+    struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+    return lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_DECRYPT, 4);
+}
+
+/* \fn static int rfc3686_aes_encrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Encrypt function for AES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int rfc3686_aes_encrypt(struct ablkcipher_request *areq)
+{
+    struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+    struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+    int ret;
+    u8 *info = areq->info;
+    u8 rfc3686_iv[16];
+
+    memcpy(rfc3686_iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE);
+    memcpy(rfc3686_iv + CTR_RFC3686_NONCE_SIZE, info, CTR_RFC3686_IV_SIZE);
+
+    /* initialize counter portion of counter block */
+    *(__be32 *)(rfc3686_iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) =
+        cpu_to_be32(1);
+
+    areq->info = rfc3686_iv;
+    ret = lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_ENCRYPT, 4);
+    areq->info = info;
+    return ret;
+}
+
+/* \fn static int rfc3686_aes_decrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Decrypt function for AES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int rfc3686_aes_decrypt(struct ablkcipher_request *areq)
+{
+    struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+    struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+    int ret;
+    u8 *info = areq->info;
+    u8 rfc3686_iv[16];
+
+    /* set up counter block */
+    memcpy(rfc3686_iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE);
+    memcpy(rfc3686_iv + CTR_RFC3686_NONCE_SIZE, info, CTR_RFC3686_IV_SIZE);
+
+    /* initialize counter portion of counter block */
+    *(__be32 *)(rfc3686_iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) =
+        cpu_to_be32(1);
+
+    areq->info = rfc3686_iv;
+    ret = lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_DECRYPT, 4);
+    areq->info = info;
+    return ret;
+}
+
+struct lq_aes_alg {
+    struct crypto_alg alg;
+};
+
+/* AES supported algo array */
+static struct lq_aes_alg aes_drivers_alg[] = {
+     {
+         .alg = {
+           .cra_name       = "aes",
+           .cra_driver_name = "ifxdeu-aes",
+           .cra_flags       = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+           .cra_blocksize   = AES_BLOCK_SIZE,
+           .cra_ctxsize     = sizeof(struct aes_ctx),
+           .cra_type        = &crypto_ablkcipher_type,
+           .cra_priority    = 300,
+           .cra_module      = THIS_MODULE,
+           .cra_ablkcipher = {
+                                .setkey = aes_setkey,
+                                .encrypt = aes_encrypt,
+                                .decrypt = aes_decrypt,
+                                .geniv = "eseqiv",
+                                .min_keysize = AES_MIN_KEY_SIZE,
+                                .max_keysize = AES_MAX_KEY_SIZE,
+                                .ivsize = AES_BLOCK_SIZE,
+             }
+          }
+     },{
+     .alg = {
+           .cra_name        = "ecb(aes)",
+           .cra_driver_name = "ifxdeu-ecb(aes)",
+           .cra_flags       = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+           .cra_blocksize   = AES_BLOCK_SIZE,
+           .cra_ctxsize     = sizeof(struct aes_ctx),
+           .cra_type        = &crypto_ablkcipher_type,
+           .cra_priority    = 300,
+           .cra_module      = THIS_MODULE,
+           .cra_ablkcipher = {
+                                .setkey = aes_generic_setkey,
+                                .encrypt = ecb_aes_encrypt,
+                                .decrypt = ecb_aes_decrypt,
+                                .geniv = "eseqiv",
+                                .min_keysize = AES_MIN_KEY_SIZE,
+                                .max_keysize = AES_MAX_KEY_SIZE,
+                                .ivsize = AES_BLOCK_SIZE,
+             }      
+          }
+     },{
+         .alg = {
+           .cra_name        = "cbc(aes)",
+           .cra_driver_name = "ifxdeu-cbc(aes)",
+           .cra_flags       = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+           .cra_blocksize   = AES_BLOCK_SIZE,
+           .cra_ctxsize     = sizeof(struct aes_ctx),
+           .cra_type        = &crypto_ablkcipher_type,
+           .cra_priority    = 300,
+           .cra_module      = THIS_MODULE,
+           .cra_ablkcipher = {
+                                .setkey = aes_generic_setkey,
+                                .encrypt = cbc_aes_encrypt,
+                                .decrypt = cbc_aes_decrypt,
+                                .geniv = "eseqiv",
+                                .min_keysize = AES_MIN_KEY_SIZE,
+                                .max_keysize = AES_MAX_KEY_SIZE,
+                                .ivsize = AES_BLOCK_SIZE,
+                }
+          }
+     },{
+         .alg = {
+           .cra_name        = "ctr(aes)",
+           .cra_driver_name = "ifxdeu-ctr(aes)",
+           .cra_flags       = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+           .cra_blocksize   = AES_BLOCK_SIZE,
+           .cra_ctxsize     = sizeof(struct aes_ctx),
+           .cra_type        = &crypto_ablkcipher_type,
+           .cra_priority    = 300,
+           .cra_module      = THIS_MODULE,
+           .cra_ablkcipher = {
+                                .setkey = aes_generic_setkey,
+                                .encrypt = ctr_aes_encrypt,
+                                .decrypt = ctr_aes_decrypt,
+                                .geniv = "eseqiv",
+                                .min_keysize = AES_MIN_KEY_SIZE,
+                                .max_keysize = AES_MAX_KEY_SIZE,
+                                .ivsize = AES_BLOCK_SIZE,
+                }
+         }
+     },{
+     .alg = {
+           .cra_name        = "rfc3686(ctr(aes))",
+           .cra_driver_name = "ifxdeu-rfc3686(ctr(aes))",
+           .cra_flags       = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+           .cra_blocksize   = AES_BLOCK_SIZE,
+           .cra_ctxsize     = sizeof(struct aes_ctx),
+           .cra_type        = &crypto_ablkcipher_type,
+           .cra_priority    = 300,
+           .cra_module      = THIS_MODULE,
+           .cra_ablkcipher = {
+                                .setkey = rfc3686_aes_setkey,
+                                .encrypt = rfc3686_aes_encrypt,
+                                .decrypt = rfc3686_aes_decrypt,
+                                .geniv = "eseqiv",
+                                .min_keysize = AES_MIN_KEY_SIZE,
+                                .max_keysize = CTR_RFC3686_MAX_KEY_SIZE,
+                               //.max_keysize = AES_MAX_KEY_SIZE,
+                                //.ivsize = CTR_RFC3686_IV_SIZE,
+                               .ivsize = AES_BLOCK_SIZE,  // else cannot reg
+               }
+         }
+      }
+};
+
+/* \fn int __init lqdeu_async_aes_init (void)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Initializes the Async. AES driver
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+int __init lqdeu_async_aes_init (void)
+{
+    int i, j, ret = -EINVAL; 
+
+#define IFX_DEU_DRV_VERSION  "2.0.0"
+    printk(KERN_INFO "Lantiq Technologies DEU Driver version %s\n", IFX_DEU_DRV_VERSION);
+
+    for (i = 0; i < ARRAY_SIZE(aes_drivers_alg); i++) {
+        ret = crypto_register_alg(&aes_drivers_alg[i].alg);
+       printk("driver: %s\n", aes_drivers_alg[i].alg.cra_name);
+        if (ret)
+            goto aes_err;
+    }
+
+    aes_chip_init();
+
+    CRTCL_SECT_INIT;
+
+
+    printk (KERN_NOTICE "Lantiq DEU AES initialized %s %s.\n", 
+           disable_multiblock ? "" : " (multiblock)", disable_deudma ? "" : " (DMA)");
+    
+    return ret;
+
+aes_err:
+    
+    for (j = 0; j < i; j++) 
+        crypto_unregister_alg(&aes_drivers_alg[j].alg);
+    
+    printk(KERN_ERR "Lantiq %s driver initialization failed!\n", (char *)&aes_drivers_alg[i].alg.cra_driver_name);
+    return ret;
+
+ctr_rfc3686_aes_err:
+    for (i = 0; i < ARRAY_SIZE(aes_drivers_alg); i++) {
+        if (!strcmp((char *)&aes_drivers_alg[i].alg.cra_name, "rfc3686(ctr(aes))"))
+            crypto_unregister_alg(&aes_drivers_alg[j].alg);
+    }
+    printk (KERN_ERR "Lantiq ctr_rfc3686_aes initialization failed!\n");
+    return ret;
+}
+
+/*! \fn void __exit ifxdeu_fini_aes (void)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief unregister aes driver
+*/
+void __exit lqdeu_fini_async_aes (void)
+{
+    int i;
+  
+    for (i = 0; i < ARRAY_SIZE(aes_drivers_alg); i++)
+        crypto_unregister_alg(&aes_drivers_alg[i].alg);
+
+    aes_queue->hw_status = AES_COMPLETED;
+
+    DEU_WAKEUP_EVENT(deu_dma_priv.deu_thread_wait, AES_ASYNC_EVENT,
+                                 deu_dma_priv.aes_event_flags);   
+
+    kfree(aes_queue); 
+
+}
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_async_des.c b/package/platform/lantiq/ltq-deu/src/ifxmips_async_des.c
new file mode 100644 (file)
index 0000000..9c593ae
--- /dev/null
@@ -0,0 +1,954 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_async_des.c
+** PROJECT      : IFX UEIP
+** MODULES      : DEU Module
+**
+** DATE         : October 11, 2010
+** AUTHOR       : Mohammad Firdaus
+** DESCRIPTION  : Data Encryption Unit Driver for DES Algorithm
+** COPYRIGHT    :       Copyright (c) 2010
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author             $Comment
+** 08,Sept 2009 Mohammad Firdaus    Initial UEIP release
+** 11, Oct 2010 Mohammad Firdaus    Kernel Port incl. Async. Ablkcipher mode
+** 21,March 2011 Mohammad Firdaus   Changes for Kernel 2.6.32 and IPSec integration
+*******************************************************************************/
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief ifx DEU driver module
+*/
+
+/*!
+  \file ifxmips_async_des.c
+  \ingroup IFX_DEU
+  \brief DES Encryption Driver main file
+*/
+
+/*!
+ \defgroup IFX_DES_FUNCTIONS IFX_DES_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief IFX DES driver Functions
+*/
+
+#include <linux/wait.h>
+#include <linux/crypto.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <crypto/ctr.h>
+#include <crypto/aes.h>
+#include <crypto/algapi.h>
+#include <crypto/scatterwalk.h>
+
+#include <asm/ifx/ifx_regs.h>
+#include <asm/ifx/ifx_types.h>
+#include <asm/ifx/common_routines.h>
+#include <asm/ifx/irq.h>
+#include <asm/ifx/ifx_pmu.h>
+#include <asm/ifx/ifx_gpio.h>
+#include <asm/kmap_types.h>
+
+#include "ifxmips_deu.h"
+
+#if defined(CONFIG_DANUBE)
+#include "ifxmips_deu_danube.h"
+extern int ifx_danube_pre_1_4;
+#elif defined(CONFIG_AR9)
+#include "ifxmips_deu_ar9.h"
+#elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
+#include "ifxmips_deu_vr9.h"
+#else
+#error "Unkown platform"
+#endif
+
+/* DMA specific header and variables */
+
+spinlock_t des_lock;
+#define CRTCL_SECT_INIT        spin_lock_init(&des_lock)
+#define CRTCL_SECT_START       spin_lock_irqsave(&des_lock, flag)
+#define CRTCL_SECT_END         spin_unlock_irqrestore(&des_lock, flag)
+
+/* Preprocessor declerations */
+#ifdef CRYPTO_DEBUG
+extern char debug_level;
+#define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
+#else
+#define DPRINTF(level, format, args...)
+#endif
+//#define DES_3DES_START  IFX_DES_CON
+#define DES_KEY_SIZE            8
+#define DES_EXPKEY_WORDS        32
+#define DES_BLOCK_SIZE          8
+#define DES3_EDE_KEY_SIZE       (3 * DES_KEY_SIZE)
+#define DES3_EDE_EXPKEY_WORDS   (3 * DES_EXPKEY_WORDS)
+#define DES3_EDE_BLOCK_SIZE     DES_BLOCK_SIZE
+
+/* Function Declaration to prevent warning messages */
+void des_chip_init (void);
+u32 endian_swap(u32 input);
+u32 input_swap(u32 input);
+int aes_memory_allocate(int value);
+int des_memory_allocate(int value);
+void memory_release(u32 *buffer);
+u32* memory_alignment(const u8 *arg, u32 *buff_alloc, int in_out, int nbytes);
+void aes_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+void des_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+
+static int lq_deu_des_core (void *ctx_arg, u8 *out_arg, const u8 *in_arg,
+             u8 *iv_arg, u32 nbytes, int encdec, int mode);
+
+struct des_ctx {
+        int controlr_M;
+        int key_length;
+        u8 iv[DES_BLOCK_SIZE];
+        u32 expkey[DES3_EDE_EXPKEY_WORDS];
+};
+
+
+static int disable_multiblock = 0;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+module_param(disable_multiblock, int, 0);
+#else
+MODULE_PARM_DESC(disable_multiblock, "Disable encryption of whole multiblock buffers");
+#endif
+
+static int disable_deudma = 1;
+
+struct des_container {
+    u8 *iv;
+    u8 *dst_buf;
+    u8 *src_buf;
+    int mode;
+    int encdec;
+    int complete;
+    int flag;
+
+    u32 bytes_processed;
+    u32 nbytes;
+
+    struct ablkcipher_request arequest;
+};
+
+des_priv_t *des_queue;
+extern deu_drv_priv_t deu_dma_priv;
+
+void hexdump1(unsigned char *buf, unsigned int len)
+{
+        print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
+                        16, 1,
+                        buf, len, false);
+}
+
+
+/*! \fn int lq_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, unsigned int keylen)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief sets DES key
+ *  \param tfm linux crypto algo transform
+ *  \param key input key
+ *  \param keylen key length
+*/
+static int lq_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
+                         unsigned int keylen)
+{
+        struct des_ctx *dctx = crypto_ablkcipher_ctx(tfm);
+
+        //printk("setkey in %s\n", __FILE__);
+
+        dctx->controlr_M = 0;   // des
+        dctx->key_length = keylen;
+
+        memcpy ((u8 *) (dctx->expkey), key, keylen);
+
+        return 0;
+}
+
+/*! \fn int lq_des3_ede_setkey(struct crypto_ablkcipher *tfm, const u8 *key, unsigned int keylen)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief sets DES key
+ *  \param tfm linux crypto algo transform
+ *  \param key input key
+ *  \param keylen key length
+*/
+
+static int lq_des3_ede_setkey(struct crypto_ablkcipher *tfm, const u8 *in_key,
+                      unsigned int keylen)
+{
+    struct des_ctx *dctx = crypto_ablkcipher_ctx(tfm);
+
+    //printk("setkey in %s\n", __FILE__);
+
+    dctx->controlr_M = keylen/8 + 1;   // des
+    dctx->key_length = keylen;
+
+    memcpy ((u8 *) (dctx->expkey), in_key, keylen);
+
+    return 0;
+}
+
+/*! \fn void ifx_deu_des_core(void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief main interface to DES hardware
+ *  \param ctx_arg crypto algo context
+ *  \param out_arg output bytestream
+ *  \param in_arg input bytestream
+ *  \param iv_arg initialization vector
+ *  \param nbytes length of bytestream
+ *  \param encdec 1 for encrypt; 0 for decrypt
+ *  \param mode operation mode such as ebc, cbc
+*/
+
+static int lq_deu_des_core (void *ctx_arg, u8 *out_arg, const u8 *in_arg,
+             u8 *iv_arg, u32 nbytes, int encdec, int mode)
+{
+        volatile struct des_t *des = (struct des_t *) DES_3DES_START;
+        struct des_ctx *dctx = ctx_arg;
+        u32 *key = dctx->expkey;
+        unsigned long flag;
+
+        int i = 0;
+        int nblocks = 0;
+
+        CRTCL_SECT_START;
+
+        des->controlr.M = dctx->controlr_M;
+        if (dctx->controlr_M == 0)      // des
+        {
+                des->K1HR = DEU_ENDIAN_SWAP(*((u32 *) key + 0));
+                des->K1LR = DEU_ENDIAN_SWAP(*((u32 *) key + 1));
+
+        }
+        else {
+                /* Hardware Section */
+                switch (dctx->key_length) {
+                case 24:
+                        des->K3HR = DEU_ENDIAN_SWAP(*((u32 *) key + 4));
+                        des->K3LR = DEU_ENDIAN_SWAP(*((u32 *) key + 5));
+                        /* no break; */
+
+                case 16:
+                        des->K2HR = DEU_ENDIAN_SWAP(*((u32 *) key + 2));
+                        des->K2LR = DEU_ENDIAN_SWAP(*((u32 *) key + 3));
+
+                        /* no break; */
+                case 8:
+                        des->K1HR = DEU_ENDIAN_SWAP(*((u32 *) key + 0));
+                        des->K1LR = DEU_ENDIAN_SWAP(*((u32 *) key + 1));
+                        break;
+
+                default:
+                        CRTCL_SECT_END;
+                        return -EINVAL;
+                }
+        }
+
+        des->controlr.E_D = !encdec;    //encryption
+        des->controlr.O = mode; //0 ECB 1 CBC 2 OFB 3 CFB 4 CTR hexdump(prin,sizeof(*des));
+
+        if (mode > 0) {
+                des->IVHR = DEU_ENDIAN_SWAP(*(u32 *) iv_arg);
+                des->IVLR = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1));
+        };
+
+    /* memory alignment issue */
+    dword_mem_aligned_in = (u32 *) DEU_DWORD_REORDERING(in_arg, des_buff_in, BUFFER_IN, nbytes);
+    
+    deu_priv->deu_rx_buf = (u32 *) out_arg;
+    deu_priv->deu_rx_len = nbytes;
+
+    dma->controlr.ALGO = 0;       //DES
+    des->controlr.DAU = 0;
+    dma->controlr.BS = 0;
+    dma->controlr.EN = 1;
+
+    while (des->controlr.BUS) {
+    };
+
+    wlen = dma_device_write (dma_device, (u8 *) dword_mem_aligned_in, nbytes, NULL);
+    if (wlen != nbytes) {
+        dma->controlr.EN = 0;
+        CRTCL_SECT_END;
+        printk (KERN_ERR "[%s %s %d]: dma_device_write fail!\n", __FILE__, __func__, __LINE__);
+        return -EINVAL;
+    }
+
+
+    /* Prepare Rx buf length used in dma psuedo interrupt */
+    outcopy = (u32 *) DEU_DWORD_REORDERING(out_arg, des_buff_out, BUFFER_OUT, nbytes);
+    deu_priv->outcopy = outcopy;
+    deu_priv->event_src = DES_ASYNC_EVENT;
+     
+    if (mode > 0) {
+        *(u32 *) iv_arg = DEU_ENDIAN_SWAP(des->IVHR);
+        *((u32 *) iv_arg + 1) = DEU_ENDIAN_SWAP(des->IVLR);
+    };
+
+    CRTCL_SECT_END; 
+
+    return -EINPROGRESS;
+
+}
+
+static int count_sgs(struct scatterlist *sl, unsigned int total_bytes)
+{
+        int i = 0;
+
+        do {
+                total_bytes -= sl[i].length;
+                i++;
+
+        } while (total_bytes > 0);
+
+        return i;
+}
+
+/* \fn static inline struct des_container *des_container_cast (
+ *                     struct scatterlist *dst)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Locate the structure des_container in memory.
+ * \param *areq Pointer to memory location where ablkcipher_request is located
+ * \return *des_cointainer The function pointer to des_container
+*/
+
+static inline struct des_container *des_container_cast(
+                        struct ablkcipher_request *areq)
+{
+    return container_of(areq, struct des_container, arequest);
+}
+
+/* \fn static void lq_sg_complete(struct des_container *des_con)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Free the used up memory after encryt/decrypt.
+*/
+
+static void lq_sg_complete(struct des_container *des_con)
+{
+    unsigned long queue_flag;
+  
+    spin_lock_irqsave(&des_queue->lock, queue_flag);
+    kfree(des_con); 
+    spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+}
+
+/* \fn void lq_sg_init(struct scatterlist *src,
+ *                     struct scatterlist *dst)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Maps the scatterlists into a source/destination page.
+ * \param *src Pointer to the source scatterlist
+ * \param *dst Pointer to the destination scatterlist
+*/
+
+static void lq_sg_init(struct des_container *des_con, struct scatterlist *src,
+                       struct scatterlist *dst)
+{
+    struct page *dst_page, *src_page;
+
+    src_page = sg_virt(src);
+    des_con->src_buf = (char *) src_page;
+
+    dst_page = sg_virt(dst);
+    des_con->dst_buf = (char *) dst_page;
+}
+
+/* \fn static int process_next_packet(struct des_container *des_con,  struct ablkcipher_request *areq,
+ *                                     int state)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Process the next packet after dequeuing the packet from crypto queue
+ * \param *des_con  Pointer to DES container structure
+ * \param *areq     Pointer to ablkcipher_request container
+ * \param state     State of the packet (scattered packet or new packet to be processed)
+ * \return -EINVAL: DEU failure, -EINPROGRESS: DEU encrypt/decrypt in progress, 1: no scatterlist left
+*/
+
+static int process_next_packet(struct des_container *des_con,  struct ablkcipher_request *areq,
+                               int state) 
+{
+    u8 *iv;
+    int mode, encdec, err = -EINVAL;
+    u32 remain, inc, chunk_size, nbytes;
+    struct scatterlist *src = NULL;
+    struct scatterlist *dst = NULL;
+    struct crypto_ablkcipher *cipher;
+    struct des_ctx *ctx;
+    unsigned long queue_flag;
+
+    spin_lock_irqsave(&des_queue->lock, queue_flag);
+
+    mode = des_con->mode;
+    encdec = des_con->encdec;
+    iv = des_con->iv;
+
+    if (state & PROCESS_SCATTER) {
+        src = scatterwalk_sg_next(areq->src);
+        dst = scatterwalk_sg_next(areq->dst);
+
+        if (!src || !dst) {
+            spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+           return 1;
+        }
+    }
+    else if (state & PROCESS_NEW_PACKET) {
+        src = areq->src;
+        dst = areq->dst;
+    }
+
+    remain = des_con->bytes_processed;
+    chunk_size = src->length;
+
+    //printk("debug ln: %d, func: %s, reqsize: %d, scattersize: %d\n", 
+//             __LINE__, __func__, areq->nbytes, chunk_size);
+
+    if (remain > DEU_MAX_PACKET_SIZE)
+        inc = DEU_MAX_PACKET_SIZE;
+    else if(remain > chunk_size)
+        inc = chunk_size;
+    else
+        inc = remain;
+    remain -= inc;
+    des_con->nbytes = inc;
+    
+    if (state & PROCESS_SCATTER) {
+        des_con->src_buf += des_con->nbytes;
+        des_con->dst_buf += des_con->nbytes;
+    } 
+
+    lq_sg_init(des_con, src, dst);
+
+    nbytes = des_con->nbytes;
+
+    cipher = crypto_ablkcipher_reqtfm(areq);
+    ctx = crypto_ablkcipher_ctx(cipher);
+
+    if (des_queue->hw_status == DES_IDLE) {
+        des_queue->hw_status = DES_STARTED;
+    }
+    
+    des_con->bytes_processed -= des_con->nbytes;
+    err = ablkcipher_enqueue_request(&des_queue->list, &des_con->arequest);
+    if (err == -EBUSY) {
+        printk("Failed to enqueue request, ln: %d, err: %d\n",
+               __LINE__, err);
+        spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+        return -EINVAL;
+    }
+
+    spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+    err = lq_deu_des_core(ctx, des_con->dst_buf, des_con->src_buf, iv, nbytes, encdec, mode);
+    return err;
+}
+
+/* \fn static void process_queue(unsigned long data)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Process next packet in queue
+ * \param data not used
+ * \return 
+*/
+
+static void process_queue(unsigned long data)
+{
+      DEU_WAKEUP_EVENT(deu_dma_priv.deu_thread_wait, DES_ASYNC_EVENT,
+                deu_dma_priv.des_event_flags);
+
+}
+
+/* \fn static int des_crypto_thread (void *data)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief DES thread that handles crypto requests from upper layer & DMA
+ * \param *data Not used
+ * \return -EINVAL: DEU failure, -EBUSY: DEU HW busy, 0: exit thread
+*/
+
+static int des_crypto_thread(void *data)
+{
+    struct des_container *des_con = NULL;
+    struct ablkcipher_request *areq = NULL;
+    int err;
+    unsigned long queue_flag;
+
+    daemonize("lq_des_thread");
+   
+    while (1)
+    {  
+       DEU_WAIT_EVENT(deu_dma_priv.deu_thread_wait, DES_ASYNC_EVENT, 
+                       deu_dma_priv.des_event_flags);
+       spin_lock_irqsave(&des_queue->lock, queue_flag);
+
+       /* wait to prevent starting a crypto session before 
+        * exiting the dma interrupt thread.
+        */
+       
+       if (des_queue->hw_status == DES_STARTED) {
+            areq = ablkcipher_dequeue_request(&des_queue->list);
+            des_con = des_container_cast(areq);
+            des_queue->hw_status = DES_BUSY;
+       }
+       else if (des_queue->hw_status == DES_IDLE) {
+            areq = ablkcipher_dequeue_request(&des_queue->list);
+            des_con = des_container_cast(areq);
+            des_queue->hw_status = DES_STARTED;
+       }
+       else if (des_queue->hw_status == DES_BUSY) {
+            areq = ablkcipher_dequeue_request(&des_queue->list);
+            des_con = des_container_cast(areq);
+       }
+       else if (des_queue->hw_status == DES_COMPLETED) {
+            areq->base.complete(&areq->base, 0);
+            lq_sg_complete(des_con);
+            des_queue->hw_status = DES_IDLE;
+            spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+            return 0;
+       }
+       spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+            
+       if ((des_con->bytes_processed == 0)) {
+            goto des_done;
+       }
+
+       if (!des_con) {
+           goto des_done;
+       }
+
+       if (des_con->flag & PROCESS_NEW_PACKET) { 
+           des_con->flag = PROCESS_SCATTER;
+           err = process_next_packet(des_con, areq, PROCESS_NEW_PACKET);  
+       }
+       else
+           err = process_next_packet(des_con, areq, PROCESS_SCATTER);  
+       
+       if (err == -EINVAL) {
+           areq->base.complete(&areq->base, err);
+           lq_sg_complete(des_con);
+           printk("src/dst returned -EINVAL in func: %s\n", __func__);
+       }
+       else if (err > 0) { 
+           printk("src/dst returned zero in func: %s\n", __func__);
+           goto des_done;
+       }
+
+       continue;
+   
+des_done:
+       //printk("debug line - %d, func: %s, qlen: %d\n", __LINE__, __func__, des_queue->list.qlen);
+       areq->base.complete(&areq->base, 0);
+       lq_sg_complete(des_con);
+
+       spin_lock_irqsave(&des_queue->lock, queue_flag);
+       if (des_queue->list.qlen > 0) {
+           spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+           tasklet_schedule(&des_queue->des_task);
+       } 
+       else {
+           des_queue->hw_status = DES_IDLE;
+           spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+       }
+    } // while(1)
+    
+    return 0;
+
+}
+
+/* \fn static int lq_des_queue_mgr(struct des_ctx *ctx, struct ablkcipher_request *areq,
+                            u8 *iv, int encdec, int mode)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief starts the process of queuing DEU requests
+ * \param *ctx crypto algo contax
+ * \param *areq Pointer to the balkcipher requests
+ * \param *iv Pointer to intput vector location
+ * \param dir Encrypt/Decrypt
+ * \mode The mode DES algo is running
+ * \return 0 if success
+*/
+
+static int lq_queue_mgr(struct des_ctx *ctx, struct ablkcipher_request *areq, 
+                        u8 *iv, int encdec, int mode)
+{
+    int err = -EINVAL;
+    unsigned long queue_flag;
+    struct scatterlist *src = areq->src;
+    struct scatterlist *dst = areq->dst;
+    struct des_container *des_con = NULL;
+    u32 remain, inc, nbytes = areq->nbytes;
+    u32 chunk_bytes = src->length;
+   
+    des_con = (struct des_container *)kmalloc(sizeof(struct des_container), 
+                                       GFP_KERNEL);
+
+    if (!(des_con)) {
+        printk("Cannot allocate memory for AES container, fn %s, ln %d\n",
+                __func__, __LINE__);
+        return -ENOMEM;
+    }
+  
+    /* DES encrypt/decrypt mode  */
+    if (mode == 5) {
+        nbytes = DES_BLOCK_SIZE;
+        chunk_bytes = DES_BLOCK_SIZE;
+        mode = 0;
+    }
+
+    des_con->bytes_processed = nbytes;
+    des_con->arequest = (*areq);
+    remain = nbytes;
+
+    //printk("debug - Line: %d, func: %s, reqsize: %d, scattersize: %d\n", 
+       //      __LINE__, __func__, nbytes, chunk_bytes);
+
+    if (remain > DEU_MAX_PACKET_SIZE)  
+        inc = DEU_MAX_PACKET_SIZE;
+    else if(remain > chunk_bytes)
+        inc = chunk_bytes;
+    else 
+        inc = remain;
+    
+    remain -= inc;
+    lq_sg_init(des_con, src, dst);
+     
+    if (remain <= 0 ) { 
+        des_con->complete = 1;
+    }
+    else 
+        des_con->complete = 0;
+        
+    des_con->nbytes = inc; 
+    des_con->iv = iv;
+    des_con->mode = mode;
+    des_con->encdec = encdec;
+
+    spin_lock_irqsave(&des_queue->lock, queue_flag);
+
+    if (des_queue->hw_status == DES_STARTED || des_queue->hw_status == DES_BUSY ||
+        des_queue->list.qlen > 0) {
+
+        des_con->flag = PROCESS_NEW_PACKET;
+        err = ablkcipher_enqueue_request(&des_queue->list, &des_con->arequest);
+        if (err == -EBUSY) {
+            spin_unlock_irqrestore(&des_queue->lock, queue_flag); 
+            printk("Fail to enqueue ablkcipher request ln: %d, err: %d\n",
+                   __LINE__, err);
+            return err;
+        }
+
+        spin_unlock_irqrestore(&des_queue->lock, queue_flag); 
+        return -EINPROGRESS;
+              
+    }
+    else if (des_queue->hw_status == DES_IDLE) {
+        des_queue->hw_status = DES_STARTED;            
+    }
+   
+    des_con->flag = PROCESS_SCATTER;
+    des_con->bytes_processed -= des_con->nbytes;
+
+    err = ablkcipher_enqueue_request(&des_queue->list, &des_con->arequest);
+    if (err == -EBUSY) {
+        printk("Fail to enqueue ablkcipher request ln: %d, err: %d\n",
+              __LINE__, err);
+
+        spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+        return err;
+     }
+                  
+     spin_unlock_irqrestore(&des_queue->lock, queue_flag); 
+     return lq_deu_des_core(ctx, des_con->dst_buf, des_con->src_buf, iv, inc, encdec, mode);
+
+}
+
+/* \fn static int lq_des_encrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Decrypt function for DES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+       
+static int lq_des_encrypt(struct ablkcipher_request *areq)
+{
+    struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+    struct des_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+    return lq_queue_mgr(ctx, areq, NULL, CRYPTO_DIR_ENCRYPT, 5);
+
+}
+
+/* \fn static int lq_des_decrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Decrypt function for DES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int lq_des_decrypt(struct ablkcipher_request *areq)
+{
+    struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+    struct des_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+    return lq_queue_mgr(ctx, areq, NULL, CRYPTO_DIR_DECRYPT, 5);
+}
+
+/* \fn static int lq_ecb_des_encrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Decrypt function for DES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int lq_ecb_des_encrypt(struct ablkcipher_request *areq)
+{
+    struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+    struct des_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+    return lq_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_ENCRYPT, 0);
+}
+
+/* \fn static int lq_ecb_des_decrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Decrypt function for DES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+static int lq_ecb_des_decrypt(struct ablkcipher_request *areq)
+{
+    struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+    struct des_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+    return lq_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_DECRYPT, 0);
+
+}
+
+/* \fn static int lq_cbc_ecb_des_encrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Decrypt function for DES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int lq_cbc_des_encrypt(struct ablkcipher_request *areq)
+{
+    struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+    struct des_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+    return lq_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_ENCRYPT, 1);
+}
+/* \fn static int lq_cbc_des_decrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Decrypt function for DES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int lq_cbc_des_decrypt(struct ablkcipher_request *areq)
+{
+    struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+    struct des_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+    return lq_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_DECRYPT, 1);
+}
+
+struct lq_des_alg {
+    struct crypto_alg alg;
+};
+
+/* DES Supported algo array */
+static struct lq_des_alg des_drivers_alg [] = {
+    {
+        .alg = {
+            .cra_name        = "des",
+            .cra_driver_name = "lqdeu-des",
+            .cra_flags       = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 
+            .cra_blocksize   = DES_BLOCK_SIZE,
+            .cra_ctxsize     = sizeof(struct des_ctx),
+            .cra_type        = &crypto_ablkcipher_type,
+            .cra_priority    = 300,
+            .cra_module      = THIS_MODULE,
+            .cra_ablkcipher  = {
+                                .setkey = lq_des_setkey,
+                                .encrypt = lq_des_encrypt,
+                                .decrypt = lq_des_decrypt,
+                                .geniv = "eseqiv",
+                                .min_keysize = DES_KEY_SIZE,
+                                .max_keysize = DES_KEY_SIZE,
+                                .ivsize = DES_BLOCK_SIZE,
+            }
+        }
+
+    },{
+        .alg = {
+            .cra_name        = "ecb(des)",
+            .cra_driver_name = "lqdeu-ecb(des)",
+            .cra_flags       = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 
+            .cra_blocksize   = DES_BLOCK_SIZE,
+            .cra_ctxsize     = sizeof(struct des_ctx),
+            .cra_type        = &crypto_ablkcipher_type,
+            .cra_priority    = 300,
+            .cra_module      = THIS_MODULE,
+            .cra_ablkcipher  = {
+                                .setkey = lq_des_setkey,
+                                .encrypt = lq_ecb_des_encrypt,
+                                .decrypt = lq_ecb_des_decrypt,
+                                .geniv = "eseqiv",
+                                .min_keysize = DES_KEY_SIZE,
+                                .max_keysize = DES_KEY_SIZE,
+                                .ivsize = DES_BLOCK_SIZE,
+            }
+         }
+    },{
+        .alg = {
+            .cra_name        = "cbc(des)",
+            .cra_driver_name = "lqdeu-cbc(des)",
+            .cra_flags       = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 
+            .cra_blocksize   = DES_BLOCK_SIZE,
+            .cra_ctxsize     = sizeof(struct des_ctx),
+            .cra_type        = &crypto_ablkcipher_type,
+            .cra_priority    = 300,
+            .cra_module      = THIS_MODULE,
+            .cra_ablkcipher  = {
+                                .setkey = lq_des_setkey,
+                                .encrypt = lq_cbc_des_encrypt,
+                                .decrypt = lq_cbc_des_decrypt,
+                                .geniv = "eseqiv",
+                                .min_keysize = DES3_EDE_KEY_SIZE,
+                                .max_keysize = DES3_EDE_KEY_SIZE,
+                                .ivsize = DES3_EDE_BLOCK_SIZE,
+            }
+         }
+    },{
+        .alg = {
+            .cra_name        = "des3_ede",
+            .cra_driver_name = "lqdeu-des3_ede",
+            .cra_flags       = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 
+            .cra_blocksize   = DES_BLOCK_SIZE,
+            .cra_ctxsize     = sizeof(struct des_ctx),
+            .cra_type        = &crypto_ablkcipher_type,
+            .cra_priority    = 300,
+            .cra_module      = THIS_MODULE,
+            .cra_ablkcipher  = {
+                                .setkey = lq_des3_ede_setkey,
+                                .encrypt = lq_des_encrypt,
+                                .decrypt = lq_des_decrypt,
+                                .geniv = "eseqiv",
+                                .min_keysize = DES_KEY_SIZE,
+                                .max_keysize = DES_KEY_SIZE,
+                                .ivsize = DES_BLOCK_SIZE,
+            }
+         }
+    },{
+        .alg = {
+            .cra_name        = "ecb(des3_ede)",
+            .cra_driver_name = "lqdeu-ecb(des3_ede)",
+            .cra_flags       = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 
+            .cra_blocksize   = DES_BLOCK_SIZE,
+            .cra_ctxsize     = sizeof(struct des_ctx),
+            .cra_type        = &crypto_ablkcipher_type,
+            .cra_priority    = 300,
+            .cra_module      = THIS_MODULE,
+            .cra_ablkcipher  = {
+                                .setkey = lq_des3_ede_setkey,
+                                .encrypt = lq_ecb_des_encrypt,
+                                .decrypt = lq_ecb_des_decrypt,
+                                .geniv = "eseqiv",
+                                .min_keysize = DES3_EDE_KEY_SIZE,
+                                .max_keysize = DES3_EDE_KEY_SIZE,
+                                .ivsize = DES3_EDE_BLOCK_SIZE,
+            }
+         } 
+    },{
+        .alg = {
+            .cra_name        = "cbc(des3_ede)",
+            .cra_driver_name = "lqdeu-cbc(des3_ede)",
+            .cra_flags       = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 
+            .cra_blocksize   = DES_BLOCK_SIZE,
+            .cra_ctxsize     = sizeof(struct des_ctx),
+            .cra_type        = &crypto_ablkcipher_type,
+            .cra_priority    = 300,
+            .cra_module      = THIS_MODULE,
+            .cra_ablkcipher  = {
+                                .setkey = lq_des3_ede_setkey,
+                                .encrypt = lq_cbc_des_encrypt,
+                                .decrypt = lq_cbc_des_decrypt,
+                                .geniv = "eseqiv",
+                                .min_keysize = DES3_EDE_KEY_SIZE,
+                                .max_keysize = DES3_EDE_KEY_SIZE,
+                                .ivsize = DES3_EDE_BLOCK_SIZE,
+            }
+         }
+    } 
+};
+
+/*! \fn int __init lqdeu_async_des_init (void)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief initialize des driver
+*/
+int __init lqdeu_async_des_init (void)
+{
+    int i, j, ret = -EINVAL;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+     if (!disable_multiblock) {
+                ifxdeu_des_alg.cra_u.cipher.cia_max_nbytes = DES_BLOCK_SIZE;    //(size_t)-1;
+                ifxdeu_des_alg.cra_u.cipher.cia_req_align = 16;
+                ifxdeu_des_alg.cra_u.cipher.cia_ecb = ifx_deu_des_ecb;
+                ifxdeu_des_alg.cra_u.cipher.cia_cbc = ifx_deu_des_cbc;
+                ifxdeu_des_alg.cra_u.cipher.cia_cfb = ifx_deu_des_cfb;
+                ifxdeu_des_alg.cra_u.cipher.cia_ofb = ifx_deu_des_ofb;
+        }
+#endif
+     for (i = 0; i < ARRAY_SIZE(des_drivers_alg); i++) {
+         ret = crypto_register_alg(&des_drivers_alg[i].alg);
+        //printk("driver: %s\n", des_drivers_alg[i].alg.cra_name);
+         if (ret)
+             goto des_err;
+     }
+            
+     des_chip_init();
+     CRTCL_SECT_INIT;
+
+
+    printk (KERN_NOTICE "IFX DEU DES initialized%s%s.\n", disable_multiblock ? "" : " (multiblock)", disable_deudma ? "" : " (DMA)");
+    return ret;
+
+des_err:
+     for (j = 0; j < i; j++) 
+        crypto_unregister_alg(&des_drivers_alg[i].alg);
+
+     printk(KERN_ERR "Lantiq %s driver initialization failed!\n", (char *)&des_drivers_alg[i].alg.cra_driver_name);
+     return ret;
+
+cbc_des3_ede_err:
+     for (i = 0; i < ARRAY_SIZE(des_drivers_alg); i++) {
+         if (!strcmp((char *)&des_drivers_alg[i].alg.cra_name, "cbc(des3_ede)"))
+             crypto_unregister_alg(&des_drivers_alg[i].alg);
+     }     
+
+     printk(KERN_ERR "Lantiq %s driver initialization failed!\n", (char *)&des_drivers_alg[i].alg.cra_driver_name);
+     return ret;
+}
+
+/*! \fn void __exit lqdeu_fini_async_des (void)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief unregister des driver
+*/
+void __exit lqdeu_fini_async_des (void)
+{
+    int i;
+    
+    for (i = 0; i < ARRAY_SIZE(des_drivers_alg); i++)
+        crypto_unregister_alg(&des_drivers_alg[i].alg);
+
+    des_queue->hw_status = DES_COMPLETED;
+    DEU_WAKEUP_EVENT(deu_dma_priv.deu_thread_wait, DES_ASYNC_EVENT,
+                                 deu_dma_priv.des_event_flags); 
+   
+    kfree(des_queue);
+}
+
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_des.c b/package/platform/lantiq/ltq-deu/src/ifxmips_des.c
new file mode 100644 (file)
index 0000000..dcf6c18
--- /dev/null
@@ -0,0 +1,768 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_des.c
+** PROJECT      : IFX UEIP
+** MODULES      : DEU Module
+**
+** DATE         : September 8, 2009
+** AUTHOR       : Mohammad Firdaus
+** DESCRIPTION  : Data Encryption Unit Driver for DES Algorithm
+** COPYRIGHT    :       Copyright (c) 2009
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author             $Comment
+** 08 Sept 2009 Mohammad Firdaus    Initial UEIP release
+*******************************************************************************/
+
+/*!
+  \defgroup IFX_DEU IFX_DEU_DRIVERS
+  \ingroup API
+  \brief ifx deu driver
+*/
+
+/*!
+  \file                ifxmips_des.c
+  \ingroup     IFX_DEU
+  \brief       DES encryption DEU driver file
+*/
+
+/*!
+  \defgroup IFX_DES_FUNCTIONS IFX_DES_FUNCTIONS
+  \ingroup IFX_DEU
+  \brief IFX DES Encryption functions
+*/
+
+/* Project Header Files */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/crypto.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+#include <crypto/algapi.h>
+#include "ifxmips_deu.h"
+
+#if defined(CONFIG_DANUBE) 
+#include "ifxmips_deu_danube.h"
+extern int ifx_danube_pre_1_4;
+#elif defined(CONFIG_AR9)
+#include "ifxmips_deu_ar9.h"
+#elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
+#include "ifxmips_deu_vr9.h"
+#else
+#error "Unkown platform"
+#endif
+
+/* DMA specific header and variables */
+
+#if 0
+     #define CRTCL_SECT_INIT        
+     #define CRTCL_SECT_START        
+     #define CRTCL_SECT_END         
+#else
+spinlock_t des_lock;
+#define CRTCL_SECT_INIT        spin_lock_init(&des_lock)
+#define CRTCL_SECT_START       spin_lock_irqsave(&des_lock, flag)
+#define CRTCL_SECT_END         spin_unlock_irqrestore(&des_lock, flag)
+#endif
+
+/* Preprocessor declerations */
+#ifdef CRYPTO_DEBUG
+extern char debug_level;
+#define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
+#else
+#define DPRINTF(level, format, args...)
+#endif
+#define DES_3DES_START  IFX_DES_CON
+#define DES_KEY_SIZE            8
+#define DES_EXPKEY_WORDS        32
+#define DES_BLOCK_SIZE          8
+#define DES3_EDE_KEY_SIZE       (3 * DES_KEY_SIZE)
+#define DES3_EDE_EXPKEY_WORDS   (3 * DES_EXPKEY_WORDS)
+#define DES3_EDE_BLOCK_SIZE     DES_BLOCK_SIZE
+
+/* Function Declaration to prevent warning messages */
+void des_chip_init (void);
+u32 endian_swap(u32 input);
+u32 input_swap(u32 input);
+int aes_memory_allocate(int value);
+int des_memory_allocate(int value);
+void memory_release(u32 *buffer);
+u32* memory_alignment(const u8 *arg, u32 *buff_alloc, int in_out, int nbytes);
+void aes_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+void des_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+
+void ifx_deu_des (void *ctx_arg, u8 *out_arg, const u8 *in_arg,
+             u8 *iv_arg, u32 nbytes, int encdec, int mode);
+
+struct des_ctx {
+        int controlr_M;
+        int key_length;
+        u8 iv[DES_BLOCK_SIZE];
+        u32 expkey[DES3_EDE_EXPKEY_WORDS];
+};
+
+extern int disable_multiblock;
+extern int disable_deudma;
+
+
+/*! \fn        int des_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief sets DES key   
+ *  \param tfm linux crypto algo transform  
+ *  \param key input key  
+ *  \param keylen key length  
+*/                                 
+int des_setkey(struct crypto_tfm *tfm, const u8 *key,
+                      unsigned int keylen)
+{
+        struct des_ctx *dctx = crypto_tfm_ctx(tfm);
+
+        //printk("setkey in %s\n", __FILE__);
+
+        dctx->controlr_M = 0;   // des
+        dctx->key_length = keylen;
+
+        memcpy ((u8 *) (dctx->expkey), key, keylen);
+
+        return 0;
+}
+
+
+/*! \fn void ifx_deu_des(void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief main interface to DES hardware   
+ *  \param ctx_arg crypto algo context  
+ *  \param out_arg output bytestream  
+ *  \param in_arg input bytestream   
+ *  \param iv_arg initialization vector  
+ *  \param nbytes length of bytestream  
+ *  \param encdec 1 for encrypt; 0 for decrypt  
+ *  \param mode operation mode such as ebc, cbc 
+*/                                 
+
+void ifx_deu_des (void *ctx_arg, u8 *out_arg, const u8 *in_arg,
+             u8 *iv_arg, u32 nbytes, int encdec, int mode)
+{
+        volatile struct des_t *des = (struct des_t *) DES_3DES_START;
+        struct des_ctx *dctx = ctx_arg;
+        u32 *key = dctx->expkey;
+        unsigned long flag;
+
+        int i = 0;
+        int nblocks = 0;
+        
+        CRTCL_SECT_START;
+
+        des->controlr.M = dctx->controlr_M;
+        if (dctx->controlr_M == 0)      // des
+        {
+                des->K1HR = DEU_ENDIAN_SWAP(*((u32 *) key + 0));
+                des->K1LR = DEU_ENDIAN_SWAP(*((u32 *) key + 1));
+
+        }
+        else {
+                /* Hardware Section */
+                switch (dctx->key_length) {
+                case 24:
+                        des->K3HR = DEU_ENDIAN_SWAP(*((u32 *) key + 4));
+                        des->K3LR = DEU_ENDIAN_SWAP(*((u32 *) key + 5));
+                        /* no break; */
+
+                case 16:
+                        des->K2HR = DEU_ENDIAN_SWAP(*((u32 *) key + 2));
+                        des->K2LR = DEU_ENDIAN_SWAP(*((u32 *) key + 3));
+
+                        /* no break; */
+                case 8:
+                        des->K1HR = DEU_ENDIAN_SWAP(*((u32 *) key + 0));
+                        des->K1LR = DEU_ENDIAN_SWAP(*((u32 *) key + 1));
+                        break;
+
+                default:
+                        CRTCL_SECT_END;
+                        return;
+                }
+        }
+
+        des->controlr.E_D = !encdec;    //encryption
+        des->controlr.O = mode; //0 ECB 1 CBC 2 OFB 3 CFB 4 CTR hexdump(prin,sizeof(*des));
+
+        if (mode > 0) {
+                des->IVHR = DEU_ENDIAN_SWAP(*(u32 *) iv_arg);
+                des->IVLR = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1));
+        };
+
+        nblocks = nbytes / 4;
+
+        for (i = 0; i < nblocks; i += 2) {
+                /* wait for busy bit to clear */
+
+                /*--- Workaround ----------------------------------------------------
+                do a dummy read to the busy flag because it is not raised early
+                enough in CFB/OFB 3DES modes */
+#ifdef CRYPTO_DEBUG
+                printk ("ihr: %x\n", (*((u32 *) in_arg + i)));
+                printk ("ilr: %x\n", (*((u32 *) in_arg + 1 + i)));
+#endif           
+                des->IHR = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + i));
+                des->ILR = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + 1 + i)); /* start crypto */
+                
+                while (des->controlr.BUS) {
+                        // this will not take long
+                }
+
+                *((u32 *) out_arg + 0 + i) = des->OHR;
+                *((u32 *) out_arg + 1 + i) = des->OLR;
+
+        }
+
+
+    
+    if (mode > 0) {
+        *(u32 *) iv_arg = DEU_ENDIAN_SWAP(des->IVHR);
+        *((u32 *) iv_arg + 1) = DEU_ENDIAN_SWAP(des->IVLR);
+    };
+
+    CRTCL_SECT_END;
+}
+
+//definitions from linux/include/crypto.h:
+//#define CRYPTO_TFM_MODE_ECB           0x00000001
+//#define CRYPTO_TFM_MODE_CBC           0x00000002
+//#define CRYPTO_TFM_MODE_CFB           0x00000004
+//#define CRYPTO_TFM_MODE_CTR           0x00000008
+//#define CRYPTO_TFM_MODE_OFB           0x00000010 // not even defined
+//but hardware definition: 0 ECB 1 CBC 2 OFB 3 CFB 4 CTR
+
+/*! \fn void ifx_deu_des(void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief main interface to DES hardware   
+ *  \param ctx_arg crypto algo context  
+ *  \param out_arg output bytestream  
+ *  \param in_arg input bytestream   
+ *  \param iv_arg initialization vector  
+ *  \param nbytes length of bytestream  
+ *  \param encdec 1 for encrypt; 0 for decrypt  
+ *  \param mode operation mode such as ebc, cbc 
+*/   
+
+
+
+/*! \fn  void ifx_deu_des_ecb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief sets DES hardware to ECB mode   
+ *  \param ctx crypto algo context  
+ *  \param dst output bytestream  
+ *  \param src input bytestream  
+ *  \param iv initialization vector   
+ *  \param nbytes length of bytestream  
+ *  \param encdec 1 for encrypt; 0 for decrypt  
+ *  \param inplace not used  
+*/
+    
+void ifx_deu_des_ecb (void *ctx, uint8_t *dst, const uint8_t *src,
+                uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+     ifx_deu_des (ctx, dst, src, NULL, nbytes, encdec, 0);
+}
+
+/*! \fn  void ifx_deu_des_cbc (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief sets DES hardware to CBC mode   
+ *  \param ctx crypto algo context  
+ *  \param dst output bytestream  
+ *  \param src input bytestream  
+ *  \param iv initialization vector   
+ *  \param nbytes length of bytestream  
+ *  \param encdec 1 for encrypt; 0 for decrypt  
+ *  \param inplace not used  
+*/                                 
+void ifx_deu_des_cbc (void *ctx, uint8_t *dst, const uint8_t *src,
+                uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+     ifx_deu_des (ctx, dst, src, iv, nbytes, encdec, 1);
+}
+
+/*! \fn  void ifx_deu_des_ofb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief sets DES hardware to OFB mode   
+ *  \param ctx crypto algo context  
+ *  \param dst output bytestream  
+ *  \param src input bytestream  
+ *  \param iv initialization vector   
+ *  \param nbytes length of bytestream  
+ *  \param encdec 1 for encrypt; 0 for decrypt  
+ *  \param inplace not used  
+*/                                 
+void ifx_deu_des_ofb (void *ctx, uint8_t *dst, const uint8_t *src,
+                uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+     ifx_deu_des (ctx, dst, src, iv, nbytes, encdec, 2);
+}
+
+/*! \fn void ifx_deu_des_cfb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+    \ingroup IFX_DES_FUNCTIONS
+    \brief sets DES hardware to CFB mode   
+    \param ctx crypto algo context  
+    \param dst output bytestream  
+    \param src input bytestream  
+    \param iv initialization vector   
+    \param nbytes length of bytestream  
+    \param encdec 1 for encrypt; 0 for decrypt  
+    \param inplace not used  
+*/                                 
+void ifx_deu_des_cfb (void *ctx, uint8_t *dst, const uint8_t *src,
+                uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+     ifx_deu_des (ctx, dst, src, iv, nbytes, encdec, 3);
+}
+
+/*! \fn void ifx_deu_des_ctr (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief sets DES hardware to CTR mode   
+ *  \param ctx crypto algo context  
+ *  \param dst output bytestream  
+ *  \param src input bytestream  
+ *  \param iv initialization vector   
+ *  \param nbytes length of bytestream  
+ *  \param encdec 1 for encrypt; 0 for decrypt  
+ *  \param inplace not used  
+*/                                 
+void ifx_deu_des_ctr (void *ctx, uint8_t *dst, const uint8_t *src,
+                uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+     ifx_deu_des (ctx, dst, src, iv, nbytes, encdec, 4);
+}
+
+/*! \fn void des_encrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief encrypt DES_BLOCK_SIZE of data   
+ *  \param tfm linux crypto algo transform  
+ *  \param out output bytestream  
+ *  \param in input bytestream  
+*/                                               
+void des_encrypt (struct crypto_tfm *tfm, uint8_t * out, const uint8_t * in)
+{
+     struct des_ctx *ctx = crypto_tfm_ctx(tfm);
+     ifx_deu_des (ctx, out, in, NULL, DES_BLOCK_SIZE,
+                    CRYPTO_DIR_ENCRYPT, 0);
+
+}
+
+/*! \fn void des_decrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief encrypt DES_BLOCK_SIZE of data   
+ *  \param tfm linux crypto algo transform  
+ *  \param out output bytestream  
+ *  \param in input bytestream  
+*/                                               
+void des_decrypt (struct crypto_tfm *tfm, uint8_t * out, const uint8_t * in)
+{
+     struct des_ctx *ctx = crypto_tfm_ctx(tfm);
+     ifx_deu_des (ctx, out, in, NULL, DES_BLOCK_SIZE,
+                    CRYPTO_DIR_DECRYPT, 0);
+}
+
+/*
+ *   \brief RFC2451:
+ *
+ *   For DES-EDE3, there is no known need to reject weak or
+ *   complementation keys.  Any weakness is obviated by the use of
+ *   multiple keys.
+ *
+ *   However, if the first two or last two independent 64-bit keys are
+ *   equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
+ *   same as DES.  Implementers MUST reject keys that exhibit this
+ *   property.
+ *
+ */
+
+/*! \fn int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief sets 3DES key   
+ *  \param tfm linux crypto algo transform  
+ *  \param key input key  
+ *  \param keylen key length  
+*/                                 
+int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key,
+                    unsigned int keylen)
+{
+        struct des_ctx *dctx = crypto_tfm_ctx(tfm);
+
+        //printk("setkey in %s\n", __FILE__);
+
+        dctx->controlr_M = keylen / 8 + 1;      // 3DES EDE1 / EDE2 / EDE3 Mode
+        dctx->key_length = keylen;
+
+        memcpy ((u8 *) (dctx->expkey), key, keylen);
+
+        return 0;
+}
+
+/*
+ * \brief DES function mappings
+*/ 
+struct crypto_alg ifxdeu_des_alg = {
+        .cra_name               =       "des",
+        .cra_driver_name        =       "ifxdeu-des",
+        .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
+        .cra_blocksize          =       DES_BLOCK_SIZE,
+        .cra_ctxsize            =       sizeof(struct des_ctx),
+        .cra_module             =       THIS_MODULE,
+        .cra_alignmask          =       3,
+        .cra_list               =       LIST_HEAD_INIT(ifxdeu_des_alg.cra_list),
+        .cra_u                  =       { .cipher = {
+        .cia_min_keysize        =       DES_KEY_SIZE,
+        .cia_max_keysize        =       DES_KEY_SIZE,
+        .cia_setkey             =       des_setkey,
+        .cia_encrypt            =       des_encrypt,
+        .cia_decrypt            =       des_decrypt } }
+};
+
+/*
+ * \brief DES function mappings
+*/ 
+struct crypto_alg ifxdeu_des3_ede_alg = {
+        .cra_name               =       "des3_ede",
+        .cra_driver_name        =       "ifxdeu-des3_ede",
+        .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
+        .cra_blocksize          =       DES_BLOCK_SIZE,
+        .cra_ctxsize            =       sizeof(struct des_ctx),
+        .cra_module             =       THIS_MODULE,
+        .cra_alignmask          =       3,
+        .cra_list               =       LIST_HEAD_INIT(ifxdeu_des3_ede_alg.cra_list),
+        .cra_u                  =       { .cipher = {
+        .cia_min_keysize        =       DES_KEY_SIZE,
+        .cia_max_keysize        =       DES_KEY_SIZE,
+        .cia_setkey             =       des3_ede_setkey,
+        .cia_encrypt            =       des_encrypt,
+        .cia_decrypt            =       des_decrypt } }
+};
+
+/*! \fn int ecb_des_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief ECB DES encrypt using linux crypto blkcipher    
+ *  \param desc blkcipher descriptor  
+ *  \param dst output scatterlist  
+ *  \param src input scatterlist  
+ *  \param nbytes data size in bytes  
+*/                                 
+int ecb_des_encrypt(struct blkcipher_desc *desc,
+                    struct scatterlist *dst, struct scatterlist *src,
+                    unsigned int nbytes)
+{
+        struct des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+        struct blkcipher_walk walk;
+        int err;
+
+        blkcipher_walk_init(&walk, dst, src, nbytes);
+        err = blkcipher_walk_virt(desc, &walk);
+
+        while ((nbytes = walk.nbytes)) {
+                nbytes -= (nbytes % DES_BLOCK_SIZE); 
+                ifx_deu_des_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
+                               NULL, nbytes, CRYPTO_DIR_ENCRYPT, 0);
+                nbytes &= DES_BLOCK_SIZE - 1;
+                err = blkcipher_walk_done(desc, &walk, nbytes);
+        }
+
+        return err;
+}
+
+/*! \fn int ecb_des_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief ECB DES decrypt using linux crypto blkcipher    
+ *  \param desc blkcipher descriptor  
+ *  \param dst output scatterlist  
+ *  \param src input scatterlist  
+ *  \param nbytes data size in bytes  
+ *  \return err
+*/                                 
+int ecb_des_decrypt(struct blkcipher_desc *desc,
+                    struct scatterlist *dst, struct scatterlist *src,
+                    unsigned int nbytes)
+{
+        struct des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+        struct blkcipher_walk walk;
+        int err;
+
+        DPRINTF(1, "\n");
+        blkcipher_walk_init(&walk, dst, src, nbytes);
+        err = blkcipher_walk_virt(desc, &walk);
+
+        while ((nbytes = walk.nbytes)) {
+                nbytes -= (nbytes % DES_BLOCK_SIZE); 
+                ifx_deu_des_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
+                               NULL, nbytes, CRYPTO_DIR_DECRYPT, 0);
+                nbytes &= DES_BLOCK_SIZE - 1;
+                err = blkcipher_walk_done(desc, &walk, nbytes);
+        }
+
+        return err;
+}
+
+/*
+ * \brief DES function mappings
+*/ 
+struct crypto_alg ifxdeu_ecb_des_alg = {
+        .cra_name               =       "ecb(des)",
+        .cra_driver_name        =       "ifxdeu-ecb(des)",
+        .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
+        .cra_blocksize          =       DES_BLOCK_SIZE,
+        .cra_ctxsize            =       sizeof(struct des_ctx),
+        .cra_type               =       &crypto_blkcipher_type,
+        .cra_module             =       THIS_MODULE,
+        .cra_list               =       LIST_HEAD_INIT(ifxdeu_ecb_des_alg.cra_list),
+        .cra_u                  =       {
+                .blkcipher = {
+                        .min_keysize            =       DES_KEY_SIZE,
+                        .max_keysize            =       DES_KEY_SIZE,
+                        .setkey                 =       des_setkey,
+                        .encrypt                =       ecb_des_encrypt,
+                        .decrypt                =       ecb_des_decrypt,
+                }
+        }
+};
+
+/*
+ * \brief DES function mappings
+*/ 
+struct crypto_alg ifxdeu_ecb_des3_ede_alg = {
+        .cra_name               =       "ecb(des3_ede)",
+        .cra_driver_name        =       "ifxdeu-ecb(des3_ede)",
+        .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
+        .cra_blocksize          =       DES3_EDE_BLOCK_SIZE,
+        .cra_ctxsize            =       sizeof(struct des_ctx),
+        .cra_type               =       &crypto_blkcipher_type,
+        .cra_module             =       THIS_MODULE,
+        .cra_list               =       LIST_HEAD_INIT(ifxdeu_ecb_des3_ede_alg.cra_list),
+        .cra_u                  =       {
+                .blkcipher = {
+                        .min_keysize            =       DES3_EDE_KEY_SIZE,
+                        .max_keysize            =       DES3_EDE_KEY_SIZE,
+                        .setkey                 =       des3_ede_setkey,
+                        .encrypt                =       ecb_des_encrypt,
+                        .decrypt                =       ecb_des_decrypt,
+                }
+        }
+};
+
+/*! \fn int cbc_des_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief CBC DES encrypt using linux crypto blkcipher    
+ *  \param desc blkcipher descriptor  
+ *  \param dst output scatterlist  
+ *  \param src input scatterlist  
+ *  \param nbytes data size in bytes  
+ *  \return err
+*/                                 
+int cbc_des_encrypt(struct blkcipher_desc *desc,
+                    struct scatterlist *dst, struct scatterlist *src,
+                    unsigned int nbytes)
+{
+        struct des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+        struct blkcipher_walk walk;
+        int err;
+
+        DPRINTF(1, "\n");
+        blkcipher_walk_init(&walk, dst, src, nbytes);
+        err = blkcipher_walk_virt(desc, &walk);
+
+        while ((nbytes = walk.nbytes)) {
+                u8 *iv = walk.iv;
+                nbytes -= (nbytes % DES_BLOCK_SIZE); 
+                ifx_deu_des_cbc(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
+                               iv, nbytes, CRYPTO_DIR_ENCRYPT, 0);      
+                nbytes &= DES_BLOCK_SIZE - 1;
+                err = blkcipher_walk_done(desc, &walk, nbytes);
+        }
+
+        return err;
+}
+
+/*! \fn int cbc_des_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief CBC DES decrypt using linux crypto blkcipher    
+ *  \param desc blkcipher descriptor  
+ *  \param dst output scatterlist  
+ *  \param src input scatterlist  
+ *  \param nbytes data size in bytes  
+ *  \return err
+*/                                 
+int cbc_des_decrypt(struct blkcipher_desc *desc,
+                    struct scatterlist *dst, struct scatterlist *src,
+                    unsigned int nbytes)
+{
+        struct des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+        struct blkcipher_walk walk;
+        int err;
+
+        DPRINTF(1, "\n");
+        blkcipher_walk_init(&walk, dst, src, nbytes);
+        err = blkcipher_walk_virt(desc, &walk);
+
+        while ((nbytes = walk.nbytes)) {
+                u8 *iv = walk.iv;
+                nbytes -= (nbytes % DES_BLOCK_SIZE); 
+                ifx_deu_des_cbc(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
+                               iv, nbytes, CRYPTO_DIR_DECRYPT, 0);
+                nbytes &= DES_BLOCK_SIZE - 1;
+                err = blkcipher_walk_done(desc, &walk, nbytes);
+        }
+
+        return err;
+}
+
+/*
+ * \brief DES function mappings
+*/ 
+struct crypto_alg ifxdeu_cbc_des_alg = {
+        .cra_name               =       "cbc(des)",
+        .cra_driver_name        =       "ifxdeu-cbc(des)",
+        .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
+        .cra_blocksize          =       DES_BLOCK_SIZE,
+        .cra_ctxsize            =       sizeof(struct des_ctx),
+        .cra_type               =       &crypto_blkcipher_type,
+        .cra_module             =       THIS_MODULE,
+        .cra_list               =       LIST_HEAD_INIT(ifxdeu_cbc_des_alg.cra_list),
+        .cra_u                  =       {
+                .blkcipher = {
+                        .min_keysize            =       DES_KEY_SIZE,
+                        .max_keysize            =       DES_KEY_SIZE,
+                        .ivsize                 =       DES_BLOCK_SIZE,
+                        .setkey                 =       des_setkey,
+                        .encrypt                =       cbc_des_encrypt,
+                        .decrypt                =       cbc_des_decrypt,
+                }
+        }
+};
+
+/*
+ * \brief DES function mappings
+*/ 
+struct crypto_alg ifxdeu_cbc_des3_ede_alg = {
+        .cra_name               =       "cbc(des3_ede)",
+        .cra_driver_name        =       "ifxdeu-cbc(des3_ede)",
+        .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
+        .cra_blocksize          =       DES3_EDE_BLOCK_SIZE,
+        .cra_ctxsize            =       sizeof(struct des_ctx),
+        .cra_type               =       &crypto_blkcipher_type,
+        .cra_module             =       THIS_MODULE,
+        .cra_list               =       LIST_HEAD_INIT(ifxdeu_cbc_des3_ede_alg.cra_list),
+        .cra_u                  =       {
+                .blkcipher = {
+                        .min_keysize            =       DES3_EDE_KEY_SIZE,
+                        .max_keysize            =       DES3_EDE_KEY_SIZE,
+                        .ivsize                 =       DES_BLOCK_SIZE,
+                        .setkey                 =       des3_ede_setkey,
+                        .encrypt                =       cbc_des_encrypt,
+                        .decrypt                =       cbc_des_decrypt,
+                }
+        }
+};
+
+/*! \fn int __init ifxdeu_init_des (void)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief initialize des driver      
+*/                                 
+int __init ifxdeu_init_des (void)
+{
+    int ret = -ENOSYS;
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+     if (!disable_multiblock) {
+                ifxdeu_des_alg.cra_u.cipher.cia_max_nbytes = DES_BLOCK_SIZE;    //(size_t)-1;
+                ifxdeu_des_alg.cra_u.cipher.cia_req_align = 16;
+                ifxdeu_des_alg.cra_u.cipher.cia_ecb = ifx_deu_des_ecb;
+                ifxdeu_des_alg.cra_u.cipher.cia_cbc = ifx_deu_des_cbc;
+                ifxdeu_des_alg.cra_u.cipher.cia_cfb = ifx_deu_des_cfb;
+                ifxdeu_des_alg.cra_u.cipher.cia_ofb = ifx_deu_des_ofb;
+        }
+#endif
+
+        ret = crypto_register_alg(&ifxdeu_des_alg);
+        if (ret < 0)
+                goto des_err;
+
+        ret = crypto_register_alg(&ifxdeu_ecb_des_alg);
+        if (ret < 0)
+                goto ecb_des_err;
+
+        ret = crypto_register_alg(&ifxdeu_cbc_des_alg);
+        if (ret < 0)
+                goto cbc_des_err;
+
+        ret = crypto_register_alg(&ifxdeu_des3_ede_alg);
+        if (ret < 0)
+                goto des3_ede_err;
+
+        ret = crypto_register_alg(&ifxdeu_ecb_des3_ede_alg);
+        if (ret < 0)
+                goto ecb_des3_ede_err;
+
+        ret = crypto_register_alg(&ifxdeu_cbc_des3_ede_alg);
+        if (ret < 0)
+                goto cbc_des3_ede_err;
+
+        des_chip_init();
+        CRTCL_SECT_INIT;
+
+
+
+         printk (KERN_NOTICE "IFX DEU DES initialized%s%s.\n", disable_multiblock ? "" : " (multiblock)", disable_deudma ? "" : " (DMA)");
+        return ret;
+
+des_err:
+        crypto_unregister_alg(&ifxdeu_des_alg);
+        printk(KERN_ERR "IFX des initialization failed!\n");
+        return ret;
+ecb_des_err:
+        crypto_unregister_alg(&ifxdeu_ecb_des_alg);
+        printk (KERN_ERR "IFX ecb_des initialization failed!\n");
+        return ret;
+cbc_des_err:
+        crypto_unregister_alg(&ifxdeu_cbc_des_alg);
+        printk (KERN_ERR "IFX cbc_des initialization failed!\n");
+        return ret;
+des3_ede_err:
+        crypto_unregister_alg(&ifxdeu_des3_ede_alg);
+        printk(KERN_ERR "IFX des3_ede initialization failed!\n");
+        return ret;
+ecb_des3_ede_err:
+        crypto_unregister_alg(&ifxdeu_ecb_des3_ede_alg);
+        printk (KERN_ERR "IFX ecb_des3_ede initialization failed!\n");
+        return ret;
+cbc_des3_ede_err:
+        crypto_unregister_alg(&ifxdeu_cbc_des3_ede_alg);
+        printk (KERN_ERR "IFX cbc_des3_ede initialization failed!\n");
+        return ret;
+
+}
+
+/*! \fn void __exit ifxdeu_fini_des (void)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief unregister des driver    
+*/                                 
+void __exit ifxdeu_fini_des (void)
+{
+        crypto_unregister_alg (&ifxdeu_des_alg);
+        crypto_unregister_alg (&ifxdeu_ecb_des_alg);
+        crypto_unregister_alg (&ifxdeu_cbc_des_alg);
+        crypto_unregister_alg (&ifxdeu_des3_ede_alg);
+        crypto_unregister_alg (&ifxdeu_ecb_des3_ede_alg);
+        crypto_unregister_alg (&ifxdeu_cbc_des3_ede_alg);
+
+}
+
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_deu.c b/package/platform/lantiq/ltq-deu/src/ifxmips_deu.c
new file mode 100644 (file)
index 0000000..cec7000
--- /dev/null
@@ -0,0 +1,210 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_deu.c
+** PROJECT      : IFX UEIP
+** MODULES      : DEU Module for Danube
+**
+** DATE         : September 8, 2009
+** AUTHOR       : Mohammad Firdaus
+** DESCRIPTION  : Data Encryption Unit Driver
+** COPYRIGHT    :       Copyright (c) 2009
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author             $Comment
+** 08,Sept 2009 Mohammad Firdaus    Initial UEIP release
+*******************************************************************************/
+
+/*!
+  \defgroup IFX_DEU IFX_DEU_DRIVERS
+  \ingroup API
+  \brief ifx deu driver module
+*/
+
+/*!
+  \file        ifxmips_deu.c
+  \ingroup IFX_DEU
+  \brief main deu driver file
+*/
+
+/*!
+ \defgroup IFX_DEU_FUNCTIONS IFX_DEU_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief IFX DEU functions
+*/
+
+/* Project header */
+#include <linux/version.h>
+#if defined(CONFIG_MODVERSIONS)
+#define MODVERSIONS
+#include <linux/modversions.h>
+#endif
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/crypto.h>
+#include <linux/proc_fs.h>
+#include <linux/platform_device.h>
+#include <linux/fs.h>       /* Stuff about file systems that we need */
+#include <asm/byteorder.h>
+#include "ifxmips_deu.h"
+
+#include <lantiq_soc.h>
+
+#if defined(CONFIG_DANUBE)
+#include "ifxmips_deu_danube.h"
+#elif defined(CONFIG_AR9)
+#include "ifxmips_deu_ar9.h"
+#elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
+#include "ifxmips_deu_vr9.h"
+#else 
+#error "Platform unknown!"
+#endif /* CONFIG_xxxx */
+
+int disable_deudma = 1;
+
+void chip_version(void);
+
+/*! \fn static int __init deu_init (void)
+ *  \ingroup IFX_DEU_FUNCTIONS
+ *  \brief link all modules that have been selected in kernel config for ifx hw crypto support   
+ *  \return ret 
+*/  
+                               
+static int __devinit ltq_deu_probe(struct platform_device *pdev)
+{
+    int ret = -ENOSYS;
+
+
+    START_DEU_POWER;
+    
+#define IFX_DEU_DRV_VERSION         "2.0.0"
+         printk(KERN_INFO "Infineon Technologies DEU driver version %s \n", IFX_DEU_DRV_VERSION);
+
+    FIND_DEU_CHIP_VERSION;
+
+#if defined(CONFIG_CRYPTO_DEV_DES)
+    if ((ret = ifxdeu_init_des ())) {
+        printk (KERN_ERR "IFX DES initialization failed!\n");
+    }
+#endif
+#if defined(CONFIG_CRYPTO_DEV_AES)
+    if ((ret = ifxdeu_init_aes ())) {
+        printk (KERN_ERR "IFX AES initialization failed!\n");
+    }
+
+#endif
+#if defined(CONFIG_CRYPTO_DEV_ARC4)
+    if ((ret = ifxdeu_init_arc4 ())) {
+        printk (KERN_ERR "IFX ARC4 initialization failed!\n");
+    }
+
+#endif
+#if defined(CONFIG_CRYPTO_DEV_SHA1)
+    if ((ret = ifxdeu_init_sha1 ())) {
+        printk (KERN_ERR "IFX SHA1 initialization failed!\n");
+    }
+#endif
+#if defined(CONFIG_CRYPTO_DEV_MD5)
+    if ((ret = ifxdeu_init_md5 ())) {
+        printk (KERN_ERR "IFX MD5 initialization failed!\n");
+    }
+
+#endif
+#if defined(CONFIG_CRYPTO_DEV_SHA1_HMAC)
+    if ((ret = ifxdeu_init_sha1_hmac ())) {
+        printk (KERN_ERR "IFX SHA1_HMAC initialization failed!\n");
+    }
+#endif
+#if defined(CONFIG_CRYPTO_DEV_MD5_HMAC)
+    if ((ret = ifxdeu_init_md5_hmac ())) {
+        printk (KERN_ERR "IFX MD5_HMAC initialization failed!\n");
+    }
+#endif
+
+
+
+    return ret;
+
+}
+
+/*! \fn static void __exit deu_fini (void)
+ *  \ingroup IFX_DEU_FUNCTIONS
+ *  \brief remove the loaded crypto algorithms   
+*/                                 
+static int __devexit ltq_deu_remove(struct platform_device *pdev)
+{
+//#ifdef CONFIG_CRYPTO_DEV_PWR_SAVE_MODE
+    #if defined(CONFIG_CRYPTO_DEV_DES)
+    ifxdeu_fini_des ();
+    #endif
+    #if defined(CONFIG_CRYPTO_DEV_AES)
+    ifxdeu_fini_aes ();
+    #endif
+    #if defined(CONFIG_CRYPTO_DEV_ARC4)
+    ifxdeu_fini_arc4 ();
+    #endif
+    #if defined(CONFIG_CRYPTO_DEV_SHA1)
+    ifxdeu_fini_sha1 ();
+    #endif
+    #if defined(CONFIG_CRYPTO_DEV_MD5)
+    ifxdeu_fini_md5 ();
+    #endif
+    #if defined(CONFIG_CRYPTO_DEV_SHA1_HMAC)
+    ifxdeu_fini_sha1_hmac ();
+    #endif
+    #if defined(CONFIG_CRYPTO_DEV_MD5_HMAC)
+    ifxdeu_fini_md5_hmac ();
+    #endif
+    printk("DEU has exited successfully\n");
+
+       return 0;
+}
+
+
+int disable_multiblock = 0;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+module_param(disable_multiblock,int,0);
+
+#else
+//MODULE_PARM (disable_multiblock, "i");
+MODULE_PARM_DESC (disable_multiblock,
+          "Disable encryption of whole multiblock buffers.");
+#endif
+
+static const struct of_device_id ltq_deu_match[] = {
+#ifdef CONFIG_DANUBE
+       { .compatible = "lantiq,deu-danube"},
+#elif defined CONFIG_AR9
+       { .compatible = "lantiq,deu-arx100"},
+#elif defined CONFIG_VR9
+       { .compatible = "lantiq,deu-xrx200"},
+#endif
+       {},
+};
+MODULE_DEVICE_TABLE(of, ltq_deu_match);
+
+
+static struct platform_driver ltq_deu_driver = {
+       .probe = ltq_deu_probe,
+       .remove = __devexit_p(ltq_deu_remove),
+       .driver = {
+               .name = "deu",
+               .owner = THIS_MODULE,
+               .of_match_table = ltq_deu_match,
+       },
+};
+
+module_platform_driver(ltq_deu_driver);
+
+MODULE_DESCRIPTION ("Infineon DEU crypto engine support.");
+MODULE_LICENSE ("GPL");
+MODULE_AUTHOR ("Mohammad Firdaus");
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_deu.h b/package/platform/lantiq/ltq-deu/src/ifxmips_deu.h
new file mode 100644 (file)
index 0000000..c842d64
--- /dev/null
@@ -0,0 +1,232 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_deu.h
+** DESCRIPTION  : Data Encryption Unit Driver
+** COPYRIGHT    :       Copyright (c) 2009
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author             $Comment
+** 08,Sept 2009 Mohammad Firdaus    Initial UEIP release
+*******************************************************************************/
+/*!
+  \defgroup IFX_DEU IFX_DEU_DRIVERS
+  \ingroup  API
+  \brief ifx deu driver module
+*/
+
+/*!
+  \file        ifxmips_deu.h
+  \brief main deu driver header file
+*/
+
+/*!
+  \defgroup IFX_DEU_DEFINITIONS IFX_DEU_DEFINITIONS
+  \ingroup  IFX_DEU
+  \brief ifx deu definitions
+*/
+
+
+#ifndef IFXMIPS_DEU_H
+#define IFXMIPS_DEU_H
+
+#include <crypto/algapi.h>
+#include <linux/interrupt.h>
+
+#define IFXDEU_ALIGNMENT 16
+
+#define IFX_DEU_BASE_ADDR                       (KSEG1 | 0x1E103100)
+#define IFX_DEU_CLK                             ((volatile u32 *)(IFX_DEU_BASE_ADDR + 0x0000))
+#define IFX_DES_CON                             ((volatile u32 *)(IFX_DEU_BASE_ADDR + 0x0010))
+#define IFX_AES_CON                             ((volatile u32 *)(IFX_DEU_BASE_ADDR + 0x0050))
+#define IFX_HASH_CON                            ((volatile u32 *)(IFX_DEU_BASE_ADDR + 0x00B0))
+#define IFX_ARC4_CON                            ((volatile u32 *)(IFX_DEU_BASE_ADDR + 0x0100))
+
+#define PFX    "ifxdeu: "
+#define CLC_START IFX_DEU_CLK
+#define IFXDEU_CRA_PRIORITY    300
+#define IFXDEU_COMPOSITE_PRIORITY 400
+//#define KSEG1                         0xA0000000
+#define IFX_PMU_ENABLE 1
+#define IFX_PMU_DISABLE 0
+
+#define CRYPTO_DIR_ENCRYPT 1
+#define CRYPTO_DIR_DECRYPT 0
+
+#define AES_IDLE 0
+#define AES_BUSY 1
+#define AES_STARTED 2
+#define AES_COMPLETED 3
+#define DES_IDLE 0
+#define DES_BUSY 1
+#define DES_STARTED 2
+#define DES_COMPLETED 3
+
+#define PROCESS_SCATTER 1
+#define PROCESS_NEW_PACKET 2
+
+#define PMU_DEU BIT(20)
+#define START_DEU_POWER        \
+    do {                       \
+        volatile struct clc_controlr_t *clc = (struct clc_controlr_t *) CLC_START;  \
+        ltq_pmu_enable(PMU_DEU); \
+        clc->FSOE = 0;           \
+        clc->SBWE = 0;           \
+        clc->SPEN = 0;           \
+        clc->SBWE = 0;           \
+        clc->DISS = 0;           \
+        clc->DISR = 0;           \
+    } while(0)
+
+#define STOP_DEU_POWER         \
+    do {                       \
+        volatile struct clc_controlr_t *clc = (struct clc_controlr_t *) CLC_START; \
+       ltq_pmu_disable(PMU_DEU); \
+        clc->FSOE = 1;         \
+        clc->SBWE = 1;           \
+        clc->SPEN = 1;           \
+        clc->SBWE = 1;           \
+        clc->DISS = 1;           \
+        clc->DISR = 1;           \
+    } while (0)
+
+/* 
+ * Not used anymore in UEIP (use IFX_DES_CON, IFX_AES_CON, etc instead) 
+ * #define DEU_BASE   (KSEG1+0x1E103100)
+ * #define DES_CON             (DEU_BASE+0x10)
+ * #define AES_CON             (DEU_BASE+0x50)
+ * #define HASH_CON    (DEU_BASE+0xB0)
+ * #define DMA_CON             (DEU_BASE+0xEC)
+ * #define INT_CON             (DEU_BASE+0xF4)
+ * #define ARC4_CON    (DEU_BASE+0x100)
+ */
+
+
+int __init ifxdeu_init_des (void);
+int __init ifxdeu_init_aes (void);
+int __init ifxdeu_init_arc4 (void);
+int __init ifxdeu_init_sha1 (void);
+int __init ifxdeu_init_md5 (void);
+int __init ifxdeu_init_sha1_hmac (void);
+int __init ifxdeu_init_md5_hmac (void);
+int __init lqdeu_async_aes_init(void);
+int __init lqdeu_async_des_init(void);
+
+void __exit ifxdeu_fini_des (void);
+void __exit ifxdeu_fini_aes (void);
+void __exit ifxdeu_fini_arc4 (void);
+void __exit ifxdeu_fini_sha1 (void);
+void __exit ifxdeu_fini_md5 (void);
+void __exit ifxdeu_fini_sha1_hmac (void);
+void __exit ifxdeu_fini_md5_hmac (void);
+void __exit ifxdeu_fini_dma(void);
+void __exit lqdeu_fini_async_aes(void);
+void __exit lqdeu_fini_async_des(void);
+void __exit deu_fini (void);
+int deu_dma_init (void);
+
+
+
+#define DEU_WAKELIST_INIT(queue) \
+    init_waitqueue_head(&queue)
+
+#define DEU_WAIT_EVENT_TIMEOUT(queue, event, flags, timeout)     \
+    do {                                                         \
+        wait_event_interruptible_timeout((queue),                \
+            test_bit((event), &(flags)), (timeout));            \
+        clear_bit((event), &(flags));                            \
+    }while (0)
+
+
+#define DEU_WAKEUP_EVENT(queue, event, flags)         \
+    do {                                              \
+        set_bit((event), &(flags));                   \
+        wake_up_interruptible(&(queue));              \
+    }while (0)
+    
+#define DEU_WAIT_EVENT(queue, event, flags)           \
+    do {                                              \
+        wait_event_interruptible(queue,               \
+            test_bit((event), &(flags)));             \
+        clear_bit((event), &(flags));                 \
+    }while (0)
+
+typedef struct deu_drv_priv {
+    wait_queue_head_t  deu_thread_wait;
+#define DEU_EVENT       1
+#define DES_ASYNC_EVENT 2
+#define AES_ASYNC_EVENT 3
+    volatile long      des_event_flags;
+    volatile long      aes_event_flags;
+    volatile long      deu_event_flags;
+    int                event_src;
+    u32                *deu_rx_buf;
+    u32                *outcopy;
+    u32                deu_rx_len;
+
+    struct aes_priv    *aes_dataptr;
+    struct des_priv    *des_dataptr;
+}deu_drv_priv_t;
+
+
+/**
+ *     struct aes_priv_t - ASYNC AES
+ *     @lock: spinlock lock
+ *     @lock_flag: flag for spinlock activities
+ *     @list: crypto queue API list
+ *     @hw_status: DEU hw status flag 
+ *     @aes_wait_flag: flag for sleep queue
+ *     @aes_wait_queue: queue attributes for aes
+ *     @bytes_processed: number of bytes to process by DEU
+ *     @aes_pid: pid number for AES thread
+ *     @aes_sync: atomic wait sync for AES
+ *
+*/
+
+typedef struct {
+    spinlock_t lock;
+    struct crypto_queue list;
+    unsigned int hw_status;
+    volatile long aes_wait_flag;
+    wait_queue_head_t aes_wait_queue;
+
+    pid_t aes_pid;
+
+    struct tasklet_struct aes_task;
+
+} aes_priv_t;
+
+/**
+ *      struct des_priv_t - ASYNC DES
+ *      @lock: spinlock lock
+ *      @list: crypto queue API list
+ *      @hw_status: DEU hw status flag
+ *      @des_wait_flag: flag for sleep queue
+ *      @des_wait_queue: queue attributes for des
+ *      @des_pid: pid number for DES thread
+ *      @des_sync: atomic wait sync for DES
+ *
+*/
+
+typedef struct {
+    spinlock_t lock;
+    struct crypto_queue list;
+    unsigned int hw_status;
+    volatile long des_wait_flag;
+    wait_queue_head_t des_wait_queue;
+
+    pid_t des_pid;
+
+    struct tasklet_struct des_task;
+
+} des_priv_t;
+    
+#endif /* IFXMIPS_DEU_H */
+
+
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_deu_ar9.c b/package/platform/lantiq/ltq-deu/src/ifxmips_deu_ar9.c
new file mode 100644 (file)
index 0000000..9dc3e30
--- /dev/null
@@ -0,0 +1,135 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_deu_ar9.c
+** PROJECT      : IFX UEIP
+** MODULES      : DEU Module for AR9
+**
+** DATE         : September 8, 2009
+** AUTHOR       : Mohammad Firdaus
+** DESCRIPTION  : Data Encryption Unit Driver
+** COPYRIGHT    :       Copyright (c) 2009
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author             $Comment
+** 08,Sept 2009 Mohammad Firdaus    Initial UEIP release
+*******************************************************************************/
+/*!
+  \defgroup IFX_DEU IFX_DEU_DRIVERS
+  \ingroup API
+  \brief ifx deu driver module
+*/
+
+/*!
+  \file        ifxmips_deu_ar9.c
+  \brief ifx deu board specific driver file for ar9
+*/
+
+/*! 
+ \defgroup BOARD_SPECIFIC_FUNCTIONS IFX_BOARD_SPECIFIC_FUNCTIONS 
+ \ingroup IFX_DEU
+ \brief board specific functions
+*/
+
+/* Project header files */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/io.h> //dma_cache_inv
+
+#include "ifxmips_deu_dma.h"
+#include "ifxmips_deu_ar9.h"
+
+/* Function decleration */
+void aes_chip_init (void);
+void des_chip_init (void);
+int deu_dma_init (void);
+u32 endian_swap(u32 input);
+u32* memory_alignment(const u8 *arg, u32 *buff_alloc, int in_out, int nbytes);
+void aes_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+void des_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+void deu_dma_priv_init(void);
+void __exit ifxdeu_fini_dma(void);
+
+#define DES_3DES_START  IFX_DES_CON
+#define AES_START       IFX_AES_CON
+#define CLC_START      IFX_DEU_CLK
+
+/* Variables */
+
+u8 *g_dma_page_ptr = NULL;
+u8 *g_dma_block = NULL;
+u8 *g_dma_block2 = NULL;
+
+deu_drv_priv_t deu_dma_priv;
+
+
+/*! \fn u32 endian_swap(u32 input) 
+ *  \ingroup BOARD_SPECIFIC_FUNCTIONS
+ *  \brief Swap data given to the function 
+ *  \param input   Data input to be swapped
+ *  \return either the swapped data or the input data depending on whether it is in DMA mode or FPI mode
+*/
+u32 endian_swap(u32 input)
+{
+    return input;
+}
+
+/*! \fn        u32 input_swap(u32 input)
+ *  \ingroup BOARD_SPECIFIC_FUNCTIONS
+ *  \brief Not used  
+ *  \return input
+*/
+
+u32 input_swap(u32 input)
+{
+    return input;
+}
+
+/*! \fn void aes_chip_init (void)
+ *  \ingroup BOARD_SPECIFIC_FUNCTIONS
+ *  \brief initialize AES hardware   
+*/
+
+void aes_chip_init (void)
+{
+   volatile struct aes_t *aes = (struct aes_t *) AES_START;
+
+   aes->controlr.SM = 1;
+   aes->controlr.ARS = 1;
+
+}
+
+/*! \fn void des_chip_init (void)
+ *  \ingroup BOARD_SPECIFIC_FUNCTIONS
+ *  \brief initialize DES hardware
+*/         
+                        
+void des_chip_init (void)
+{
+    volatile struct des_t *des = (struct des_t *) DES_3DES_START;
+
+    // start crypto engine with write to ILR
+    des->controlr.SM = 1;
+    asm("sync");
+    des->controlr.ARS = 1;
+
+}
+
+/*! \fn void chip_version(void) 
+ *  \ingroup BOARD_SPECIFIC_FUNCTIONS
+ *  \brief not used!
+*/     
+
+void chip_version(void) 
+{
+    return;
+}
+
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_deu_ar9.h b/package/platform/lantiq/ltq-deu/src/ifxmips_deu_ar9.h
new file mode 100644 (file)
index 0000000..1d84da3
--- /dev/null
@@ -0,0 +1,299 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_deu_ar9.h
+** PROJECT      : IFX UEIP
+** MODULES      : DEU Module for AR9
+**
+** DATE         : September 8, 2009
+** AUTHOR       : Mohammad Firdaus
+** DESCRIPTION  : Data Encryption Unit Driver
+** COPYRIGHT    :       Copyright (c) 2009
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author             $Comment
+** 08,Sept 2009 Mohammad Firdaus    Initial UEIP release
+*******************************************************************************/
+/*!
+  \defgroup IFX_DEU IFX_DEU_DRIVERS
+  \ingroup API
+  \brief deu driver module
+*/
+
+/*!
+  \defgroup IFX_DEU_DEFINITIONS IFX_DEU_DEFINITIONS
+  \ingroup IFX_DEU
+  \brief ifx deu definitions
+*/
+
+/*!
+  \file                ifxmips_deu_ar9.h
+  \brief       deu driver header file
+*/
+
+
+#ifndef IFXMIPS_DEU_AR9_H
+#define IFXMIPS_DEU_AR9_H
+
+/* Project Header Files */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/crypto.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+#include <crypto/algapi.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <asm/scatterlist.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include "ifxmips_deu.h"
+
+
+/* SHA CONSTANTS */
+#define HASH_CON_VALUE    0x0700002C
+
+#define INPUT_ENDIAN_SWAP(input)    input_swap(input)
+#define DEU_ENDIAN_SWAP(input)    endian_swap(input)
+#define DELAY_PERIOD    10 
+#define FIND_DEU_CHIP_VERSION    chip_version()
+#define CLC_START IFX_DEU_CLK 
+
+#define AES_INIT 0
+#define DES_INIT 1
+#define ARC4_INIT 2
+#define SHA1_INIT 3
+#define MD5_INIT 4
+#define SHA1_HMAC_INIT 5
+#define MD5_HMAC_INIT 6
+
+#define AES_START IFX_AES_CON
+#define DES_3DES_START  IFX_DES_CON
+                                     
+#define WAIT_AES_DMA_READY()          \
+    do {                             \
+        int i;                       \
+        volatile struct deu_dma_t *dma = (struct deu_dma_t *) IFX_DEU_DMA_CON; \
+        volatile struct aes_t *aes = (volatile struct aes_t *) AES_START; \
+        for (i = 0; i < 10; i++)      \
+           udelay(DELAY_PERIOD);     \
+        while (dma->controlr.BSY) {}; \
+        while (aes->controlr.BUS) {}; \
+    } while (0)
+
+#define WAIT_DES_DMA_READY()          \
+    do {                             \
+        int i;                       \
+        volatile struct deu_dma_t *dma = (struct deu_dma_t *) IFX_DEU_DMA_CON; \
+        volatile struct des_t *des = (struct des_t *) DES_3DES_START; \
+        for (i = 0; i < 10; i++)      \
+            udelay(DELAY_PERIOD);     \
+        while (dma->controlr.BSY) {}; \
+        while (des->controlr.BUS) {}; \
+    } while (0)
+
+#define AES_DMA_MISC_CONFIG()        \
+    do {                             \
+        volatile struct aes_t *aes = (volatile struct aes_t *) AES_START; \
+        aes->controlr.KRE = 1;        \
+        aes->controlr.GO = 1;         \
+    } while(0)
+
+#define SHA_HASH_INIT                  \
+    do {                               \
+        volatile struct deu_hash_t *hash = (struct deu_hash_t *) HASH_START; \
+        hash->controlr.SM = 1;    \
+        hash->controlr.ALGO = 0;  \
+        hash->controlr.INIT = 1;  \
+    } while(0)
+
+/* DEU Common Structures for AR9*/
+struct clc_controlr_t {
+       u32 Res:26;
+       u32 FSOE:1;
+       u32 SBWE:1;
+       u32 EDIS:1;
+       u32 SPEN:1;
+       u32 DISS:1;
+       u32 DISR:1;
+
+};
+
+struct des_t {
+       struct des_controlr {   //10h
+               u32 KRE:1;
+               u32 reserved1:5;
+               u32 GO:1;
+               u32 STP:1;
+               u32 Res2:6;
+                u32 NDC:1;
+                u32 ENDI:1;
+                u32 Res3:2;
+               u32 F:3;
+               u32 O:3;
+               u32 BUS:1;
+               u32 DAU:1;
+               u32 ARS:1;
+               u32 SM:1;
+               u32 E_D:1;
+               u32 M:3;
+
+       } controlr;
+       u32 IHR;                //14h
+       u32 ILR;                //18h
+       u32 K1HR;               //1c
+       u32 K1LR;               //
+       u32 K2HR;
+       u32 K2LR;
+       u32 K3HR;
+       u32 K3LR;               //30h
+       u32 IVHR;               //34h
+       u32 IVLR;               //38
+       u32 OHR;                //3c
+       u32 OLR;                //40
+};
+
+struct aes_t {
+       struct aes_controlr {
+
+               u32 KRE:1;
+               u32 reserved1:4;
+               u32 PNK:1;
+               u32 GO:1;
+               u32 STP:1;
+               u32 reserved2:6;
+               u32 NDC:1;
+               u32 ENDI:1;
+                u32 reserved3:2;
+               u32 F:3;        //fbs
+               u32 O:3;        //om
+               u32 BUS:1;      //bsy
+               u32 DAU:1;
+               u32 ARS:1;
+               u32 SM:1;
+               u32 E_D:1;
+               u32 KV:1;
+               u32 K:2;        //KL
+
+       } controlr;
+       u32 ID3R;               //80h
+       u32 ID2R;               //84h
+       u32 ID1R;               //88h
+       u32 ID0R;               //8Ch
+       u32 K7R;                //90h
+       u32 K6R;                //94h
+       u32 K5R;                //98h
+       u32 K4R;                //9Ch
+       u32 K3R;                //A0h
+       u32 K2R;                //A4h
+       u32 K1R;                //A8h
+       u32 K0R;                //ACh
+       u32 IV3R;               //B0h
+       u32 IV2R;               //B4h
+       u32 IV1R;               //B8h
+       u32 IV0R;               //BCh
+       u32 OD3R;               //D4h
+       u32 OD2R;               //D8h
+       u32 OD1R;               //DCh
+       u32 OD0R;               //E0h
+};
+
+struct arc4_t {
+       struct arc4_controlr {
+
+               u32 KRE:1;
+               u32 KLEN:4;
+               u32 KSAE:1;
+               u32 GO:1;
+               u32 STP:1;
+               u32 reserved1:6;
+               u32 NDC:1;
+               u32 ENDI:1;
+               u32 reserved2:8;
+               u32 BUS:1;      //bsy
+               u32 reserved3:1;
+               u32 ARS:1;
+               u32 SM:1;
+               u32 reserved4:4;                                                
+
+       } controlr;
+       u32 K3R;                //104h
+       u32 K2R;                //108h
+       u32 K1R;                //10Ch
+       u32 K0R;                //110h
+
+        u32 IDLEN;             //114h
+
+       u32 ID3R;               //118h
+       u32 ID2R;               //11Ch
+       u32 ID1R;               //120h
+       u32 ID0R;               //124h
+       
+       u32 OD3R;               //128h
+       u32 OD2R;               //12Ch
+       u32 OD1R;               //130h
+       u32 OD0R;               //134h
+};
+
+struct deu_hash_t {
+       struct hash_controlr {
+               u32 reserved1:5;
+               u32 KHS:1;              
+               u32 GO:1;
+               u32 INIT:1;
+               u32 reserved2:6;
+               u32 NDC:1;
+               u32 ENDI:1;
+               u32 reserved3:7;
+               u32 DGRY:1;             
+               u32 BSY:1;
+               u32 reserved4:1;
+               u32 IRCL:1;
+               u32 SM:1;
+               u32 KYUE:1;
+                u32 HMEN:1;
+               u32 SSEN:1;
+               u32 ALGO:1;
+
+       } controlr;
+       u32 MR;                 //B4h
+       u32 D1R;                //B8h
+       u32 D2R;                //BCh
+       u32 D3R;                //C0h
+       u32 D4R;                //C4h
+       u32 D5R;                //C8h
+
+       u32 dummy;              //CCh
+
+       u32 KIDX;               //D0h
+       u32 KEY;                //D4h
+       u32 DBN;                //D8h
+};
+
+
+struct deu_dma_t {
+       struct dma_controlr {
+               u32 reserved1:22;
+               u32 BS:2;
+               u32 BSY:1;
+               u32 reserved2:1;
+               u32 ALGO:2;
+               u32 RXCLS:2;
+               u32 reserved3:1;
+               u32 EN:1;
+
+       } controlr;
+};
+
+#endif /* IFXMIPS_DEU_AR9_H */
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_deu_danube.c b/package/platform/lantiq/ltq-deu/src/ifxmips_deu_danube.c
new file mode 100644 (file)
index 0000000..492391d
--- /dev/null
@@ -0,0 +1,168 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_deu_danube.c
+** PROJECT      : IFX UEIP
+** MODULES      : DEU Module for Danube
+**
+** DATE         : September 8, 2009
+** AUTHOR       : Mohammad Firdaus
+** DESCRIPTION  : Data Encryption Unit Driver
+** COPYRIGHT    :       Copyright (c) 2009
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author             $Comment
+** 08,Sept 2009 Mohammad Firdaus    Initial UEIP release
+*******************************************************************************/
+/*!
+  \defgroup IFX_DEU IFX_DEU_DRIVERS
+  \ingroup API
+  \brief deu driver module
+*/
+
+/*!
+  \file        ifxmips_deu_danube.c
+  \ingroup IFX_DEU
+  \brief board specific deu driver file for danube
+*/
+
+/*!
+  \defgroup BOARD_SPECIFIC_FUNCTIONS IFX_BOARD_SPECIFIC_FUNCTIONS
+  \ingroup IFX_DEU
+  \brief board specific deu functions
+*/
+
+/* Project header files */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/io.h> //dma_cache_inv
+
+#include "ifxmips_deu_dma.h"
+#include "ifxmips_deu_danube.h"
+
+
+/* Function Declerations */
+int aes_memory_allocate(int value);
+int des_memory_allocate(int value);
+void memory_release(u32 *addr); 
+int aes_chip_init (void);
+void des_chip_init (void);
+int deu_dma_init (void);
+u32 endian_swap(u32 input);
+u32* memory_alignment(const u8 *arg, u32 *buff_alloc, int in_out, int nbytes);
+void dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+void chip_version(void); 
+void deu_dma_priv_init(void);
+void __exit ifxdeu_fini_dma(void);
+
+#define DES_3DES_START  IFX_DES_CON
+#define AES_START       IFX_AES_CON
+#define CLC_START       IFX_DEU_CLK
+
+/* Variables definition */
+int ifx_danube_pre_1_4; 
+u8 *g_dma_page_ptr = NULL;
+u8 *g_dma_block = NULL;
+u8 *g_dma_block2 = NULL;
+
+deu_drv_priv_t deu_dma_priv;
+
+
+/*! \fn u32 endian_swap(u32 input) 
+ *  \ingroup BOARD_SPECIFIC_FUNCTIONS
+ *  \brief function is not used
+ *  \param input Data input to be swapped
+ *  \return input
+*/
+
+u32 endian_swap(u32 input)
+{
+    return input;
+}
+
+/*! \fn        u32 input_swap(u32 input)
+ *  \ingroup BOARD_SPECIFIC_FUNCTIONS
+ *  \brief Swap the input data if the current chip is Danube version
+ *         1.4 and do nothing to the data if the current chip is 
+ *         Danube version 1.3 
+ *  \param input data that needs to be swapped
+ *  \return input or swapped input
+*/
+
+u32 input_swap(u32 input)
+{
+    if (!ifx_danube_pre_1_4) {
+        u8 *ptr = (u8 *)&input;
+        return ((ptr[3] << 24) | (ptr[2] << 16) | (ptr[1] << 8) | ptr[0]); 
+    }
+    else 
+        return input;
+}
+
+
+
+/*! \fn void aes_chip_init (void)
+ *  \ingroup BOARD_SPECIFIC_FUNCTIONS
+ * \brief initialize AES hardware   
+*/
+
+int aes_chip_init (void)
+{
+    volatile struct aes_t *aes = (struct aes_t *) AES_START;
+
+    //start crypto engine with write to ILR
+    aes->controlr.SM = 1;
+    aes->controlr.ARS = 1;
+    return 0;
+}
+
+/*! \fn void des_chip_init (void)
+ *  \ingroup BOARD_SPECIFIC_FUNCTIONS
+ *  \brief initialize DES hardware
+*/  
+                        
+void des_chip_init (void)
+{
+        volatile struct des_t *des = (struct des_t *) DES_3DES_START;
+
+        // start crypto engine with write to ILR
+        des->controlr.SM = 1;
+        des->controlr.ARS = 1;
+}
+
+/*! \fn void chip_version (void)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief To find the version of the chip by looking at the chip ID
+ *  \param ifx_danube_pre_1_4 (sets to 1 if Chip is Danube less than v1.4)
+*/  
+#define IFX_MPS               (KSEG1 | 0x1F107000)
+#define IFX_MPS_CHIPID                          ((volatile u32*)(IFX_MPS + 0x0344))
+
+void chip_version(void) 
+{
+
+    /* DANUBE PRE 1.4 SOFTWARE FIX */
+    int chip_id = 0;
+    chip_id = *IFX_MPS_CHIPID;
+    chip_id >>= 28;
+
+    if (chip_id >= 4) {
+        ifx_danube_pre_1_4 = 0;
+        printk("Danube Chip ver. 1.4 detected. \n");
+    }
+    else {
+        ifx_danube_pre_1_4 = 1; 
+        printk("Danube Chip ver. 1.3 or below detected. \n");
+    }
+
+    return;
+}
+
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_deu_danube.h b/package/platform/lantiq/ltq-deu/src/ifxmips_deu_danube.h
new file mode 100644 (file)
index 0000000..62ad96d
--- /dev/null
@@ -0,0 +1,250 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_deu_danube.h
+** PROJECT      : IFX UEIP
+** MODULES      : DEU Module for Danube
+**
+** DATE         : September 8, 2009
+** AUTHOR       : Mohammad Firdaus
+** DESCRIPTION  : Data Encryption Unit Driver
+** COPYRIGHT    :       Copyright (c) 2009
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author             $Comment
+** 08,Sept 2009 Mohammad Firdaus    Initial UEIP release
+*******************************************************************************/
+/*!
+  \defgroup IFX_DEU IFX_DEU_DRIVERS
+  \ingroup API
+  \brief deu driver module
+*/
+
+/*!
+  \file        ifxmips_deu_danube.h
+  \brief board specific driver header file for danube
+*/
+
+/*!
+  \defgroup BOARD_SPECIFIC_FUNCTIONS IFX_BOARD_SPECIFIC_FUNCTIONS
+  \ingroup IFX_DEU
+  \brief board specific deu header files
+*/
+
+#ifndef IFXMIPS_DEU_DANUBE_H
+#define IFXMIPS_DEU_DANUBE_H
+
+/* Project Header Files */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/crypto.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+#include <crypto/algapi.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <asm/scatterlist.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include "ifxmips_deu.h"
+
+
+
+#define INPUT_ENDIAN_SWAP(input)                             input_swap(input)
+#define DEU_ENDIAN_SWAP(input)                                endian_swap(input)
+#define FIND_DEU_CHIP_VERSION                                chip_version()
+#define AES_DMA_MISC_CONFIG()
+#define CLC_START IFX_DEU_CLK
+
+#define AES_START IFX_AES_CON
+#define DES_3DES_START  IFX_DES_CON
+
+#define AES_INIT 0
+#define DES_INIT 1
+#define SHA1_INIT 2 
+#define MD5_INIT 3
+
+#define WAIT_AES_DMA_READY()          \
+    do {                             \
+        int i;                       \
+        volatile struct deu_dma_t *dma = (struct deu_dma_t *) IFX_DEU_DMA_CON; \
+        volatile struct aes_t *aes = (volatile struct aes_t *) AES_START; \
+        for (i = 0; i < 10; i++)      \
+            udelay(DELAY_PERIOD);     \
+        while (dma->controlr.BSY) {}; \
+        while (aes->controlr.BUS) {}; \
+    } while (0)
+
+#define WAIT_DES_DMA_READY()          \
+    do {                             \
+        int i;                       \
+        volatile struct deu_dma_t *dma = (struct deu_dma_t *) IFX_DEU_DMA_CON; \
+        volatile struct des_t *des = (struct des_t *) DES_3DES_START; \
+        for (i = 0; i < 10; i++)      \
+            udelay(DELAY_PERIOD);     \
+        while (dma->controlr.BSY) {}; \
+        while (des->controlr.BUS) {}; \
+    } while (0)     
+
+#define SHA_HASH_INIT                  \
+    do {                               \
+        volatile struct deu_hash_t *hash = (struct deu_hash_t *) HASH_START; \
+        hash->controlr.SM = 1;    \
+        hash->controlr.ALGO = 0;  \
+        hash->controlr.INIT = 1;  \
+    } while(0)
+
+/* DEU STRUCTURES */
+
+struct clc_controlr_t {
+       u32 Res:26;
+       u32 FSOE:1;
+       u32 SBWE:1;
+       u32 EDIS:1;
+       u32 SPEN:1;
+       u32 DISS:1;
+       u32 DISR:1;
+
+};
+
+struct des_t {
+       struct des_controlr {   //10h
+               u32 KRE:1;
+               u32 reserved1:5;
+               u32 GO:1;
+               u32 STP:1;
+               u32 Res2:6;
+               u32 NDC:1;
+               u32 ENDI:1;
+               u32 Res3:2;
+               u32 F:3;
+               u32 O:3;
+               u32 BUS:1;
+               u32 DAU:1;
+               u32 ARS:1;
+               u32 SM:1;
+               u32 E_D:1;
+               u32 M:3;
+
+       } controlr;
+       u32 IHR;                //14h
+       u32 ILR;                //18h
+       u32 K1HR;               //1c
+       u32 K1LR;               //
+       u32 K2HR;
+       u32 K2LR;
+       u32 K3HR;
+       u32 K3LR;               //30h
+       u32 IVHR;               //34h
+       u32 IVLR;               //38
+       u32 OHR;                //3c
+       u32 OLR;                //40
+};
+
+struct aes_t {
+       struct aes_controlr {
+
+               u32 KRE:1;
+               u32 reserved1:4;
+               u32 PNK:1;
+               u32 GO:1;
+               u32 STP:1;
+               
+               u32 reserved2:6;
+               u32 NDC:1;
+               u32 ENDI:1;             
+               u32 reserved3:2;
+               
+               u32 F:3;        //fbs
+               u32 O:3;        //om
+               u32 BUS:1;      //bsy
+               u32 DAU:1;
+               u32 ARS:1;
+               u32 SM:1;
+               u32 E_D:1;
+               u32 KV:1;
+               u32 K:2;        //KL
+
+       } controlr;
+       u32 ID3R;               //80h
+       u32 ID2R;               //84h
+       u32 ID1R;               //88h
+       u32 ID0R;               //8Ch
+       u32 K7R;                //90h
+       u32 K6R;                //94h
+       u32 K5R;                //98h
+       u32 K4R;                //9Ch
+       u32 K3R;                //A0h
+       u32 K2R;                //A4h
+       u32 K1R;                //A8h
+       u32 K0R;                //ACh
+       u32 IV3R;               //B0h
+       u32 IV2R;               //B4h
+       u32 IV1R;               //B8h
+       u32 IV0R;               //BCh
+       u32 OD3R;               //D4h
+       u32 OD2R;               //D8h
+       u32 OD1R;               //DCh
+       u32 OD0R;               //E0h
+};
+
+struct deu_hash_t {
+       struct hash_controlr {
+               u32 reserved1:5;
+               u32 KHS:1;              
+               u32 GO:1;
+               u32 INIT:1;
+               u32 reserved2:6;
+               u32 NDC:1;
+               u32 ENDI:1;
+               u32 reserved3:7;
+               u32 DGRY:1;             
+               u32 BSY:1;
+               u32 reserved4:1;
+               u32 IRCL:1;
+               u32 SM:1;
+               u32 KYUE:1;
+                u32 HMEN:1;
+               u32 SSEN:1;
+               u32 ALGO:1;
+
+       } controlr;
+       u32 MR;                 //B4h
+       u32 D1R;                //B8h
+       u32 D2R;                //BCh
+       u32 D3R;                //C0h
+       u32 D4R;                //C4h
+       u32 D5R;                //C8h
+
+       u32 dummy;              //CCh
+
+       u32 KIDX;               //D0h
+       u32 KEY;                //D4h
+       u32 DBN;                //D8h
+};
+
+struct deu_dma_t {
+       struct dma_controlr {
+               u32 reserved1:22;
+               u32 BS:2;
+               u32 BSY:1;
+               u32 reserved2:1;
+               u32 ALGO:2;
+               u32 RXCLS:2;
+               u32 reserved3:1;
+               u32 EN:1;
+
+       } controlr;
+};
+
+#endif  /* IFXMIPS_DEU_DANUBE_H */
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_deu_dma.c b/package/platform/lantiq/ltq-deu/src/ifxmips_deu_dma.c
new file mode 100644 (file)
index 0000000..13dc921
--- /dev/null
@@ -0,0 +1,42 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_deu_dma.c
+** PROJECT      : IFX UEIP
+** MODULES      : DEU Module for Danube
+**
+** DATE         : September 8, 2009
+** AUTHOR       : Mohammad Firdaus
+** DESCRIPTION  : Data Encryption Unit Driver
+** COPYRIGHT    :       Copyright (c) 2009
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author             $Comment
+** 08 Sept 2009 Mohammad Firdaus    Initial UEIP release
+*******************************************************************************/
+/*!
+  \defgroup IFX_DEU IFX_DEU_DRIVERS
+  \ingroup  IFX_API
+  \brief ifx deu driver module
+*/
+
+/*!
+  \file        ifxmips_deu_dma.c
+  \ingroup IFX_DEU
+  \brief DMA deu driver file 
+*/
+
+/*!
+ \defgroup IFX_DMA_FUNCTIONS IFX_DMA_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief deu-dma driver functions
+*/
+
+/* Project header files */ 
+
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_deu_dma.h b/package/platform/lantiq/ltq-deu/src/ifxmips_deu_dma.h
new file mode 100644 (file)
index 0000000..5198a4a
--- /dev/null
@@ -0,0 +1,69 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_deu_dma.h
+** DESCRIPTION  : Data Encryption Unit Driver
+** COPYRIGHT    :       Copyright (c) 2009
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author             $Comment
+** 08,Sept 2009 Mohammad Firdaus    Initial UEIP release
+*******************************************************************************/
+
+/*!
+  \addtogroup    IFX_DEU IFX_DEU_DRIVERS
+  \ingroup      API
+  \brief        ifx deu driver module
+*/
+
+/*!
+  \file                ifxmips_deu_dma.h
+  \ingroup     IFX_DEU
+  \brief       DMA deu driver header file
+*/
+
+#ifndef IFXMIPS_DEU_DMA_H
+#define IFXMIPS_DEU_DMA_H
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/crypto.h>
+#include <asm/scatterlist.h>
+#include <asm/byteorder.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+
+// must match the size of memory block allocated for g_dma_block and g_dma_block2
+#define DEU_MAX_PACKET_SIZE    (PAGE_SIZE >> 1)
+
+typedef struct ifx_deu_device {
+       struct dma_device_info *dma_device;
+       u8 *dst;
+       u8 *src;
+       int len;
+       int dst_count;
+       int src_count;
+       int recv_count;
+       int packet_size;
+       int packet_num;
+       wait_queue_t wait;
+} _ifx_deu_device;
+
+extern _ifx_deu_device ifx_deu[1];
+
+extern int deu_dma_intr_handler (struct dma_device_info *, int);
+extern u8 *deu_dma_buffer_alloc (int, int *, void **);
+extern int deu_dma_buffer_free (u8 *, void *);
+extern void deu_dma_inactivate_poll(struct dma_device_info* dma_dev);
+extern void deu_dma_activate_poll (struct dma_device_info* dma_dev);
+extern struct dma_device_info* deu_dma_reserve(struct dma_device_info** dma_device);
+extern int deu_dma_release(struct dma_device_info** dma_device);
+
+#endif /* IFMIPS_DEU_DMA_H */
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_deu_vr9.c b/package/platform/lantiq/ltq-deu/src/ifxmips_deu_vr9.c
new file mode 100644 (file)
index 0000000..aaa7bce
--- /dev/null
@@ -0,0 +1,144 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_deu_vr9.c
+** PROJECT      : IFX UEIP
+** MODULES      : DEU Module for VR9
+**
+** DATE         : September 8, 2009
+** AUTHOR       : Mohammad Firdaus
+** DESCRIPTION  : Data Encryption Unit Driver
+** COPYRIGHT    :       Copyright (c) 2009
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author             $Comment
+** 08,Sept 2009 Mohammad Firdaus    Initial UEIP release
+*******************************************************************************/
+
+/*!
+  \defgroup  IFX_DEU IFX_DEU_DRIVERS
+  \ingroup  API
+  \brief deu driver module
+*/
+
+/*!
+  \file                ifxmips_deu_vr9.c
+  \ingroup     IFX_DEU
+  \brief       board specific deu driver file for vr9
+*/
+
+/*!
+  \defgroup   BOARD_SPECIFIC_FUNCTIONS IFX_BOARD_SPECIFIC_FUNCTIONS
+  \ingroup IFX_DEU
+  \brief board specific deu driver functions
+*/
+
+/* Project header files */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/io.h> //dma_cache_inv
+
+#include "ifxmips_deu_dma.h"
+#include "ifxmips_deu_vr9.h"
+
+/* Function decleration */
+void aes_chip_init (void);
+void des_chip_init (void);
+int deu_dma_init (void);
+void deu_dma_priv_init(void);
+u32 endian_swap(u32 input);
+u32* memory_alignment(const u8 *arg, u32 *buff_alloc, int in_out, int nbytes);
+void aes_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+void des_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+void __exit ifxdeu_fini_dma(void);
+
+#define DES_3DES_START  IFX_DES_CON
+#define AES_START       IFX_AES_CON
+
+/* Variables */
+
+u8 *g_dma_page_ptr = NULL;
+u8 *g_dma_block = NULL;
+u8 *g_dma_block2 = NULL;
+
+deu_drv_priv_t deu_dma_priv;
+
+
+/*! \fn u32 endian_swap(u32 input) 
+ *  \ingroup BOARD_SPECIFIC_FUNCTIONS
+ *  \brief Swap data given to the function 
+ *  \param input Data input to be swapped
+ *  \return either the swapped data or the input data depending on whether it is in DMA mode or FPI mode
+*/
+
+
+u32 endian_swap(u32 input)
+{
+    return input;
+}
+
+/*! \fn u32 input_swap(u32 input)
+ *  \ingroup BOARD_SPECIFIC_FUNCTIONS
+ *  \brief Not used  
+ *  \return input
+*/
+
+u32 input_swap(u32 input)
+{
+    return input;
+}
+
+/*! \fn void aes_chip_init (void)
+ *  \ingroup BOARD_SPECIFIC_FUNCTIONS
+ *  \brief initialize AES hardware   
+*/
+
+void aes_chip_init (void)
+{
+    volatile struct aes_t *aes = (struct aes_t *) AES_START;
+
+    // start crypto engine with write to ILR
+    aes->controlr.SM = 1;
+    aes->controlr.NDC = 0;
+    asm("sync");
+    aes->controlr.ENDI = 1;
+    asm("sync");
+    aes->controlr.ARS = 0;
+       
+}
+
+/*! \fn void des_chip_init (void)
+ *  \ingroup IFX_AES_FUNCTIONS
+ *  \brief initialize DES hardware
+*/         
+                        
+void des_chip_init (void)
+{
+    volatile struct des_t *des = (struct des_t *) DES_3DES_START;
+
+    // start crypto engine with write to ILR
+    des->controlr.SM = 1;
+    des->controlr.NDC = 1;
+    asm("sync");
+    des->controlr.ENDI = 1;
+    asm("sync");    
+    des->controlr.ARS = 0;
+
+}
+/*! \fn void chip_version(void)
+ *  \ingroup IFX_DES_FUNCTIONS
+ *  \brief function not used in VR9
+*/
+void chip_version(void) 
+{
+    return;
+}
+
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_deu_vr9.h b/package/platform/lantiq/ltq-deu/src/ifxmips_deu_vr9.h
new file mode 100644 (file)
index 0000000..d2cfd11
--- /dev/null
@@ -0,0 +1,324 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_deu_vr9.h
+** PROJECT      : IFX UEIP
+** MODULES      : DEU Module for VR9
+**
+** DATE         : September 8, 2009
+** AUTHOR       : Mohammad Firdaus
+** DESCRIPTION  : Data Encryption Unit Driver
+** COPYRIGHT    :       Copyright (c) 2009
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author             $Comment
+** 08,Sept 2009 Mohammad Firdaus    Initial UEIP release
+*******************************************************************************/
+/*!
+  \defgroup IFX_DEU IFX_DEU_DRIVERS
+  \ingroup API
+  \brief deu driver module
+*/
+
+/*!
+  \file        ifxmips_deu_vr9.h
+  \ingroup IFX_DEU
+  \brief board specific deu driver header file for vr9
+*/
+
+/*!
+  \defgroup IFX_DEU_DEFINITIONS IFX_DEU_DEFINITIONS
+  \brief deu driver header file
+*/
+
+
+#ifndef IFXMIPS_DEU_VR9_H
+#define IFXMIPS_DEU_VR9_H
+
+/* Project Header Files */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/crypto.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+#include <crypto/algapi.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <asm/scatterlist.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include "ifxmips_deu.h"
+
+
+#define AES_INIT 1
+#define DES_INIT 2
+#define ARC4_INIT 3
+#define SHA1_INIT 4
+#define MD5_INIT 5
+#define SHA1_HMAC_INIT 6
+#define MD5_HMAC_INIT 7
+
+#define AES_START IFX_AES_CON
+#define DES_3DES_START  IFX_DES_CON
+
+#if 0
+#define AES_IDLE 0
+#define AES_BUSY 1
+#define AES_STARTED 2
+#define AES_COMPLETED 3
+#define DES_IDLE 0
+#define DES_BUSY 1
+#define DES_STARTED 2
+#define DES_COMPLETED 3
+#endif
+
+/* SHA1 CONSTANT */
+#define HASH_CON_VALUE    0x0701002C
+
+#define INPUT_ENDIAN_SWAP(input)    input_swap(input)
+#define DEU_ENDIAN_SWAP(input)    endian_swap(input)
+#define FIND_DEU_CHIP_VERSION    chip_version() 
+
+#if defined (CONFIG_AR10)
+#define DELAY_PERIOD    30
+#else
+#define DELAY_PERIOD    10
+#endif
+                                     
+#define WAIT_AES_DMA_READY()          \
+    do {                             \
+        int i;                       \
+        volatile struct deu_dma_t *dma = (struct deu_dma_t *) IFX_DEU_DMA_CON; \
+        volatile struct aes_t *aes = (volatile struct aes_t *) AES_START; \
+        for (i = 0; i < 10; i++)      \
+            udelay(DELAY_PERIOD);     \
+        while (dma->controlr.BSY) {}; \
+        while (aes->controlr.BUS) {}; \
+    } while (0)
+
+#define WAIT_DES_DMA_READY()          \
+    do {                             \
+        int i;                       \
+        volatile struct deu_dma_t *dma = (struct deu_dma_t *) IFX_DEU_DMA_CON; \
+        volatile struct des_t *des = (struct des_t *) DES_3DES_START; \
+        for (i = 0; i < 10; i++)      \
+            udelay(DELAY_PERIOD);     \
+        while (dma->controlr.BSY) {}; \
+        while (des->controlr.BUS) {}; \
+    } while (0)
+
+#define AES_DMA_MISC_CONFIG()        \
+    do { \
+        volatile struct aes_t *aes = (volatile struct aes_t *) AES_START; \
+        aes->controlr.KRE = 1;        \
+        aes->controlr.GO = 1;         \
+    } while(0)
+
+#define SHA_HASH_INIT                \
+    do {                               \
+        volatile struct deu_hash_t *hash = (struct deu_hash_t *) HASH_START; \
+        hash->controlr.ENDI = 1;  \
+        hash->controlr.SM = 1;    \
+        hash->controlr.ALGO = 0;  \
+        hash->controlr.INIT = 1;  \
+    } while(0)
+
+#define MD5_HASH_INIT                \
+    do {                               \
+        volatile struct deu_hash_t *hash = (struct deu_hash_t *) HASH_START; \
+        hash->controlr.ENDI = 1;  \
+        hash->controlr.SM = 1;    \
+        hash->controlr.ALGO = 1;  \
+        hash->controlr.INIT = 1;  \
+    } while(0)
+
+/* DEU Common Structures for AR9*/
+struct clc_controlr_t {
+       u32 Res:26;
+       u32 FSOE:1;
+       u32 SBWE:1;
+       u32 EDIS:1;
+       u32 SPEN:1;
+       u32 DISS:1;
+       u32 DISR:1;
+
+};
+
+struct des_t {
+       struct des_controlr {   //10h
+               u32 KRE:1;
+               u32 reserved1:5;
+               u32 GO:1;
+               u32 STP:1;
+               u32 Res2:6;
+                u32 NDC:1;
+                u32 ENDI:1;
+                u32 Res3:2;
+               u32 F:3;
+               u32 O:3;
+               u32 BUS:1;
+               u32 DAU:1;
+               u32 ARS:1;
+               u32 SM:1;
+               u32 E_D:1;
+               u32 M:3;
+
+       } controlr;
+       u32 IHR;                //14h
+       u32 ILR;                //18h
+       u32 K1HR;               //1c
+       u32 K1LR;               //
+       u32 K2HR;
+       u32 K2LR;
+       u32 K3HR;
+       u32 K3LR;               //30h
+       u32 IVHR;               //34h
+       u32 IVLR;               //38
+       u32 OHR;                //3c
+       u32 OLR;                //40
+};
+
+struct aes_t {
+       struct aes_controlr {
+
+               u32 KRE:1;
+               u32 reserved1:4;
+               u32 PNK:1;
+               u32 GO:1;
+               u32 STP:1;
+               u32 reserved2:6;
+               u32 NDC:1;
+               u32 ENDI:1;
+                u32 reserved3:2;
+               u32 F:3;        //fbs
+               u32 O:3;        //om
+               u32 BUS:1;      //bsy
+               u32 DAU:1;
+               u32 ARS:1;
+               u32 SM:1;
+               u32 E_D:1;
+               u32 KV:1;
+               u32 K:2;        //KL
+
+       } controlr;
+       u32 ID3R;               //80h
+       u32 ID2R;               //84h
+       u32 ID1R;               //88h
+       u32 ID0R;               //8Ch
+       u32 K7R;                //90h
+       u32 K6R;                //94h
+       u32 K5R;                //98h
+       u32 K4R;                //9Ch
+       u32 K3R;                //A0h
+       u32 K2R;                //A4h
+       u32 K1R;                //A8h
+       u32 K0R;                //ACh
+       u32 IV3R;               //B0h
+       u32 IV2R;               //B4h
+       u32 IV1R;               //B8h
+       u32 IV0R;               //BCh
+       u32 OD3R;               //D4h
+       u32 OD2R;               //D8h
+       u32 OD1R;               //DCh
+       u32 OD0R;               //E0h
+};
+
+struct arc4_t {
+       struct arc4_controlr {
+
+               u32 KRE:1;
+               u32 KLEN:4;
+               u32 KSAE:1;
+               u32 GO:1;
+               u32 STP:1;
+               u32 reserved1:6;
+               u32 NDC:1;
+               u32 ENDI:1;
+               u32 reserved2:8;
+               u32 BUS:1;      //bsy
+               u32 reserved3:1;
+               u32 ARS:1;
+               u32 SM:1;
+               u32 reserved4:4;                                                
+
+       } controlr;
+       u32 K3R;                //104h
+       u32 K2R;                //108h
+       u32 K1R;                //10Ch
+       u32 K0R;                //110h
+
+        u32 IDLEN;             //114h
+
+       u32 ID3R;               //118h
+       u32 ID2R;               //11Ch
+       u32 ID1R;               //120h
+       u32 ID0R;               //124h
+       
+       u32 OD3R;               //128h
+       u32 OD2R;               //12Ch
+       u32 OD1R;               //130h
+       u32 OD0R;               //134h
+};
+
+struct deu_hash_t {
+       struct hash_controlr {
+               u32 reserved1:5;
+               u32 KHS:1;              
+               u32 GO:1;
+               u32 INIT:1;
+               u32 reserved2:6;
+               u32 NDC:1;
+               u32 ENDI:1;
+               u32 reserved3:7;
+               u32 DGRY:1;             
+               u32 BSY:1;
+               u32 reserved4:1;
+               u32 IRCL:1;
+               u32 SM:1;
+               u32 KYUE:1;
+                u32 HMEN:1;
+               u32 SSEN:1;
+               u32 ALGO:1;
+
+       } controlr;
+       u32 MR;                 //B4h
+       u32 D1R;                //B8h
+       u32 D2R;                //BCh
+       u32 D3R;                //C0h
+       u32 D4R;                //C4h
+       u32 D5R;                //C8h
+
+       u32 dummy;              //CCh
+
+       u32 KIDX;               //D0h
+       u32 KEY;                //D4h
+       u32 DBN;                //D8h
+};
+
+
+struct deu_dma_t {
+       struct dma_controlr {
+               u32 reserved1:22;
+               u32 BS:2;
+               u32 BSY:1;
+               u32 reserved2:1;
+               u32 ALGO:2;
+               u32 RXCLS:2;
+               u32 reserved3:1;
+               u32 EN:1;
+
+       } controlr;
+};
+
+#endif /* IFXMIPS_DEU_VR9_H */
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_md5.c b/package/platform/lantiq/ltq-deu/src/ifxmips_md5.c
new file mode 100644 (file)
index 0000000..591389f
--- /dev/null
@@ -0,0 +1,310 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_md5.c
+** PROJECT      : IFX UEIP
+** MODULES      : DEU Module for UEIP
+**
+** DATE         : September 8, 2009
+** AUTHOR       : Mohammad Firdaus
+** DESCRIPTION  : Data Encryption Unit Driver
+** COPYRIGHT    :       Copyright (c) 2009
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author             $Comment
+** 08,Sept 2009 Mohammad Firdaus    Initial UEIP release
+*******************************************************************************/
+/*!
+  \defgroup    IFX_DEU IFX_DEU_DRIVERS
+  \ingroup API
+  \brief ifx deu driver module
+*/
+
+/*!
+  \file                ifxmips_md5.c
+  \ingroup     IFX_DEU
+  \brief       MD5 encryption deu driver file 
+*/
+
+/*!
+  \defgroup IFX_MD5_FUNCTIONS IFX_MD5_FUNCTIONS
+  \ingroup IFX_DEU
+  \brief ifx deu MD5 functions
+*/
+
+/*Project header files */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <linux/types.h>
+#include <crypto/internal/hash.h>
+#include <asm/byteorder.h>
+
+/* Project header */
+#if defined(CONFIG_DANUBE)
+#include "ifxmips_deu_danube.h"
+#elif defined(CONFIG_AR9)
+#include "ifxmips_deu_ar9.h"
+#elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
+#include "ifxmips_deu_vr9.h"
+#else
+#error "Plaform Unknwon!"
+#endif
+
+#define MD5_DIGEST_SIZE     16
+#define MD5_HMAC_BLOCK_SIZE 64
+#define MD5_BLOCK_WORDS     16
+#define MD5_HASH_WORDS      4
+#define HASH_START   IFX_HASH_CON
+
+static spinlock_t lock;
+#define CRTCL_SECT_INIT        spin_lock_init(&lock)
+#define CRTCL_SECT_START       spin_lock_irqsave(&lock, flag)
+#define CRTCL_SECT_END         spin_unlock_irqrestore(&lock, flag)
+
+//#define CRYPTO_DEBUG
+#ifdef CRYPTO_DEBUG
+extern char debug_level;
+#define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
+#else
+#define DPRINTF(level, format, args...)
+#endif
+
+struct md5_ctx {
+    int started;
+    u32 hash[MD5_HASH_WORDS];
+    u32 block[MD5_BLOCK_WORDS];
+    u64 byte_count;
+};
+
+extern int disable_deudma;
+
+/*! \fn static u32 endian_swap(u32 input)
+ *  \ingroup IFX_MD5_FUNCTIONS
+ *  \brief perform dword level endian swap   
+ *  \param input value of dword that requires to be swapped  
+*/ 
+static u32 endian_swap(u32 input)
+{
+    u8 *ptr = (u8 *)&input;
+    
+    return ((ptr[3] << 24) | (ptr[2] << 16) | (ptr[1] << 8) | ptr[0]);     
+}
+
+/*! \fn static void md5_transform(u32 *hash, u32 const *in)
+ *  \ingroup IFX_MD5_FUNCTIONS
+ *  \brief main interface to md5 hardware   
+ *  \param hash current hash value  
+ *  \param in 64-byte block of input  
+*/                                 
+static void md5_transform(struct md5_ctx *mctx, u32 *hash, u32 const *in)
+{
+    int i;
+    volatile struct deu_hash_t *hashs = (struct deu_hash_t *) HASH_START;
+    unsigned long flag;
+
+    CRTCL_SECT_START;
+
+    if (mctx->started) { 
+        hashs->D1R = endian_swap(*((u32 *) hash + 0));
+       hashs->D2R = endian_swap(*((u32 *) hash + 1));
+        hashs->D3R = endian_swap(*((u32 *) hash + 2));
+        hashs->D4R = endian_swap(*((u32 *) hash + 3));
+    }
+
+    for (i = 0; i < 16; i++) {
+        hashs->MR = endian_swap(in[i]);
+//     printk("in[%d]: %08x\n", i, endian_swap(in[i]));
+    };
+
+    //wait for processing
+    while (hashs->controlr.BSY) {
+        // this will not take long
+    }
+
+    *((u32 *) hash + 0) = endian_swap (hashs->D1R);
+    *((u32 *) hash + 1) = endian_swap (hashs->D2R);
+    *((u32 *) hash + 2) = endian_swap (hashs->D3R);
+    *((u32 *) hash + 3) = endian_swap (hashs->D4R);
+
+    mctx->started = 1; 
+
+    CRTCL_SECT_END;
+}
+
+/*! \fn static inline void md5_transform_helper(struct md5_ctx *ctx)
+ *  \ingroup IFX_MD5_FUNCTIONS
+ *  \brief interfacing function for md5_transform()   
+ *  \param ctx crypto context  
+*/                                 
+static inline void md5_transform_helper(struct md5_ctx *ctx)
+{
+    //le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(u32));
+    md5_transform(ctx, ctx->hash, ctx->block);
+}
+
+/*! \fn static void md5_init(struct crypto_tfm *tfm)
+ *  \ingroup IFX_MD5_FUNCTIONS
+ *  \brief initialize md5 hardware   
+ *  \param tfm linux crypto algo transform  
+*/                                 
+static int md5_init(struct shash_desc *desc)
+{
+    struct md5_ctx *mctx = shash_desc_ctx(desc);
+    volatile struct deu_hash_t *hash = (struct deu_hash_t *) HASH_START;
+
+    hash->controlr.ENDI = 0;
+    hash->controlr.SM = 1;
+    hash->controlr.ALGO = 1;    // 1 = md5  0 = sha1
+    hash->controlr.INIT = 1;    // Initialize the hash operation by writing a '1' to the INIT bit.
+
+    mctx->byte_count = 0;
+    mctx->started = 0;
+    return 0;
+}
+
+/*! \fn static void md5_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
+ *  \ingroup IFX_MD5_FUNCTIONS
+ *  \brief on-the-fly md5 computation   
+ *  \param tfm linux crypto algo transform  
+ *  \param data input data  
+ *  \param len size of input data  
+*/                                 
+static int md5_update(struct shash_desc *desc, const u8 *data, unsigned int len)
+{
+    struct md5_ctx *mctx = shash_desc_ctx(desc);
+    const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
+
+    mctx->byte_count += len;
+
+    if (avail > len) {
+        memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
+               data, len);
+        return 0;
+    }
+
+    memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
+           data, avail);
+
+    md5_transform_helper(mctx);
+    data += avail;
+    len -= avail;
+
+    while (len >= sizeof(mctx->block)) {
+        memcpy(mctx->block, data, sizeof(mctx->block));
+        md5_transform_helper(mctx);
+        data += sizeof(mctx->block);
+        len -= sizeof(mctx->block);
+    }
+
+    memcpy(mctx->block, data, len);
+    return 0;
+}
+
+/*! \fn static void md5_final(struct crypto_tfm *tfm, u8 *out)
+ *  \ingroup IFX_MD5_FUNCTIONS
+ *  \brief compute final md5 value   
+ *  \param tfm linux crypto algo transform  
+ *  \param out final md5 output value  
+*/                                 
+static int md5_final(struct shash_desc *desc, u8 *out)
+{
+    struct md5_ctx *mctx = shash_desc_ctx(desc);
+    const unsigned int offset = mctx->byte_count & 0x3f;
+    char *p = (char *)mctx->block + offset;
+    int padding = 56 - (offset + 1);
+    volatile struct deu_hash_t *hashs = (struct deu_hash_t *) HASH_START;
+    unsigned long flag;
+
+    *p++ = 0x80;
+    if (padding < 0) {
+        memset(p, 0x00, padding + sizeof (u64));
+        md5_transform_helper(mctx);
+        p = (char *)mctx->block;
+        padding = 56;
+    }
+
+    memset(p, 0, padding);
+    mctx->block[14] = endian_swap(mctx->byte_count << 3);
+    mctx->block[15] = endian_swap(mctx->byte_count >> 29);
+
+#if 0
+    le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
+                      sizeof(u64)) / sizeof(u32));
+#endif
+
+    md5_transform(mctx, mctx->hash, mctx->block);                                                 
+
+    CRTCL_SECT_START;
+
+    *((u32 *) out + 0) = endian_swap (hashs->D1R);
+    *((u32 *) out + 1) = endian_swap (hashs->D2R);
+    *((u32 *) out + 2) = endian_swap (hashs->D3R);
+    *((u32 *) out + 3) = endian_swap (hashs->D4R);
+
+    CRTCL_SECT_END;
+
+    // Wipe context
+    memset(mctx, 0, sizeof(*mctx));
+
+    return 0;
+}
+
+/*
+ * \brief MD5 function mappings
+*/
+static struct shash_alg ifxdeu_md5_alg = {
+    .digestsize         =       MD5_DIGEST_SIZE,
+    .init               =       md5_init,
+    .update             =       md5_update,
+    .final              =       md5_final,
+    .descsize           =       sizeof(struct md5_ctx),
+    .base               =       {
+                .cra_name       =       "md5",
+                .cra_driver_name=       "ifxdeu-md5",
+                .cra_flags      =       CRYPTO_ALG_TYPE_DIGEST,
+                .cra_blocksize  =       MD5_HMAC_BLOCK_SIZE,
+                .cra_module     =       THIS_MODULE,
+    }
+};
+
+/*! \fn int __init ifxdeu_init_md5 (void)
+ *  \ingroup IFX_MD5_FUNCTIONS
+ *  \brief initialize md5 driver   
+*/                                 
+int __init ifxdeu_init_md5 (void)
+{
+    int ret = -ENOSYS;
+
+
+    if ((ret = crypto_register_shash(&ifxdeu_md5_alg)))
+        goto md5_err;
+
+    CRTCL_SECT_INIT;
+
+    printk (KERN_NOTICE "IFX DEU MD5 initialized%s.\n", disable_deudma ? "" : " (DMA)");
+    return ret;
+
+md5_err:
+    printk(KERN_ERR "IFX DEU MD5 initialization failed!\n");
+    return ret;
+}
+
+/*! \fn void __exit ifxdeu_fini_md5 (void)
+  * \ingroup IFX_MD5_FUNCTIONS
+  * \brief unregister md5 driver   
+*/                  
+               
+void __exit ifxdeu_fini_md5 (void)
+{
+    crypto_unregister_shash(&ifxdeu_md5_alg);
+
+}
+
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_md5_hmac.c b/package/platform/lantiq/ltq-deu/src/ifxmips_md5_hmac.c
new file mode 100644 (file)
index 0000000..fc6f52e
--- /dev/null
@@ -0,0 +1,386 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_md5_hmac.c
+** PROJECT      : IFX UEIP
+** MODULES      : DEU Module for UEIP
+**
+** DATE         : September 8, 2009
+** AUTHOR       : Mohammad Firdaus
+** DESCRIPTION  : Data Encryption Unit Driver
+** COPYRIGHT    :       Copyright (c) 2009
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author             $Comment
+** 08,Sept 2009 Mohammad Firdaus    Initial UEIP release
+** 21,March 2011 Mohammad Firdaus   Changes for Kernel 2.6.32 and IPSec integration
+*******************************************************************************/
+/*!
+  \defgroup IFX_DEU IFX_DEU_DRIVERS
+  \ingroup API
+  \brief  ifx deu driver module
+*/
+
+/*!
+  \file        ifxmips_md5_hmac.c
+  \ingroup IFX_DEU
+  \brief MD5-HMAC encryption deu driver file
+*/
+
+/*!
+ \defgroup IFX_MD5_HMAC_FUNCTIONS IFX_MD5_HMAC_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief ifx md5-hmac driver functions
+*/
+
+/* Project Header files */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <linux/types.h>
+#include <crypto/internal/hash.h>
+#include <asm/byteorder.h>
+
+#if defined(CONFIG_AR9)
+#include "ifxmips_deu_ar9.h"
+#elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
+#include "ifxmips_deu_vr9.h"
+#else
+#error "Plaform Unknwon!"
+#endif
+
+#define MD5_DIGEST_SIZE     16
+#define MD5_HMAC_BLOCK_SIZE 64
+#define MD5_BLOCK_WORDS     16
+#define MD5_HASH_WORDS      4
+#define MD5_HMAC_DBN_TEMP_SIZE  1024 // size in dword, needed for dbn workaround 
+#define HASH_START   IFX_HASH_CON
+
+static spinlock_t lock;
+#define CRTCL_SECT_INIT        spin_lock_init(&lock)
+#define CRTCL_SECT_START       spin_lock_irqsave(&lock, flag)
+#define CRTCL_SECT_END         spin_unlock_irqrestore(&lock, flag)
+
+//#define CRYPTO_DEBUG
+#ifdef CRYPTO_DEBUG
+extern char debug_level;
+#define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
+#else
+#define DPRINTF(level, format, args...)
+#endif
+
+#define MAX_HASH_KEYLEN 64
+
+struct md5_hmac_ctx {
+    u8 key[MAX_HASH_KEYLEN];
+    u32 hash[MD5_HASH_WORDS];
+    u32 block[MD5_BLOCK_WORDS];
+    u64 byte_count;
+    u32 dbn;
+    unsigned int keylen;
+};
+
+static u32 temp[MD5_HMAC_DBN_TEMP_SIZE];
+
+extern int disable_deudma;
+
+/*! \fn static u32 endian_swap(u32 input)
+ *  \ingroup IFX_MD5_HMAC_FUNCTIONS
+ *  \brief perform dword level endian swap   
+ *  \param input value of dword that requires to be swapped  
+*/                                 
+static u32 endian_swap(u32 input)
+{
+    u8 *ptr = (u8 *)&input;
+    
+    return ((ptr[3] << 24) | (ptr[2] << 16) | (ptr[1] << 8) | ptr[0]);     
+}
+
+/*! \fn static void md5_hmac_transform(struct crypto_tfm *tfm, u32 const *in)
+ *  \ingroup IFX_MD5_HMAC_FUNCTIONS
+ *  \brief save input block to context   
+ *  \param tfm linux crypto algo transform  
+ *  \param in 64-byte block of input  
+*/                                 
+static void md5_hmac_transform(struct shash_desc *desc, u32 const *in)
+{
+    struct md5_hmac_ctx *mctx = crypto_shash_ctx(desc->tfm);
+
+    memcpy(&temp[mctx->dbn<<4], in, 64); //dbn workaround
+    mctx->dbn += 1;
+    
+    if ( (mctx->dbn<<4) > MD5_HMAC_DBN_TEMP_SIZE )
+    {
+        printk("MD5_HMAC_DBN_TEMP_SIZE exceeded\n");
+    }
+
+}
+
+/*! \fn int md5_hmac_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
+ *  \ingroup IFX_MD5_HMAC_FUNCTIONS
+ *  \brief sets md5 hmac key   
+ *  \param tfm linux crypto algo transform  
+ *  \param key input key  
+ *  \param keylen key length greater than 64 bytes IS NOT SUPPORTED  
+*/  
+static int md5_hmac_setkey(struct crypto_shash *tfm, const u8 *key, unsigned int keylen) 
+{
+    struct md5_hmac_ctx *mctx = crypto_shash_ctx(tfm);
+    volatile struct deu_hash_t *hash = (struct deu_hash_t *) HASH_START;
+    //printk("copying keys to context with length %d\n", keylen);
+
+    if (keylen > MAX_HASH_KEYLEN) {
+       printk("Key length more than what DEU hash can handle\n");
+       return -EINVAL;
+    }
+
+    hash->KIDX |= 0x80000000; // reset all 16 words of the key to '0'
+    memcpy(&mctx->key, key, keylen);
+    mctx->keylen = keylen;
+
+    return 0;
+
+}
+
+
+/*! \fn int md5_hmac_setkey_hw(const u8 *key, unsigned int keylen)
+ *  \ingroup IFX_MD5_HMAC_FUNCTIONS
+ *  \brief sets md5 hmac key into the hardware registers  
+ *  \param key input key  
+ *  \param keylen key length greater than 64 bytes IS NOT SUPPORTED  
+*/  
+                               
+static int md5_hmac_setkey_hw(const u8 *key, unsigned int keylen)
+{
+    volatile struct deu_hash_t *hash = (struct deu_hash_t *) HASH_START;
+    unsigned long flag;
+    int i, j;
+    u32 *in_key = (u32 *)key;        
+
+    //printk("\nsetkey keylen: %d\n key: ", keylen);
+    
+    CRTCL_SECT_START;
+    j = 0;
+    for (i = 0; i < keylen; i+=4)
+    {
+         hash->KIDX = j;
+         asm("sync");
+         hash->KEY = *((u32 *) in_key + j); 
+         asm("sync");
+         j++;
+    }
+    CRTCL_SECT_END;
+
+    return 0;
+}
+
+/*! \fn void md5_hmac_init(struct crypto_tfm *tfm)
+ *  \ingroup IFX_MD5_HMAC_FUNCTIONS
+ *  \brief initialize md5 hmac context   
+ *  \param tfm linux crypto algo transform  
+*/                                 
+static int md5_hmac_init(struct shash_desc *desc)
+{
+
+    struct md5_hmac_ctx *mctx = crypto_shash_ctx(desc->tfm);
+    
+
+    mctx->dbn = 0; //dbn workaround
+    md5_hmac_setkey_hw(mctx->key, mctx->keylen);
+
+    return 0;
+}
+EXPORT_SYMBOL(md5_hmac_init);
+    
+/*! \fn void md5_hmac_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
+ *  \ingroup IFX_MD5_HMAC_FUNCTIONS
+ *  \brief on-the-fly md5 hmac computation   
+ *  \param tfm linux crypto algo transform  
+ *  \param data input data  
+ *  \param len size of input data  
+*/                                 
+static int md5_hmac_update(struct shash_desc *desc, const u8 *data, unsigned int len)
+{
+    struct md5_hmac_ctx *mctx = crypto_shash_ctx(desc->tfm);
+    const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
+
+    mctx->byte_count += len;
+    
+    if (avail > len) {
+        memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
+               data, len);
+        return 0;
+    }
+
+    memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
+           data, avail);
+
+    md5_hmac_transform(desc, mctx->block);
+    data += avail;
+    len -= avail;
+
+    while (len >= sizeof(mctx->block)) {
+        memcpy(mctx->block, data, sizeof(mctx->block));
+        md5_hmac_transform(desc, mctx->block);
+        data += sizeof(mctx->block);
+        len -= sizeof(mctx->block);
+    }
+
+    memcpy(mctx->block, data, len);
+    return 0;    
+}
+EXPORT_SYMBOL(md5_hmac_update);
+
+/*! \fn void md5_hmac_final(struct crypto_tfm *tfm, u8 *out)
+ *  \ingroup IFX_MD5_HMAC_FUNCTIONS
+ *  \brief compute final md5 hmac value   
+ *  \param tfm linux crypto algo transform  
+ *  \param out final md5 hmac output value  
+*/                                 
+static int md5_hmac_final(struct shash_desc *desc, u8 *out)
+{
+    struct md5_hmac_ctx *mctx = crypto_shash_ctx(desc->tfm);
+    const unsigned int offset = mctx->byte_count & 0x3f;
+    char *p = (char *)mctx->block + offset;
+    int padding = 56 - (offset + 1);
+    volatile struct deu_hash_t *hashs = (struct deu_hash_t *) HASH_START;
+    unsigned long flag;
+    int i = 0;
+    int dbn;
+    u32 *in = &temp[0];
+
+
+    *p++ = 0x80;
+    if (padding < 0) {
+        memset(p, 0x00, padding + sizeof (u64));
+        md5_hmac_transform(desc, mctx->block);
+        p = (char *)mctx->block;
+        padding = 56;
+    }
+
+    memset(p, 0, padding);
+    mctx->block[14] = endian_swap((mctx->byte_count + 64) << 3); // need to add 512 bit of the IPAD operation 
+    mctx->block[15] = 0x00000000;
+
+    md5_hmac_transform(desc, mctx->block);
+
+    CRTCL_SECT_START;
+
+    //printk("\ndbn = %d\n", mctx->dbn); 
+    hashs->DBN = mctx->dbn;
+    asm("sync");
+    
+    *IFX_HASH_CON = 0x0703002D; //khs, go, init, ndc, endi, kyue, hmen, md5    
+
+    //wait for processing
+    while (hashs->controlr.BSY) {
+        // this will not take long
+    }
+
+    for (dbn = 0; dbn < mctx->dbn; dbn++)
+    {
+        for (i = 0; i < 16; i++) {
+            hashs->MR = in[i];
+        };
+
+        hashs->controlr.GO = 1;
+        asm("sync");
+
+        //wait for processing
+        while (hashs->controlr.BSY) {
+           // this will not take long
+        }
+    
+        in += 16;
+}
+
+
+#if 1
+    //wait for digest ready
+    while (! hashs->controlr.DGRY) {
+        // this will not take long
+    }
+#endif
+
+    *((u32 *) out + 0) = hashs->D1R;
+    *((u32 *) out + 1) = hashs->D2R;
+    *((u32 *) out + 2) = hashs->D3R;
+    *((u32 *) out + 3) = hashs->D4R;
+    *((u32 *) out + 4) = hashs->D5R;
+
+    /* reset the context after we finish with the hash */
+    mctx->byte_count = 0;
+    memset(&mctx->hash[0], 0, sizeof(MD5_HASH_WORDS));
+    memset(&mctx->block[0], 0, sizeof(MD5_BLOCK_WORDS));
+    memset(&temp[0], 0, MD5_HMAC_DBN_TEMP_SIZE);
+
+    CRTCL_SECT_END;
+
+
+   return 0;
+}
+
+EXPORT_SYMBOL(md5_hmac_final);
+
+/* 
+ * \brief MD5_HMAC function mappings
+*/
+
+static struct shash_alg ifxdeu_md5_hmac_alg = {
+    .digestsize         =       MD5_DIGEST_SIZE,
+    .init               =       md5_hmac_init,
+    .update             =       md5_hmac_update,
+    .final              =       md5_hmac_final,
+    .setkey             =       md5_hmac_setkey,
+    .descsize           =       sizeof(struct md5_hmac_ctx),
+    .base               =       {
+        .cra_name       =       "hmac(md5)",
+        .cra_driver_name=       "ifxdeu-md5_hmac",
+        .cra_ctxsize    =      sizeof(struct md5_hmac_ctx),
+        .cra_flags      =       CRYPTO_ALG_TYPE_DIGEST,
+        .cra_blocksize  =       MD5_HMAC_BLOCK_SIZE,
+        .cra_module     =       THIS_MODULE,
+        }
+};
+
+/*! \fn int __init ifxdeu_init_md5_hmac (void)
+ *  \ingroup IFX_MD5_HMAC_FUNCTIONS
+ *  \brief initialize md5 hmac driver   
+*/                                 
+int __init ifxdeu_init_md5_hmac (void)
+{
+
+    int ret = -ENOSYS;
+
+
+    if ((ret = crypto_register_shash(&ifxdeu_md5_hmac_alg)))
+        goto md5_hmac_err;
+
+    CRTCL_SECT_INIT;
+
+    printk (KERN_NOTICE "IFX DEU MD5_HMAC initialized%s.\n", disable_deudma ? "" : " (DMA)");
+    return ret;
+
+md5_hmac_err:
+    printk(KERN_ERR "IFX DEU MD5_HMAC initialization failed!\n");
+    return ret;
+}
+
+/** \fn void __exit ifxdeu_fini_md5_hmac (void)
+ *  \ingroup IFX_MD5_HMAC_FUNCTIONS
+ *  \brief unregister md5 hmac driver   
+*/                                 
+void __exit ifxdeu_fini_md5_hmac (void)
+{
+    crypto_unregister_shash(&ifxdeu_md5_hmac_alg);
+}
+
+
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_sha1.c b/package/platform/lantiq/ltq-deu/src/ifxmips_sha1.c
new file mode 100644 (file)
index 0000000..a5f5f90
--- /dev/null
@@ -0,0 +1,301 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_sha1.c
+** PROJECT      : IFX UEIP
+** MODULES      : DEU Module for Danube
+**
+** DATE         : September 8, 2009
+** AUTHOR       : Mohammad Firdaus
+** DESCRIPTION  : Data Encryption Unit Driver
+** COPYRIGHT    :       Copyright (c) 2009
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author             $Comment
+** 08,Sept 2009 Mohammad Firdaus    Initial UEIP release
+*******************************************************************************/
+/*!
+  \defgroup IFX_DEU IFX_DEU_DRIVERS
+  \ingroup API
+  \brief ifx deu driver module
+*/
+
+/*!
+  \file        ifxmips_sha1.c
+  \ingroup IFX_DEU
+  \brief SHA1 encryption deu driver file
+*/
+
+/*!
+  \defgroup IFX_SHA1_FUNCTIONS IFX_SHA1_FUNCTIONS
+  \ingroup IFX_DEU
+  \brief ifx deu sha1 functions
+*/
+
+
+/* Project header */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/crypto.h>
+#include <linux/cryptohash.h>
+#include <crypto/sha.h>
+#include <crypto/internal/hash.h>
+#include <linux/types.h>
+#include <asm/scatterlist.h>
+#include <asm/byteorder.h>
+
+#if defined(CONFIG_DANUBE)
+#include "ifxmips_deu_danube.h"
+#elif defined(CONFIG_AR9)
+#include "ifxmips_deu_ar9.h"
+#elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
+#include "ifxmips_deu_vr9.h"
+#else
+#error "Plaform Unknwon!"
+#endif
+
+#define SHA1_DIGEST_SIZE    20
+#define SHA1_HMAC_BLOCK_SIZE    64
+#define HASH_START   IFX_HASH_CON
+
+static spinlock_t lock;
+#define CRTCL_SECT_INIT        spin_lock_init(&lock)
+#define CRTCL_SECT_START       spin_lock_irqsave(&lock, flag)
+#define CRTCL_SECT_END         spin_unlock_irqrestore(&lock, flag)
+
+//#define CRYPTO_DEBUG
+#ifdef CRYPTO_DEBUG
+extern char debug_level;
+#define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
+#else
+#define DPRINTF(level, format, args...)
+#endif
+
+/*
+ * \brief SHA1 private structure
+*/
+struct sha1_ctx {
+       int started;
+        u64 count;
+       u32 hash[5];
+        u32 state[5];
+        u8 buffer[64];
+};
+
+extern int disable_deudma;
+
+
+/*! \fn static void sha1_transform (u32 *state, const u32 *in)
+ *  \ingroup IFX_SHA1_FUNCTIONS
+ *  \brief main interface to sha1 hardware   
+ *  \param state current state 
+ *  \param in 64-byte block of input  
+*/                                 
+static void sha1_transform (struct sha1_ctx *sctx, u32 *state, const u32 *in)
+{
+    int i = 0;
+    volatile struct deu_hash_t *hashs = (struct deu_hash_t *) HASH_START;
+    unsigned long flag;
+
+    CRTCL_SECT_START;
+
+    /* For context switching purposes, the previous hash output
+     * is loaded back into the output register 
+    */
+    if (sctx->started) {
+        hashs->D1R = *((u32 *) sctx->hash + 0);
+        hashs->D2R = *((u32 *) sctx->hash + 1);
+        hashs->D3R = *((u32 *) sctx->hash + 2);
+        hashs->D4R = *((u32 *) sctx->hash + 3);
+        hashs->D5R = *((u32 *) sctx->hash + 4);
+    }
+
+    for (i = 0; i < 16; i++) {
+        hashs->MR = in[i];
+    };
+
+    //wait for processing
+    while (hashs->controlr.BSY) {
+        // this will not take long
+    }
+   
+    /* For context switching purposes, the output is saved into a 
+     * context struct which can be used later on 
+    */
+    *((u32 *) sctx->hash + 0) = hashs->D1R;
+    *((u32 *) sctx->hash + 1) = hashs->D2R;
+    *((u32 *) sctx->hash + 2) = hashs->D3R;
+    *((u32 *) sctx->hash + 3) = hashs->D4R;
+    *((u32 *) sctx->hash + 4) = hashs->D5R;
+
+    sctx->started = 1;
+
+    CRTCL_SECT_END;
+}
+
+/*! \fn static void sha1_init(struct crypto_tfm *tfm)
+ *  \ingroup IFX_SHA1_FUNCTIONS
+ *  \brief initialize sha1 hardware   
+ *  \param tfm linux crypto algo transform  
+*/                                 
+static int sha1_init(struct shash_desc *desc)
+{
+    struct sha1_ctx *sctx = shash_desc_ctx(desc);
+    
+    SHA_HASH_INIT;
+
+    sctx->started = 0;
+    sctx->count = 0;
+    return 0;
+}
+
+/*! \fn static void sha1_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
+ *  \ingroup IFX_SHA1_FUNCTIONS
+ *  \brief on-the-fly sha1 computation   
+ *  \param tfm linux crypto algo transform  
+ *  \param data input data  
+ *  \param len size of input data  
+*/                                 
+static int sha1_update(struct shash_desc * desc, const u8 *data,
+            unsigned int len)
+{
+    struct sha1_ctx *sctx = shash_desc_ctx(desc);
+    unsigned int i, j;
+
+    j = (sctx->count >> 3) & 0x3f;
+    sctx->count += len << 3;
+
+    if ((j + len) > 63) {
+        memcpy (&sctx->buffer[j], data, (i = 64 - j));
+        sha1_transform (sctx, sctx->state, (const u32 *)sctx->buffer);
+        for (; i + 63 < len; i += 64) {
+            sha1_transform (sctx, sctx->state, (const u32 *)&data[i]);
+        }
+
+        j = 0;
+    }
+    else
+        i = 0;
+
+    memcpy (&sctx->buffer[j], &data[i], len - i);
+    return 0;
+}
+
+/*! \fn static void sha1_final(struct crypto_tfm *tfm, u8 *out)
+ *  \ingroup IFX_SHA1_FUNCTIONS
+ *  \brief compute final sha1 value   
+ *  \param tfm linux crypto algo transform  
+ *  \param out final md5 output value  
+*/                                 
+static int sha1_final(struct shash_desc *desc, u8 *out)
+{
+    struct sha1_ctx *sctx = shash_desc_ctx(desc);
+    u32 index, padlen;
+    u64 t;
+    u8 bits[8] = { 0, };
+    static const u8 padding[64] = { 0x80, };
+    volatile struct deu_hash_t *hashs = (struct deu_hash_t *) HASH_START;
+    unsigned long flag;
+
+    t = sctx->count;
+    bits[7] = 0xff & t;
+    t >>= 8;
+    bits[6] = 0xff & t;
+    t >>= 8;
+    bits[5] = 0xff & t;
+    t >>= 8;
+    bits[4] = 0xff & t;
+    t >>= 8;
+    bits[3] = 0xff & t;
+    t >>= 8;
+    bits[2] = 0xff & t;
+    t >>= 8;
+    bits[1] = 0xff & t;
+    t >>= 8;
+    bits[0] = 0xff & t;
+
+    /* Pad out to 56 mod 64 */
+    index = (sctx->count >> 3) & 0x3f;
+    padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
+    sha1_update (desc, padding, padlen);
+
+    /* Append length */
+    sha1_update (desc, bits, sizeof bits);
+
+    CRTCL_SECT_START;
+
+    *((u32 *) out + 0) = hashs->D1R;
+    *((u32 *) out + 1) = hashs->D2R;
+    *((u32 *) out + 2) = hashs->D3R;
+    *((u32 *) out + 3) = hashs->D4R;
+    *((u32 *) out + 4) = hashs->D5R;
+
+    CRTCL_SECT_END;
+
+    // Wipe context
+    memset (sctx, 0, sizeof *sctx);
+
+    return 0;
+}
+
+/* 
+ * \brief SHA1 function mappings
+*/
+static struct shash_alg ifxdeu_sha1_alg = {
+        .digestsize     =       SHA1_DIGEST_SIZE,
+        .init           =       sha1_init,
+        .update         =       sha1_update,
+        .final          =       sha1_final,
+        .descsize       =       sizeof(struct sha1_ctx),
+        .statesize      =       sizeof(struct sha1_state),
+        .base           =       {
+                .cra_name       =       "sha1",
+                .cra_driver_name=       "ifxdeu-sha1",
+                .cra_flags      =       CRYPTO_ALG_TYPE_DIGEST,
+                .cra_blocksize  =       SHA1_HMAC_BLOCK_SIZE,
+                .cra_module     =       THIS_MODULE,
+        }
+};
+
+
+/*! \fn int __init ifxdeu_init_sha1 (void)
+ *  \ingroup IFX_SHA1_FUNCTIONS
+ *  \brief initialize sha1 driver    
+*/                                 
+int __init ifxdeu_init_sha1 (void)
+{
+    int ret = -ENOSYS;
+
+
+    if ((ret = crypto_register_shash(&ifxdeu_sha1_alg)))
+        goto sha1_err;
+
+    CRTCL_SECT_INIT;
+
+    printk (KERN_NOTICE "IFX DEU SHA1 initialized%s.\n", disable_deudma ? "" : " (DMA)");
+    return ret;
+
+sha1_err:
+    printk(KERN_ERR "IFX DEU SHA1 initialization failed!\n");
+    return ret;
+}
+
+/*! \fn void __exit ifxdeu_fini_sha1 (void)
+ *  \ingroup IFX_SHA1_FUNCTIONS
+ *  \brief unregister sha1 driver   
+*/                                 
+void __exit ifxdeu_fini_sha1 (void)
+{
+    crypto_unregister_shash(&ifxdeu_sha1_alg);
+
+
+}
+
+
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_sha1_hmac.c b/package/platform/lantiq/ltq-deu/src/ifxmips_sha1_hmac.c
new file mode 100644 (file)
index 0000000..a5a6c39
--- /dev/null
@@ -0,0 +1,378 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_sha1_hmac.c
+** PROJECT      : IFX UEIP
+** MODULES      : DEU Module for UEIP
+** DATE         : September 8, 2009
+** AUTHOR       : Mohammad Firdaus
+** DESCRIPTION  : Data Encryption Unit Driver
+** COPYRIGHT    :       Copyright (c) 2009
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author             $Comment
+** 08,Sept 2009 Mohammad Firdaus    Initial UEIP release
+** 21,March 2011 Mohammad Firdaus   Changes for Kernel 2.6.32 and IPSec integration
+*******************************************************************************/
+/*!
+  \defgroup IFX_DEU IFX_DEU_DRIVERS
+  \ingroup API
+  \brief ifx deu driver module
+*/
+
+/*!
+  \file        ifxmips_sha1_hmac.c
+  \ingroup IFX_DEU
+  \brief SHA1-HMAC deu driver file
+*/
+
+/*! 
+  \defgroup IFX_SHA1_HMAC_FUNCTIONS IFX_SHA1_HMAC_FUNCTIONS
+  \ingroup IFX_DEU
+  \brief ifx sha1 hmac functions
+*/
+
+
+/* Project header */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/crypto.h>
+#include <linux/cryptohash.h>
+#include <crypto/internal/hash.h>
+#include <linux/types.h>
+#include <asm/scatterlist.h>
+#include <asm/byteorder.h>
+#include <linux/delay.h>
+
+#if defined(CONFIG_AR9)
+#include "ifxmips_deu_ar9.h"
+#elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
+#include "ifxmips_deu_vr9.h"
+#else
+#error "Plaform Unknwon!"
+#endif
+
+#define SHA1_DIGEST_SIZE    20
+#define SHA1_HMAC_BLOCK_SIZE    64
+#define SHA1_HMAC_DBN_TEMP_SIZE 1024 // size in dword, needed for dbn workaround 
+#define HASH_START   IFX_HASH_CON
+
+#define SHA1_HMAC_MAX_KEYLEN 64
+
+static spinlock_t lock;
+#define CRTCL_SECT_INIT        spin_lock_init(&lock)
+#define CRTCL_SECT_START       spin_lock_irqsave(&lock, flag)
+#define CRTCL_SECT_END         spin_unlock_irqrestore(&lock, flag)
+
+#ifdef CRYPTO_DEBUG
+extern char debug_level;
+#define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
+#else
+#define DPRINTF(level, format, args...)
+#endif
+
+struct sha1_hmac_ctx {
+    int keylen;
+
+    u8 buffer[SHA1_HMAC_BLOCK_SIZE];
+    u8 key[SHA1_HMAC_MAX_KEYLEN];
+    u32 state[5];
+    u32 dbn;
+    u64 count;
+
+};
+
+static u32 temp[SHA1_HMAC_DBN_TEMP_SIZE];  
+
+extern int disable_deudma;
+
+/*! \fn static void sha1_hmac_transform(struct crypto_tfm *tfm, u32 const *in)
+ *  \ingroup IFX_SHA1_HMAC_FUNCTIONS
+ *  \brief save input block to context   
+ *  \param tfm linux crypto algo transform  
+ *  \param in 64-byte block of input  
+*/                                 
+static int sha1_hmac_transform(struct shash_desc *desc, u32 const *in)
+{
+    struct sha1_hmac_ctx *sctx =  crypto_shash_ctx(desc->tfm);
+
+    memcpy(&temp[sctx->dbn<<4], in, 64); //dbn workaround
+    sctx->dbn += 1;
+    
+    if ( (sctx->dbn<<4) > SHA1_HMAC_DBN_TEMP_SIZE )
+    {
+        printk("SHA1_HMAC_DBN_TEMP_SIZE exceeded\n");
+    }
+   
+    return 0;
+}
+
+/*! \fn int sha1_hmac_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
+ *  \ingroup IFX_SHA1_HMAC_FUNCTIONS
+ *  \brief sets sha1 hmac key   
+ *  \param tfm linux crypto algo transform  
+ *  \param key input key  
+ *  \param keylen key length greater than 64 bytes IS NOT SUPPORTED  
+*/                                 
+static int sha1_hmac_setkey(struct crypto_shash *tfm, const u8 *key, unsigned int keylen)
+{
+    struct sha1_hmac_ctx *sctx = crypto_shash_ctx(tfm);
+    volatile struct deu_hash_t *hashs = (struct deu_hash_t *) HASH_START;
+    
+    if (keylen > SHA1_HMAC_MAX_KEYLEN) {
+       printk("Key length exceeds maximum key length\n");
+       return -EINVAL;
+    }
+
+    //printk("Setting keys of len: %d\n", keylen);
+     
+    hashs->KIDX |= 0x80000000; //reset keys back to 0
+    memcpy(&sctx->key, key, keylen);
+    sctx->keylen = keylen;
+
+    return 0;
+         
+}
+
+
+/*! \fn int sha1_hmac_setkey_hw(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
+ *  \ingroup IFX_SHA1_HMAC_FUNCTIONS
+ *  \brief sets sha1 hmac key  into hw registers 
+ *  \param tfm linux crypto algo transform  
+ *  \param key input key  
+ *  \param keylen key length greater than 64 bytes IS NOT SUPPORTED  
+*/                                 
+static int sha1_hmac_setkey_hw(const u8 *key, unsigned int keylen)
+{
+    volatile struct deu_hash_t *hash = (struct deu_hash_t *) HASH_START;
+    int i, j;
+    unsigned long flag;
+    u32 *in_key = (u32 *)key;        
+
+    j = 0;
+
+    CRTCL_SECT_START;
+    for (i = 0; i < keylen; i+=4)
+    {
+         hash->KIDX = j;
+         asm("sync");
+         hash->KEY = *((u32 *) in_key + j); 
+         j++;
+    }
+
+    CRTCL_SECT_END;
+    return 0;
+}
+
+/*! \fn void sha1_hmac_init(struct crypto_tfm *tfm)
+ *  \ingroup IFX_SHA1_HMAC_FUNCTIONS
+ *  \brief initialize sha1 hmac context   
+ *  \param tfm linux crypto algo transform  
+*/                                 
+static int sha1_hmac_init(struct shash_desc *desc)
+{
+    struct sha1_hmac_ctx *sctx =  crypto_shash_ctx(desc->tfm);
+
+    //printk("debug ln: %d, fn: %s\n", __LINE__, __func__);
+    sctx->dbn = 0; //dbn workaround
+    sha1_hmac_setkey_hw(sctx->key, sctx->keylen);
+
+    return 0;
+}
+
+/*! \fn static void sha1_hmac_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
+ *  \ingroup IFX_SHA1_HMAC_FUNCTIONS
+ *  \brief on-the-fly sha1 hmac computation   
+ *  \param tfm linux crypto algo transform  
+ *  \param data input data  
+ *  \param len size of input data 
+*/                                 
+static int sha1_hmac_update(struct shash_desc *desc, const u8 *data,
+            unsigned int len)
+{
+    struct sha1_hmac_ctx *sctx =  crypto_shash_ctx(desc->tfm);
+    unsigned int i, j;
+
+    j = (sctx->count >> 3) & 0x3f;
+    sctx->count += len << 3;
+   // printk("sctx->count = %d\n", sctx->count);
+
+    if ((j + len) > 63) {
+        memcpy (&sctx->buffer[j], data, (i = 64 - j));
+        sha1_hmac_transform (desc, (const u32 *)sctx->buffer);
+        for (; i + 63 < len; i += 64) {
+            sha1_hmac_transform (desc, (const u32 *)&data[i]);
+        }
+
+        j = 0;
+    }
+    else
+        i = 0;
+
+    memcpy (&sctx->buffer[j], &data[i], len - i);
+    return 0;
+}
+
+/*! \fn static void sha1_hmac_final(struct crypto_tfm *tfm, u8 *out)
+ *  \ingroup IFX_SHA1_HMAC_FUNCTIONS
+ *  \brief ompute final sha1 hmac value   
+ *  \param tfm linux crypto algo transform  
+ *  \param out final sha1 hmac output value  
+*/                                 
+static int sha1_hmac_final(struct shash_desc *desc, u8 *out)
+{
+    //struct sha1_hmac_ctx *sctx = shash_desc_ctx(desc);
+    struct sha1_hmac_ctx *sctx =  crypto_shash_ctx(desc->tfm);
+    u32 index, padlen;
+    u64 t;
+    u8 bits[8] = { 0, };
+    static const u8 padding[64] = { 0x80, };
+    volatile struct deu_hash_t *hashs = (struct deu_hash_t *) HASH_START;
+    unsigned long flag;
+    int i = 0;
+    int dbn;
+    u32 *in = &temp[0];
+        
+    t = sctx->count + 512; // need to add 512 bit of the IPAD operation
+    bits[7] = 0xff & t;
+    t >>= 8;
+    bits[6] = 0xff & t;
+    t >>= 8;
+    bits[5] = 0xff & t;
+    t >>= 8;
+    bits[4] = 0xff & t;
+    t >>= 8;
+    bits[3] = 0xff & t;
+    t >>= 8;
+    bits[2] = 0xff & t;
+    t >>= 8;
+    bits[1] = 0xff & t;
+    t >>= 8;
+    bits[0] = 0xff & t;
+
+    /* Pad out to 56 mod 64 */
+    index = (sctx->count >> 3) & 0x3f;
+    padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
+    sha1_hmac_update (desc, padding, padlen);
+
+    /* Append length */
+    sha1_hmac_update (desc, bits, sizeof bits);
+
+    CRTCL_SECT_START;
+    
+    hashs->DBN = sctx->dbn;
+    
+    //for vr9 change, ENDI = 1
+    *IFX_HASH_CON = HASH_CON_VALUE; 
+
+    //wait for processing
+    while (hashs->controlr.BSY) {
+        // this will not take long
+    }
+
+    for (dbn = 0; dbn < sctx->dbn; dbn++)
+    {
+    for (i = 0; i < 16; i++) {
+        hashs->MR = in[i];
+    };
+
+    hashs->controlr.GO = 1;
+    asm("sync");
+
+    //wait for processing
+    while (hashs->controlr.BSY) {
+            // this will not take long
+    }
+    
+    in += 16;
+}
+
+
+#if 1
+    //wait for digest ready
+    while (! hashs->controlr.DGRY) {
+        // this will not take long
+    }
+#endif
+
+    *((u32 *) out + 0) = hashs->D1R;
+    *((u32 *) out + 1) = hashs->D2R;
+    *((u32 *) out + 2) = hashs->D3R;
+    *((u32 *) out + 3) = hashs->D4R;
+    *((u32 *) out + 4) = hashs->D5R;
+
+    memset(&sctx->buffer[0], 0, SHA1_HMAC_BLOCK_SIZE);
+    sctx->count = 0; 
+    //printk("debug ln: %d, fn: %s\n", __LINE__, __func__);
+    CRTCL_SECT_END;
+
+
+    return 0;
+
+}
+
+/*
+ * \brief SHA1-HMAC function mappings
+*/
+static struct shash_alg ifxdeu_sha1_hmac_alg = {
+        .digestsize     =       SHA1_DIGEST_SIZE,
+        .init           =       sha1_hmac_init,
+        .update         =       sha1_hmac_update,
+        .final          =       sha1_hmac_final,
+        .setkey         =       sha1_hmac_setkey,
+        .descsize       =       sizeof(struct sha1_hmac_ctx),
+        .base           =       {
+                .cra_name       =       "hmac(sha1)",
+                .cra_driver_name=       "ifxdeu-sha1_hmac",
+               .cra_ctxsize    =       sizeof(struct sha1_hmac_ctx),
+                .cra_flags      =       CRYPTO_ALG_TYPE_DIGEST,
+                .cra_blocksize  =       SHA1_HMAC_BLOCK_SIZE,
+                .cra_module     =       THIS_MODULE,
+        }
+
+};
+
+
+/*! \fn int __init ifxdeu_init_sha1_hmac (void)
+ *  \ingroup IFX_SHA1_HMAC_FUNCTIONS
+ *  \brief initialize sha1 hmac driver    
+*/                                 
+int __init ifxdeu_init_sha1_hmac (void)
+{
+    int ret = -ENOSYS;
+
+
+
+    if ((ret = crypto_register_shash(&ifxdeu_sha1_hmac_alg)))
+        goto sha1_err;
+
+    CRTCL_SECT_INIT;
+
+    printk (KERN_NOTICE "IFX DEU SHA1_HMAC initialized%s.\n", disable_deudma ? "" : " (DMA)");
+    return ret;
+
+sha1_err:
+    printk(KERN_ERR "IFX DEU SHA1_HMAC initialization failed!\n");
+    return ret;
+}
+
+/*! \fn void __exit ifxdeu_fini_sha1_hmac (void)
+ *  \ingroup IFX_SHA1_HMAC_FUNCTIONS
+ *  \brief unregister sha1 hmac driver    
+*/                                 
+void __exit ifxdeu_fini_sha1_hmac (void)
+{
+
+    crypto_unregister_shash(&ifxdeu_sha1_hmac_alg);
+
+
+}
+
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_tcrypt.h b/package/platform/lantiq/ltq-deu/src/ifxmips_tcrypt.h
new file mode 100644 (file)
index 0000000..1e7047b
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Quick & dirty crypto testing module.
+ *
+ * This will only exist until we have a better testing mechanism
+ * (e.g. a char device).
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
+ * Copyright (c) 2007 Nokia Siemens Networks
+ *
+ * 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.
+ *
+ */
+#ifndef _IFXMIPS_CRYPTO_TCRYPT_H
+#define _IFXMIPS_CRYPTO_TCRYPT_H
+
+struct cipher_speed_template {
+       const char *key;
+       unsigned int klen;
+};
+
+struct hash_speed {
+       unsigned int blen;      /* buffer length */
+       unsigned int plen;      /* per-update length */
+};
+
+/*
+ * DES test vectors.
+ */
+#define DES3_SPEED_VECTORS     1
+#define CRYPTO_ALG_TYPE_SPEED_TEST 0xB
+
+static int alg_speed_test(const char *alg, const char *driver,
+                         unsigned int sec,
+                         struct cipher_speed_template *t,
+                         unsigned int tcount, u8 *keysize);
+
+static struct cipher_speed_template des3_speed_template[] = {
+       {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\x55\x55\x55\x55\x55\x55\x55\x55"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .klen   = 24,
+       }
+};
+
+/*
+ * Cipher speed tests
+ */
+static u8 speed_template_8[] = {8, 0};
+static u8 speed_template_24[] = {24, 0};
+static u8 speed_template_8_32[] = {8, 32, 0};
+static u8 speed_template_16_32[] = {16, 32, 0};
+static u8 speed_template_16_24_32[] = {16, 24, 32, 0};
+static u8 speed_template_32_40_48[] = {32, 40, 48, 0};
+static u8 speed_template_32_48_64[] = {32, 48, 64, 0};
+
+/*
+ * Digest speed tests
+ */
+static struct hash_speed generic_hash_speed_template[] = {
+       { .blen = 16,   .plen = 16, },
+       { .blen = 64,   .plen = 16, },
+       { .blen = 64,   .plen = 64, },
+       { .blen = 256,  .plen = 16, },
+       { .blen = 256,  .plen = 64, },
+       { .blen = 256,  .plen = 256, },
+       { .blen = 1024, .plen = 16, },
+       { .blen = 1024, .plen = 256, },
+       { .blen = 1024, .plen = 1024, },
+       { .blen = 2048, .plen = 16, },
+       { .blen = 2048, .plen = 256, },
+       { .blen = 2048, .plen = 1024, },
+       { .blen = 2048, .plen = 2048, },
+       { .blen = 4096, .plen = 16, },
+       { .blen = 4096, .plen = 256, },
+       { .blen = 4096, .plen = 1024, },
+       { .blen = 4096, .plen = 4096, },
+       { .blen = 8192, .plen = 16, },
+       { .blen = 8192, .plen = 256, },
+       { .blen = 8192, .plen = 1024, },
+       { .blen = 8192, .plen = 4096, },
+       { .blen = 8192, .plen = 8192, },
+
+       /* End marker */
+       {  .blen = 0,   .plen = 0, }
+};
+
+#endif /* _CRYPTO_TCRYPT_H */
diff --git a/package/platform/lantiq/ltq-deu/src/ifxmips_testmgr.h b/package/platform/lantiq/ltq-deu/src/ifxmips_testmgr.h
new file mode 100644 (file)
index 0000000..27fe9a9
--- /dev/null
@@ -0,0 +1,9598 @@
+/*
+ * Algorithm testing framework and tests.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
+ * Copyright (c) 2007 Nokia Siemens Networks
+ * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
+ *
+ * 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.
+ *
+ */
+#ifndef _IFXMIPS_CRYPTO_TESTMGR_H
+#define _IFXMIPS_CRYPTO_TESTMGR_H
+
+#include <linux/netlink.h>
+#include <linux/zlib.h>
+
+#include <crypto/compress.h>
+
+#define MAX_DIGEST_SIZE                64
+#define MAX_TAP                        8
+
+#define MAX_KEYLEN             56
+#define MAX_IVLEN              32
+
+struct hash_testvec {
+       /* only used with keyed hash algorithms */
+       char *key;
+       char *plaintext;
+       char *digest;
+       unsigned char tap[MAX_TAP];
+       unsigned char psize;
+       unsigned char np;
+       unsigned char ksize;
+};
+
+struct cipher_testvec {
+       char *key;
+       char *iv;
+       char *input;
+       char *result;
+       unsigned short tap[MAX_TAP];
+       int np;
+       unsigned char fail;
+       unsigned char wk; /* weak key flag */
+       unsigned char klen;
+       unsigned short ilen;
+       unsigned short rlen;
+};
+
+struct aead_testvec {
+       char *key;
+       char *iv;
+       char *input;
+       char *assoc;
+       char *result;
+       unsigned char tap[MAX_TAP];
+       unsigned char atap[MAX_TAP];
+       int np;
+       int anp;
+       unsigned char fail;
+       unsigned char novrfy;   /* ccm dec verification failure expected */
+       unsigned char wk; /* weak key flag */
+       unsigned char klen;
+       unsigned short ilen;
+       unsigned short alen;
+       unsigned short rlen;
+};
+
+struct cprng_testvec {
+       char *key;
+       char *dt;
+       char *v;
+       char *result;
+       unsigned char klen;
+       unsigned short dtlen;
+       unsigned short vlen;
+       unsigned short rlen;
+       unsigned short loops;
+};
+
+static char zeroed_string[48];
+
+/*
+ * MD4 test vectors from RFC1320
+ */
+#define MD4_TEST_VECTORS       7
+
+static struct hash_testvec md4_tv_template [] = {
+       {
+               .plaintext = "",
+               .digest = "\x31\xd6\xcf\xe0\xd1\x6a\xe9\x31"
+                         "\xb7\x3c\x59\xd7\xe0\xc0\x89\xc0",
+       }, {
+               .plaintext = "a",
+               .psize  = 1,
+               .digest = "\xbd\xe5\x2c\xb3\x1d\xe3\x3e\x46"
+                         "\x24\x5e\x05\xfb\xdb\xd6\xfb\x24",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xa4\x48\x01\x7a\xaf\x21\xd8\x52"
+                         "\x5f\xc1\x0a\xe8\x7a\xa6\x72\x9d",
+       }, {
+               .plaintext = "message digest",
+               .psize  = 14,
+               .digest = "\xd9\x13\x0a\x81\x64\x54\x9f\xe8"
+                       "\x18\x87\x48\x06\xe1\xc7\x01\x4b",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyz",
+               .psize  = 26,
+               .digest = "\xd7\x9e\x1c\x30\x8a\xa5\xbb\xcd"
+                         "\xee\xa8\xed\x63\xdf\x41\x2d\xa9",
+               .np     = 2,
+               .tap    = { 13, 13 },
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+               .psize  = 62,
+               .digest = "\x04\x3f\x85\x82\xf2\x41\xdb\x35"
+                         "\x1c\xe6\x27\xe1\x53\xe7\xf0\xe4",
+       }, {
+               .plaintext = "123456789012345678901234567890123456789012345678901234567890123"
+                          "45678901234567890",
+               .psize  = 80,
+               .digest = "\xe3\x3b\x4d\xdc\x9c\x38\xf2\x19"
+                         "\x9c\x3e\x7b\x16\x4f\xcc\x05\x36",
+       },
+};
+
+/*
+ * MD5 test vectors from RFC1321
+ */
+#define MD5_TEST_VECTORS       7
+
+static struct hash_testvec md5_tv_template[] = {
+       {
+               .digest = "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04"
+                         "\xe9\x80\x09\x98\xec\xf8\x42\x7e",
+       }, {
+               .plaintext = "a",
+               .psize  = 1,
+               .digest = "\x0c\xc1\x75\xb9\xc0\xf1\xb6\xa8"
+                         "\x31\xc3\x99\xe2\x69\x77\x26\x61",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\x90\x01\x50\x98\x3c\xd2\x4f\xb0"
+                         "\xd6\x96\x3f\x7d\x28\xe1\x7f\x72",
+       }, {
+               .plaintext = "message digest",
+               .psize  = 14,
+               .digest = "\xf9\x6b\x69\x7d\x7c\xb7\x93\x8d"
+                         "\x52\x5a\x2f\x31\xaa\xf1\x61\xd0",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyz",
+               .psize  = 26,
+               .digest = "\xc3\xfc\xd3\xd7\x61\x92\xe4\x00"
+                         "\x7d\xfb\x49\x6c\xca\x67\xe1\x3b",
+               .np     = 2,
+               .tap    = {13, 13}
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+               .psize  = 62,
+               .digest = "\xd1\x74\xab\x98\xd2\x77\xd9\xf5"
+                         "\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f",
+       }, {
+               .plaintext = "12345678901234567890123456789012345678901234567890123456789012"
+                          "345678901234567890",
+               .psize  = 80,
+               .digest = "\x57\xed\xf4\xa2\x2b\xe3\xc9\x55"
+                         "\xac\x49\xda\x2e\x21\x07\xb6\x7a",
+       }
+
+};
+
+/*
+ * RIPEMD-128 test vectors from ISO/IEC 10118-3:2004(E)
+ */
+#define RMD128_TEST_VECTORS     10
+
+static struct hash_testvec rmd128_tv_template[] = {
+       {
+               .digest = "\xcd\xf2\x62\x13\xa1\x50\xdc\x3e"
+                         "\xcb\x61\x0f\x18\xf6\xb3\x8b\x46",
+       }, {
+               .plaintext = "a",
+               .psize  = 1,
+               .digest = "\x86\xbe\x7a\xfa\x33\x9d\x0f\xc7"
+                         "\xcf\xc7\x85\xe7\x2f\x57\x8d\x33",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xc1\x4a\x12\x19\x9c\x66\xe4\xba"
+                         "\x84\x63\x6b\x0f\x69\x14\x4c\x77",
+       }, {
+               .plaintext = "message digest",
+               .psize  = 14,
+               .digest = "\x9e\x32\x7b\x3d\x6e\x52\x30\x62"
+                         "\xaf\xc1\x13\x2d\x7d\xf9\xd1\xb8",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyz",
+               .psize  = 26,
+               .digest = "\xfd\x2a\xa6\x07\xf7\x1d\xc8\xf5"
+                         "\x10\x71\x49\x22\xb3\x71\x83\x4e",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
+                            "fghijklmnopqrstuvwxyz0123456789",
+               .psize  = 62,
+               .digest = "\xd1\xe9\x59\xeb\x17\x9c\x91\x1f"
+                         "\xae\xa4\x62\x4c\x60\xc5\xc7\x02",
+       }, {
+               .plaintext = "1234567890123456789012345678901234567890"
+                            "1234567890123456789012345678901234567890",
+               .psize  = 80,
+               .digest = "\x3f\x45\xef\x19\x47\x32\xc2\xdb"
+                         "\xb2\xc4\xa2\xc7\x69\x79\x5f\xa3",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighij"
+                            "hijkijkljklmklmnlmnomnopnopq",
+               .psize  = 56,
+               .digest = "\xa1\xaa\x06\x89\xd0\xfa\xfa\x2d"
+                         "\xdc\x22\xe8\x8b\x49\x13\x3a\x06",
+               .np     = 2,
+               .tap    = { 28, 28 },
+       }, {
+               .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghi"
+                            "jklmghijklmnhijklmnoijklmnopjklmnopqklmnopqr"
+                            "lmnopqrsmnopqrstnopqrstu",
+               .psize  = 112,
+               .digest = "\xd4\xec\xc9\x13\xe1\xdf\x77\x6b"
+                         "\xf4\x8d\xe9\xd5\x5b\x1f\x25\x46",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
+               .psize  = 32,
+               .digest = "\x13\xfc\x13\xe8\xef\xff\x34\x7d"
+                         "\xe1\x93\xff\x46\xdb\xac\xcf\xd4",
+       }
+};
+
+/*
+ * RIPEMD-160 test vectors from ISO/IEC 10118-3:2004(E)
+ */
+#define RMD160_TEST_VECTORS     10
+
+static struct hash_testvec rmd160_tv_template[] = {
+       {
+               .digest = "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28"
+                         "\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31",
+       }, {
+               .plaintext = "a",
+               .psize  = 1,
+               .digest = "\x0b\xdc\x9d\x2d\x25\x6b\x3e\xe9\xda\xae"
+                         "\x34\x7b\xe6\xf4\xdc\x83\x5a\x46\x7f\xfe",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04"
+                         "\x4a\x8e\x98\xc6\xb0\x87\xf1\x5a\x0b\xfc",
+       }, {
+               .plaintext = "message digest",
+               .psize  = 14,
+               .digest = "\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8"
+                         "\x81\xb1\x23\xa8\x5f\xfa\x21\x59\x5f\x36",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyz",
+               .psize  = 26,
+               .digest = "\xf7\x1c\x27\x10\x9c\x69\x2c\x1b\x56\xbb"
+                         "\xdc\xeb\x5b\x9d\x28\x65\xb3\x70\x8d\xbc",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
+                            "fghijklmnopqrstuvwxyz0123456789",
+               .psize  = 62,
+               .digest = "\xb0\xe2\x0b\x6e\x31\x16\x64\x02\x86\xed"
+                         "\x3a\x87\xa5\x71\x30\x79\xb2\x1f\x51\x89",
+       }, {
+               .plaintext = "1234567890123456789012345678901234567890"
+                            "1234567890123456789012345678901234567890",
+               .psize  = 80,
+               .digest = "\x9b\x75\x2e\x45\x57\x3d\x4b\x39\xf4\xdb"
+                         "\xd3\x32\x3c\xab\x82\xbf\x63\x32\x6b\xfb",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighij"
+                            "hijkijkljklmklmnlmnomnopnopq",
+               .psize  = 56,
+               .digest = "\x12\xa0\x53\x38\x4a\x9c\x0c\x88\xe4\x05"
+                         "\xa0\x6c\x27\xdc\xf4\x9a\xda\x62\xeb\x2b",
+               .np     = 2,
+               .tap    = { 28, 28 },
+       }, {
+               .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghi"
+                            "jklmghijklmnhijklmnoijklmnopjklmnopqklmnopqr"
+                            "lmnopqrsmnopqrstnopqrstu",
+               .psize  = 112,
+               .digest = "\x6f\x3f\xa3\x9b\x6b\x50\x3c\x38\x4f\x91"
+                         "\x9a\x49\xa7\xaa\x5c\x2c\x08\xbd\xfb\x45",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
+               .psize  = 32,
+               .digest = "\x94\xc2\x64\x11\x54\x04\xe6\x33\x79\x0d"
+                         "\xfc\xc8\x7b\x58\x7d\x36\x77\x06\x7d\x9f",
+       }
+};
+
+/*
+ * RIPEMD-256 test vectors
+ */
+#define RMD256_TEST_VECTORS     8
+
+static struct hash_testvec rmd256_tv_template[] = {
+       {
+               .digest = "\x02\xba\x4c\x4e\x5f\x8e\xcd\x18"
+                         "\x77\xfc\x52\xd6\x4d\x30\xe3\x7a"
+                         "\x2d\x97\x74\xfb\x1e\x5d\x02\x63"
+                         "\x80\xae\x01\x68\xe3\xc5\x52\x2d",
+       }, {
+               .plaintext = "a",
+               .psize  = 1,
+               .digest = "\xf9\x33\x3e\x45\xd8\x57\xf5\xd9"
+                         "\x0a\x91\xba\xb7\x0a\x1e\xba\x0c"
+                         "\xfb\x1b\xe4\xb0\x78\x3c\x9a\xcf"
+                         "\xcd\x88\x3a\x91\x34\x69\x29\x25",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xaf\xbd\x6e\x22\x8b\x9d\x8c\xbb"
+                         "\xce\xf5\xca\x2d\x03\xe6\xdb\xa1"
+                         "\x0a\xc0\xbc\x7d\xcb\xe4\x68\x0e"
+                         "\x1e\x42\xd2\xe9\x75\x45\x9b\x65",
+       }, {
+               .plaintext = "message digest",
+               .psize  = 14,
+               .digest = "\x87\xe9\x71\x75\x9a\x1c\xe4\x7a"
+                         "\x51\x4d\x5c\x91\x4c\x39\x2c\x90"
+                         "\x18\xc7\xc4\x6b\xc1\x44\x65\x55"
+                         "\x4a\xfc\xdf\x54\xa5\x07\x0c\x0e",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyz",
+               .psize  = 26,
+               .digest = "\x64\x9d\x30\x34\x75\x1e\xa2\x16"
+                         "\x77\x6b\xf9\xa1\x8a\xcc\x81\xbc"
+                         "\x78\x96\x11\x8a\x51\x97\x96\x87"
+                         "\x82\xdd\x1f\xd9\x7d\x8d\x51\x33",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
+                            "fghijklmnopqrstuvwxyz0123456789",
+               .psize  = 62,
+               .digest = "\x57\x40\xa4\x08\xac\x16\xb7\x20"
+                         "\xb8\x44\x24\xae\x93\x1c\xbb\x1f"
+                         "\xe3\x63\xd1\xd0\xbf\x40\x17\xf1"
+                         "\xa8\x9f\x7e\xa6\xde\x77\xa0\xb8",
+       }, {
+               .plaintext = "1234567890123456789012345678901234567890"
+                            "1234567890123456789012345678901234567890",
+               .psize  = 80,
+               .digest = "\x06\xfd\xcc\x7a\x40\x95\x48\xaa"
+                         "\xf9\x13\x68\xc0\x6a\x62\x75\xb5"
+                         "\x53\xe3\xf0\x99\xbf\x0e\xa4\xed"
+                         "\xfd\x67\x78\xdf\x89\xa8\x90\xdd",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighij"
+                            "hijkijkljklmklmnlmnomnopnopq",
+               .psize  = 56,
+               .digest = "\x38\x43\x04\x55\x83\xaa\xc6\xc8"
+                         "\xc8\xd9\x12\x85\x73\xe7\xa9\x80"
+                         "\x9a\xfb\x2a\x0f\x34\xcc\xc3\x6e"
+                         "\xa9\xe7\x2f\x16\xf6\x36\x8e\x3f",
+               .np     = 2,
+               .tap    = { 28, 28 },
+       }
+};
+
+/*
+ * RIPEMD-320 test vectors
+ */
+#define RMD320_TEST_VECTORS     8
+
+static struct hash_testvec rmd320_tv_template[] = {
+       {
+               .digest = "\x22\xd6\x5d\x56\x61\x53\x6c\xdc\x75\xc1"
+                         "\xfd\xf5\xc6\xde\x7b\x41\xb9\xf2\x73\x25"
+                         "\xeb\xc6\x1e\x85\x57\x17\x7d\x70\x5a\x0e"
+                         "\xc8\x80\x15\x1c\x3a\x32\xa0\x08\x99\xb8",
+       }, {
+               .plaintext = "a",
+               .psize  = 1,
+               .digest = "\xce\x78\x85\x06\x38\xf9\x26\x58\xa5\xa5"
+                         "\x85\x09\x75\x79\x92\x6d\xda\x66\x7a\x57"
+                         "\x16\x56\x2c\xfc\xf6\xfb\xe7\x7f\x63\x54"
+                         "\x2f\x99\xb0\x47\x05\xd6\x97\x0d\xff\x5d",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xde\x4c\x01\xb3\x05\x4f\x89\x30\xa7\x9d"
+                         "\x09\xae\x73\x8e\x92\x30\x1e\x5a\x17\x08"
+                         "\x5b\xef\xfd\xc1\xb8\xd1\x16\x71\x3e\x74"
+                         "\xf8\x2f\xa9\x42\xd6\x4c\xdb\xc4\x68\x2d",
+       }, {
+               .plaintext = "message digest",
+               .psize  = 14,
+               .digest = "\x3a\x8e\x28\x50\x2e\xd4\x5d\x42\x2f\x68"
+                         "\x84\x4f\x9d\xd3\x16\xe7\xb9\x85\x33\xfa"
+                         "\x3f\x2a\x91\xd2\x9f\x84\xd4\x25\xc8\x8d"
+                         "\x6b\x4e\xff\x72\x7d\xf6\x6a\x7c\x01\x97",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyz",
+               .psize  = 26,
+               .digest = "\xca\xbd\xb1\x81\x0b\x92\x47\x0a\x20\x93"
+                         "\xaa\x6b\xce\x05\x95\x2c\x28\x34\x8c\xf4"
+                         "\x3f\xf6\x08\x41\x97\x51\x66\xbb\x40\xed"
+                         "\x23\x40\x04\xb8\x82\x44\x63\xe6\xb0\x09",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
+                            "fghijklmnopqrstuvwxyz0123456789",
+               .psize  = 62,
+               .digest = "\xed\x54\x49\x40\xc8\x6d\x67\xf2\x50\xd2"
+                         "\x32\xc3\x0b\x7b\x3e\x57\x70\xe0\xc6\x0c"
+                         "\x8c\xb9\xa4\xca\xfe\x3b\x11\x38\x8a\xf9"
+                         "\x92\x0e\x1b\x99\x23\x0b\x84\x3c\x86\xa4",
+       }, {
+               .plaintext = "1234567890123456789012345678901234567890"
+                            "1234567890123456789012345678901234567890",
+               .psize  = 80,
+               .digest = "\x55\x78\x88\xaf\x5f\x6d\x8e\xd6\x2a\xb6"
+                         "\x69\x45\xc6\xd2\xa0\xa4\x7e\xcd\x53\x41"
+                         "\xe9\x15\xeb\x8f\xea\x1d\x05\x24\x95\x5f"
+                         "\x82\x5d\xc7\x17\xe4\xa0\x08\xab\x2d\x42",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighij"
+                            "hijkijkljklmklmnlmnomnopnopq",
+               .psize  = 56,
+               .digest = "\xd0\x34\xa7\x95\x0c\xf7\x22\x02\x1b\xa4"
+                         "\xb8\x4d\xf7\x69\xa5\xde\x20\x60\xe2\x59"
+                         "\xdf\x4c\x9b\xb4\xa4\x26\x8c\x0e\x93\x5b"
+                         "\xbc\x74\x70\xa9\x69\xc9\xd0\x72\xa1\xac",
+               .np     = 2,
+               .tap    = { 28, 28 },
+       }
+};
+
+/*
+ * SHA1 test vectors  from from FIPS PUB 180-1
+ */
+#define SHA1_TEST_VECTORS      2
+
+static struct hash_testvec sha1_tv_template[] = {
+       {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xa9\x99\x3e\x36\x47\x06\x81\x6a\xba\x3e"
+                         "\x25\x71\x78\x50\xc2\x6c\x9c\xd0\xd8\x9d",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+               .psize  = 56,
+               .digest = "\x84\x98\x3e\x44\x1c\x3b\xd2\x6e\xba\xae"
+                         "\x4a\xa1\xf9\x51\x29\xe5\xe5\x46\x70\xf1",
+               .np     = 2,
+               .tap    = { 28, 28 }
+       }
+};
+
+
+/*
+ * SHA224 test vectors from from FIPS PUB 180-2
+ */
+#define SHA224_TEST_VECTORS     2
+
+static struct hash_testvec sha224_tv_template[] = {
+       {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\x23\x09\x7D\x22\x34\x05\xD8\x22"
+                         "\x86\x42\xA4\x77\xBD\xA2\x55\xB3"
+                         "\x2A\xAD\xBC\xE4\xBD\xA0\xB3\xF7"
+                         "\xE3\x6C\x9D\xA7",
+       }, {
+               .plaintext =
+               "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+               .psize  = 56,
+               .digest = "\x75\x38\x8B\x16\x51\x27\x76\xCC"
+                         "\x5D\xBA\x5D\xA1\xFD\x89\x01\x50"
+                         "\xB0\xC6\x45\x5C\xB4\xF5\x8B\x19"
+                         "\x52\x52\x25\x25",
+               .np     = 2,
+               .tap    = { 28, 28 }
+       }
+};
+
+/*
+ * SHA256 test vectors from from NIST
+ */
+#define SHA256_TEST_VECTORS    2
+
+static struct hash_testvec sha256_tv_template[] = {
+       {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xba\x78\x16\xbf\x8f\x01\xcf\xea"
+                         "\x41\x41\x40\xde\x5d\xae\x22\x23"
+                         "\xb0\x03\x61\xa3\x96\x17\x7a\x9c"
+                         "\xb4\x10\xff\x61\xf2\x00\x15\xad",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+               .psize  = 56,
+               .digest = "\x24\x8d\x6a\x61\xd2\x06\x38\xb8"
+                         "\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
+                         "\xa3\x3c\xe4\x59\x64\xff\x21\x67"
+                         "\xf6\xec\xed\xd4\x19\xdb\x06\xc1",
+               .np     = 2,
+               .tap    = { 28, 28 }
+       },
+};
+
+/*
+ * SHA384 test vectors from from NIST and kerneli
+ */
+#define SHA384_TEST_VECTORS    4
+
+static struct hash_testvec sha384_tv_template[] = {
+       {
+               .plaintext= "abc",
+               .psize  = 3,
+               .digest = "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b"
+                         "\xb5\xa0\x3d\x69\x9a\xc6\x50\x07"
+                         "\x27\x2c\x32\xab\x0e\xde\xd1\x63"
+                         "\x1a\x8b\x60\x5a\x43\xff\x5b\xed"
+                         "\x80\x86\x07\x2b\xa1\xe7\xcc\x23"
+                         "\x58\xba\xec\xa1\x34\xc8\x25\xa7",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+               .psize  = 56,
+               .digest = "\x33\x91\xfd\xdd\xfc\x8d\xc7\x39"
+                         "\x37\x07\xa6\x5b\x1b\x47\x09\x39"
+                         "\x7c\xf8\xb1\xd1\x62\xaf\x05\xab"
+                         "\xfe\x8f\x45\x0d\xe5\xf3\x6b\xc6"
+                         "\xb0\x45\x5a\x85\x20\xbc\x4e\x6f"
+                         "\x5f\xe9\x5b\x1f\xe3\xc8\x45\x2b",
+       }, {
+               .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+                          "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+               .psize  = 112,
+               .digest = "\x09\x33\x0c\x33\xf7\x11\x47\xe8"
+                         "\x3d\x19\x2f\xc7\x82\xcd\x1b\x47"
+                         "\x53\x11\x1b\x17\x3b\x3b\x05\xd2"
+                         "\x2f\xa0\x80\x86\xe3\xb0\xf7\x12"
+                         "\xfc\xc7\xc7\x1a\x55\x7e\x2d\xb9"
+                         "\x66\xc3\xe9\xfa\x91\x74\x60\x39",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd"
+                          "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
+               .psize  = 104,
+               .digest = "\x3d\x20\x89\x73\xab\x35\x08\xdb"
+                         "\xbd\x7e\x2c\x28\x62\xba\x29\x0a"
+                         "\xd3\x01\x0e\x49\x78\xc1\x98\xdc"
+                         "\x4d\x8f\xd0\x14\xe5\x82\x82\x3a"
+                         "\x89\xe1\x6f\x9b\x2a\x7b\xbc\x1a"
+                         "\xc9\x38\xe2\xd1\x99\xe8\xbe\xa4",
+               .np     = 4,
+               .tap    = { 26, 26, 26, 26 }
+       },
+};
+
+/*
+ * SHA512 test vectors from from NIST and kerneli
+ */
+#define SHA512_TEST_VECTORS    4
+
+static struct hash_testvec sha512_tv_template[] = {
+       {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xdd\xaf\x35\xa1\x93\x61\x7a\xba"
+                         "\xcc\x41\x73\x49\xae\x20\x41\x31"
+                         "\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2"
+                         "\x0a\x9e\xee\xe6\x4b\x55\xd3\x9a"
+                         "\x21\x92\x99\x2a\x27\x4f\xc1\xa8"
+                         "\x36\xba\x3c\x23\xa3\xfe\xeb\xbd"
+                         "\x45\x4d\x44\x23\x64\x3c\xe8\x0e"
+                         "\x2a\x9a\xc9\x4f\xa5\x4c\xa4\x9f",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+               .psize  = 56,
+               .digest = "\x20\x4a\x8f\xc6\xdd\xa8\x2f\x0a"
+                         "\x0c\xed\x7b\xeb\x8e\x08\xa4\x16"
+                         "\x57\xc1\x6e\xf4\x68\xb2\x28\xa8"
+                         "\x27\x9b\xe3\x31\xa7\x03\xc3\x35"
+                         "\x96\xfd\x15\xc1\x3b\x1b\x07\xf9"
+                         "\xaa\x1d\x3b\xea\x57\x78\x9c\xa0"
+                         "\x31\xad\x85\xc7\xa7\x1d\xd7\x03"
+                         "\x54\xec\x63\x12\x38\xca\x34\x45",
+       }, {
+               .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+                          "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+               .psize  = 112,
+               .digest = "\x8e\x95\x9b\x75\xda\xe3\x13\xda"
+                         "\x8c\xf4\xf7\x28\x14\xfc\x14\x3f"
+                         "\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1"
+                         "\x72\x99\xae\xad\xb6\x88\x90\x18"
+                         "\x50\x1d\x28\x9e\x49\x00\xf7\xe4"
+                         "\x33\x1b\x99\xde\xc4\xb5\x43\x3a"
+                         "\xc7\xd3\x29\xee\xb6\xdd\x26\x54"
+                         "\x5e\x96\xe5\x5b\x87\x4b\xe9\x09",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd"
+                          "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
+               .psize  = 104,
+               .digest = "\x93\x0d\x0c\xef\xcb\x30\xff\x11"
+                         "\x33\xb6\x89\x81\x21\xf1\xcf\x3d"
+                         "\x27\x57\x8a\xfc\xaf\xe8\x67\x7c"
+                         "\x52\x57\xcf\x06\x99\x11\xf7\x5d"
+                         "\x8f\x58\x31\xb5\x6e\xbf\xda\x67"
+                         "\xb2\x78\xe6\x6d\xff\x8b\x84\xfe"
+                         "\x2b\x28\x70\xf7\x42\xa5\x80\xd8"
+                         "\xed\xb4\x19\x87\x23\x28\x50\xc9",
+               .np     = 4,
+               .tap    = { 26, 26, 26, 26 }
+       },
+};
+
+
+/*
+ * WHIRLPOOL test vectors from Whirlpool package
+ * by Vincent Rijmen and Paulo S. L. M. Barreto as part of the NESSIE
+ * submission
+ */
+#define WP512_TEST_VECTORS     8
+
+static struct hash_testvec wp512_tv_template[] = {
+       {
+               .plaintext = "",
+               .psize  = 0,
+               .digest = "\x19\xFA\x61\xD7\x55\x22\xA4\x66"
+                         "\x9B\x44\xE3\x9C\x1D\x2E\x17\x26"
+                         "\xC5\x30\x23\x21\x30\xD4\x07\xF8"
+                         "\x9A\xFE\xE0\x96\x49\x97\xF7\xA7"
+                         "\x3E\x83\xBE\x69\x8B\x28\x8F\xEB"
+                         "\xCF\x88\xE3\xE0\x3C\x4F\x07\x57"
+                         "\xEA\x89\x64\xE5\x9B\x63\xD9\x37"
+                         "\x08\xB1\x38\xCC\x42\xA6\x6E\xB3",
+
+
+       }, {
+               .plaintext = "a",
+               .psize  = 1,
+               .digest = "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F"
+                         "\x11\xA6\x72\x06\x53\x1F\xB7\xD7"
+                         "\xF0\xDF\xF5\x94\x13\x14\x5E\x69"
+                         "\x73\xC4\x50\x01\xD0\x08\x7B\x42"
+                         "\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6"
+                         "\x3A\x42\x39\x1A\x39\x14\x5A\x59"
+                         "\x1A\x92\x20\x0D\x56\x01\x95\xE5"
+                         "\x3B\x47\x85\x84\xFD\xAE\x23\x1A",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\x4E\x24\x48\xA4\xC6\xF4\x86\xBB"
+                         "\x16\xB6\x56\x2C\x73\xB4\x02\x0B"
+                         "\xF3\x04\x3E\x3A\x73\x1B\xCE\x72"
+                         "\x1A\xE1\xB3\x03\xD9\x7E\x6D\x4C"
+                         "\x71\x81\xEE\xBD\xB6\xC5\x7E\x27"
+                         "\x7D\x0E\x34\x95\x71\x14\xCB\xD6"
+                         "\xC7\x97\xFC\x9D\x95\xD8\xB5\x82"
+                         "\xD2\x25\x29\x20\x76\xD4\xEE\xF5",
+       }, {
+               .plaintext = "message digest",
+               .psize  = 14,
+               .digest = "\x37\x8C\x84\xA4\x12\x6E\x2D\xC6"
+                         "\xE5\x6D\xCC\x74\x58\x37\x7A\xAC"
+                         "\x83\x8D\x00\x03\x22\x30\xF5\x3C"
+                         "\xE1\xF5\x70\x0C\x0F\xFB\x4D\x3B"
+                         "\x84\x21\x55\x76\x59\xEF\x55\xC1"
+                         "\x06\xB4\xB5\x2A\xC5\xA4\xAA\xA6"
+                         "\x92\xED\x92\x00\x52\x83\x8F\x33"
+                         "\x62\xE8\x6D\xBD\x37\xA8\x90\x3E",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyz",
+               .psize  = 26,
+               .digest = "\xF1\xD7\x54\x66\x26\x36\xFF\xE9"
+                         "\x2C\x82\xEB\xB9\x21\x2A\x48\x4A"
+                         "\x8D\x38\x63\x1E\xAD\x42\x38\xF5"
+                         "\x44\x2E\xE1\x3B\x80\x54\xE4\x1B"
+                         "\x08\xBF\x2A\x92\x51\xC3\x0B\x6A"
+                         "\x0B\x8A\xAE\x86\x17\x7A\xB4\xA6"
+                         "\xF6\x8F\x67\x3E\x72\x07\x86\x5D"
+                         "\x5D\x98\x19\xA3\xDB\xA4\xEB\x3B",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                          "abcdefghijklmnopqrstuvwxyz0123456789",
+               .psize  = 62,
+               .digest = "\xDC\x37\xE0\x08\xCF\x9E\xE6\x9B"
+                         "\xF1\x1F\x00\xED\x9A\xBA\x26\x90"
+                         "\x1D\xD7\xC2\x8C\xDE\xC0\x66\xCC"
+                         "\x6A\xF4\x2E\x40\xF8\x2F\x3A\x1E"
+                         "\x08\xEB\xA2\x66\x29\x12\x9D\x8F"
+                         "\xB7\xCB\x57\x21\x1B\x92\x81\xA6"
+                         "\x55\x17\xCC\x87\x9D\x7B\x96\x21"
+                         "\x42\xC6\x5F\x5A\x7A\xF0\x14\x67",
+       }, {
+               .plaintext = "1234567890123456789012345678901234567890"
+                          "1234567890123456789012345678901234567890",
+               .psize  = 80,
+               .digest = "\x46\x6E\xF1\x8B\xAB\xB0\x15\x4D"
+                         "\x25\xB9\xD3\x8A\x64\x14\xF5\xC0"
+                         "\x87\x84\x37\x2B\xCC\xB2\x04\xD6"
+                         "\x54\x9C\x4A\xFA\xDB\x60\x14\x29"
+                         "\x4D\x5B\xD8\xDF\x2A\x6C\x44\xE5"
+                         "\x38\xCD\x04\x7B\x26\x81\xA5\x1A"
+                         "\x2C\x60\x48\x1E\x88\xC5\xA2\x0B"
+                         "\x2C\x2A\x80\xCF\x3A\x9A\x08\x3B",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
+               .psize  = 32,
+               .digest = "\x2A\x98\x7E\xA4\x0F\x91\x70\x61"
+                         "\xF5\xD6\xF0\xA0\xE4\x64\x4F\x48"
+                         "\x8A\x7A\x5A\x52\xDE\xEE\x65\x62"
+                         "\x07\xC5\x62\xF9\x88\xE9\x5C\x69"
+                         "\x16\xBD\xC8\x03\x1B\xC5\xBE\x1B"
+                         "\x7B\x94\x76\x39\xFE\x05\x0B\x56"
+                         "\x93\x9B\xAA\xA0\xAD\xFF\x9A\xE6"
+                         "\x74\x5B\x7B\x18\x1C\x3B\xE3\xFD",
+       },
+};
+
+#define WP384_TEST_VECTORS     8
+
+static struct hash_testvec wp384_tv_template[] = {
+       {
+               .plaintext = "",
+               .psize  = 0,
+               .digest = "\x19\xFA\x61\xD7\x55\x22\xA4\x66"
+                         "\x9B\x44\xE3\x9C\x1D\x2E\x17\x26"
+                         "\xC5\x30\x23\x21\x30\xD4\x07\xF8"
+                         "\x9A\xFE\xE0\x96\x49\x97\xF7\xA7"
+                         "\x3E\x83\xBE\x69\x8B\x28\x8F\xEB"
+                         "\xCF\x88\xE3\xE0\x3C\x4F\x07\x57",
+
+
+       }, {
+               .plaintext = "a",
+               .psize  = 1,
+               .digest = "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F"
+                         "\x11\xA6\x72\x06\x53\x1F\xB7\xD7"
+                         "\xF0\xDF\xF5\x94\x13\x14\x5E\x69"
+                         "\x73\xC4\x50\x01\xD0\x08\x7B\x42"
+                         "\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6"
+                         "\x3A\x42\x39\x1A\x39\x14\x5A\x59",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\x4E\x24\x48\xA4\xC6\xF4\x86\xBB"
+                         "\x16\xB6\x56\x2C\x73\xB4\x02\x0B"
+                         "\xF3\x04\x3E\x3A\x73\x1B\xCE\x72"
+                         "\x1A\xE1\xB3\x03\xD9\x7E\x6D\x4C"
+                         "\x71\x81\xEE\xBD\xB6\xC5\x7E\x27"
+                         "\x7D\x0E\x34\x95\x71\x14\xCB\xD6",
+       }, {
+               .plaintext = "message digest",
+               .psize  = 14,
+               .digest = "\x37\x8C\x84\xA4\x12\x6E\x2D\xC6"
+                         "\xE5\x6D\xCC\x74\x58\x37\x7A\xAC"
+                         "\x83\x8D\x00\x03\x22\x30\xF5\x3C"
+                         "\xE1\xF5\x70\x0C\x0F\xFB\x4D\x3B"
+                         "\x84\x21\x55\x76\x59\xEF\x55\xC1"
+                         "\x06\xB4\xB5\x2A\xC5\xA4\xAA\xA6",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyz",
+               .psize  = 26,
+               .digest = "\xF1\xD7\x54\x66\x26\x36\xFF\xE9"
+                         "\x2C\x82\xEB\xB9\x21\x2A\x48\x4A"
+                         "\x8D\x38\x63\x1E\xAD\x42\x38\xF5"
+                         "\x44\x2E\xE1\x3B\x80\x54\xE4\x1B"
+                         "\x08\xBF\x2A\x92\x51\xC3\x0B\x6A"
+                         "\x0B\x8A\xAE\x86\x17\x7A\xB4\xA6",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                          "abcdefghijklmnopqrstuvwxyz0123456789",
+               .psize  = 62,
+               .digest = "\xDC\x37\xE0\x08\xCF\x9E\xE6\x9B"
+                         "\xF1\x1F\x00\xED\x9A\xBA\x26\x90"
+                         "\x1D\xD7\xC2\x8C\xDE\xC0\x66\xCC"
+                         "\x6A\xF4\x2E\x40\xF8\x2F\x3A\x1E"
+                         "\x08\xEB\xA2\x66\x29\x12\x9D\x8F"
+                         "\xB7\xCB\x57\x21\x1B\x92\x81\xA6",
+       }, {
+               .plaintext = "1234567890123456789012345678901234567890"
+                          "1234567890123456789012345678901234567890",
+               .psize  = 80,
+               .digest = "\x46\x6E\xF1\x8B\xAB\xB0\x15\x4D"
+                         "\x25\xB9\xD3\x8A\x64\x14\xF5\xC0"
+                         "\x87\x84\x37\x2B\xCC\xB2\x04\xD6"
+                         "\x54\x9C\x4A\xFA\xDB\x60\x14\x29"
+                         "\x4D\x5B\xD8\xDF\x2A\x6C\x44\xE5"
+                         "\x38\xCD\x04\x7B\x26\x81\xA5\x1A",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
+               .psize  = 32,
+               .digest = "\x2A\x98\x7E\xA4\x0F\x91\x70\x61"
+                         "\xF5\xD6\xF0\xA0\xE4\x64\x4F\x48"
+                         "\x8A\x7A\x5A\x52\xDE\xEE\x65\x62"
+                         "\x07\xC5\x62\xF9\x88\xE9\x5C\x69"
+                         "\x16\xBD\xC8\x03\x1B\xC5\xBE\x1B"
+                         "\x7B\x94\x76\x39\xFE\x05\x0B\x56",
+       },
+};
+
+#define WP256_TEST_VECTORS     8
+
+static struct hash_testvec wp256_tv_template[] = {
+       {
+               .plaintext = "",
+               .psize  = 0,
+               .digest = "\x19\xFA\x61\xD7\x55\x22\xA4\x66"
+                         "\x9B\x44\xE3\x9C\x1D\x2E\x17\x26"
+                         "\xC5\x30\x23\x21\x30\xD4\x07\xF8"
+                         "\x9A\xFE\xE0\x96\x49\x97\xF7\xA7",
+
+
+       }, {
+               .plaintext = "a",
+               .psize  = 1,
+               .digest = "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F"
+                         "\x11\xA6\x72\x06\x53\x1F\xB7\xD7"
+                         "\xF0\xDF\xF5\x94\x13\x14\x5E\x69"
+                         "\x73\xC4\x50\x01\xD0\x08\x7B\x42",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\x4E\x24\x48\xA4\xC6\xF4\x86\xBB"
+                         "\x16\xB6\x56\x2C\x73\xB4\x02\x0B"
+                         "\xF3\x04\x3E\x3A\x73\x1B\xCE\x72"
+                         "\x1A\xE1\xB3\x03\xD9\x7E\x6D\x4C",
+       }, {
+               .plaintext = "message digest",
+               .psize  = 14,
+               .digest = "\x37\x8C\x84\xA4\x12\x6E\x2D\xC6"
+                         "\xE5\x6D\xCC\x74\x58\x37\x7A\xAC"
+                         "\x83\x8D\x00\x03\x22\x30\xF5\x3C"
+                         "\xE1\xF5\x70\x0C\x0F\xFB\x4D\x3B",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyz",
+               .psize  = 26,
+               .digest = "\xF1\xD7\x54\x66\x26\x36\xFF\xE9"
+                         "\x2C\x82\xEB\xB9\x21\x2A\x48\x4A"
+                         "\x8D\x38\x63\x1E\xAD\x42\x38\xF5"
+                         "\x44\x2E\xE1\x3B\x80\x54\xE4\x1B",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                          "abcdefghijklmnopqrstuvwxyz0123456789",
+               .psize  = 62,
+               .digest = "\xDC\x37\xE0\x08\xCF\x9E\xE6\x9B"
+                         "\xF1\x1F\x00\xED\x9A\xBA\x26\x90"
+                         "\x1D\xD7\xC2\x8C\xDE\xC0\x66\xCC"
+                         "\x6A\xF4\x2E\x40\xF8\x2F\x3A\x1E",
+       }, {
+               .plaintext = "1234567890123456789012345678901234567890"
+                          "1234567890123456789012345678901234567890",
+               .psize  = 80,
+               .digest = "\x46\x6E\xF1\x8B\xAB\xB0\x15\x4D"
+                         "\x25\xB9\xD3\x8A\x64\x14\xF5\xC0"
+                         "\x87\x84\x37\x2B\xCC\xB2\x04\xD6"
+                         "\x54\x9C\x4A\xFA\xDB\x60\x14\x29",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
+               .psize  = 32,
+               .digest = "\x2A\x98\x7E\xA4\x0F\x91\x70\x61"
+                         "\xF5\xD6\xF0\xA0\xE4\x64\x4F\x48"
+                         "\x8A\x7A\x5A\x52\xDE\xEE\x65\x62"
+                         "\x07\xC5\x62\xF9\x88\xE9\x5C\x69",
+       },
+};
+
+/*
+ * TIGER test vectors from Tiger website
+ */
+#define TGR192_TEST_VECTORS    6
+
+static struct hash_testvec tgr192_tv_template[] = {
+       {
+               .plaintext = "",
+               .psize  = 0,
+               .digest = "\x24\xf0\x13\x0c\x63\xac\x93\x32"
+                         "\x16\x16\x6e\x76\xb1\xbb\x92\x5f"
+                         "\xf3\x73\xde\x2d\x49\x58\x4e\x7a",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xf2\x58\xc1\xe8\x84\x14\xab\x2a"
+                         "\x52\x7a\xb5\x41\xff\xc5\xb8\xbf"
+                         "\x93\x5f\x7b\x95\x1c\x13\x29\x51",
+       }, {
+               .plaintext = "Tiger",
+               .psize  = 5,
+               .digest = "\x9f\x00\xf5\x99\x07\x23\x00\xdd"
+                         "\x27\x6a\xbb\x38\xc8\xeb\x6d\xec"
+                         "\x37\x79\x0c\x11\x6f\x9d\x2b\xdf",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
+               .psize  = 64,
+               .digest = "\x87\xfb\x2a\x90\x83\x85\x1c\xf7"
+                         "\x47\x0d\x2c\xf8\x10\xe6\xdf\x9e"
+                         "\xb5\x86\x44\x50\x34\xa5\xa3\x86",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789",
+               .psize  = 64,
+               .digest = "\x46\x7d\xb8\x08\x63\xeb\xce\x48"
+                         "\x8d\xf1\xcd\x12\x61\x65\x5d\xe9"
+                         "\x57\x89\x65\x65\x97\x5f\x91\x97",
+       }, {
+               .plaintext = "Tiger - A Fast New Hash Function, "
+                          "by Ross Anderson and Eli Biham, "
+                          "proceedings of Fast Software Encryption 3, "
+                          "Cambridge, 1996.",
+               .psize  = 125,
+               .digest = "\x3d\x9a\xeb\x03\xd1\xbd\x1a\x63"
+                         "\x57\xb2\x77\x4d\xfd\x6d\x5b\x24"
+                         "\xdd\x68\x15\x1d\x50\x39\x74\xfc",
+       },
+};
+
+#define TGR160_TEST_VECTORS    6
+
+static struct hash_testvec tgr160_tv_template[] = {
+       {
+               .plaintext = "",
+               .psize  = 0,
+               .digest = "\x24\xf0\x13\x0c\x63\xac\x93\x32"
+                         "\x16\x16\x6e\x76\xb1\xbb\x92\x5f"
+                         "\xf3\x73\xde\x2d",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xf2\x58\xc1\xe8\x84\x14\xab\x2a"
+                         "\x52\x7a\xb5\x41\xff\xc5\xb8\xbf"
+                         "\x93\x5f\x7b\x95",
+       }, {
+               .plaintext = "Tiger",
+               .psize  = 5,
+               .digest = "\x9f\x00\xf5\x99\x07\x23\x00\xdd"
+                         "\x27\x6a\xbb\x38\xc8\xeb\x6d\xec"
+                         "\x37\x79\x0c\x11",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
+               .psize  = 64,
+               .digest = "\x87\xfb\x2a\x90\x83\x85\x1c\xf7"
+                         "\x47\x0d\x2c\xf8\x10\xe6\xdf\x9e"
+                         "\xb5\x86\x44\x50",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789",
+               .psize  = 64,
+               .digest = "\x46\x7d\xb8\x08\x63\xeb\xce\x48"
+                         "\x8d\xf1\xcd\x12\x61\x65\x5d\xe9"
+                         "\x57\x89\x65\x65",
+       }, {
+               .plaintext = "Tiger - A Fast New Hash Function, "
+                          "by Ross Anderson and Eli Biham, "
+                          "proceedings of Fast Software Encryption 3, "
+                          "Cambridge, 1996.",
+               .psize  = 125,
+               .digest = "\x3d\x9a\xeb\x03\xd1\xbd\x1a\x63"
+                         "\x57\xb2\x77\x4d\xfd\x6d\x5b\x24"
+                         "\xdd\x68\x15\x1d",
+       },
+};
+
+#define TGR128_TEST_VECTORS    6
+
+static struct hash_testvec tgr128_tv_template[] = {
+       {
+               .plaintext = "",
+               .psize  = 0,
+               .digest = "\x24\xf0\x13\x0c\x63\xac\x93\x32"
+                         "\x16\x16\x6e\x76\xb1\xbb\x92\x5f",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xf2\x58\xc1\xe8\x84\x14\xab\x2a"
+                         "\x52\x7a\xb5\x41\xff\xc5\xb8\xbf",
+       }, {
+               .plaintext = "Tiger",
+               .psize  = 5,
+               .digest = "\x9f\x00\xf5\x99\x07\x23\x00\xdd"
+                         "\x27\x6a\xbb\x38\xc8\xeb\x6d\xec",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
+               .psize  = 64,
+               .digest = "\x87\xfb\x2a\x90\x83\x85\x1c\xf7"
+                         "\x47\x0d\x2c\xf8\x10\xe6\xdf\x9e",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789",
+               .psize  = 64,
+               .digest = "\x46\x7d\xb8\x08\x63\xeb\xce\x48"
+                         "\x8d\xf1\xcd\x12\x61\x65\x5d\xe9",
+       }, {
+               .plaintext = "Tiger - A Fast New Hash Function, "
+                          "by Ross Anderson and Eli Biham, "
+                          "proceedings of Fast Software Encryption 3, "
+                          "Cambridge, 1996.",
+               .psize  = 125,
+               .digest = "\x3d\x9a\xeb\x03\xd1\xbd\x1a\x63"
+                         "\x57\xb2\x77\x4d\xfd\x6d\x5b\x24",
+       },
+};
+
+/*
+ * HMAC-MD5 test vectors from RFC2202
+ * (These need to be fixed to not use strlen).
+ */
+#ifndef CONFIG_CRYPTO_DEV_MD5_HMAC
+#define HMAC_MD5_TEST_VECTORS  7
+#else
+#define HMAC_MD5_TEST_VECTORS   5
+#endif
+
+static struct hash_testvec hmac_md5_tv_template[] =
+{
+       {
+               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+               .ksize  = 16,
+               .plaintext = "Hi There",
+               .psize  = 8,
+               .digest = "\x92\x94\x72\x7a\x36\x38\xbb\x1c"
+                         "\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d",
+       }, {
+               .key    = "Jefe",
+               .ksize  = 4,
+               .plaintext = "what do ya want for nothing?",
+               .psize  = 28,
+               .digest = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03"
+                         "\xea\xa8\x6e\x31\x0a\x5d\xb7\x38",
+               .np     = 2,
+               .tap    = {14, 14}
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+               .ksize  = 16,
+               .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+               .psize  = 50,
+               .digest = "\x56\xbe\x34\x52\x1d\x14\x4c\x88"
+                         "\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6",
+       }, {
+               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
+                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+                         "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+               .ksize  = 25,
+               .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+               .psize  = 50,
+               .digest = "\x69\x7e\xaf\x0a\xca\x3a\x3a\xea"
+                         "\x3a\x75\x16\x47\x46\xff\xaa\x79",
+       }, {
+               .key    = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
+               .ksize  = 16,
+               .plaintext = "Test With Truncation",
+               .psize  = 20,
+               .digest = "\x56\x46\x1e\xf2\x34\x2e\xdc\x00"
+                         "\xf9\xba\xb9\x95\x69\x0e\xfd\x4c",
+#ifndef CONFIG_CRYPTO_DEV_MD5_HMAC
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa",
+               .ksize  = 80,
+               .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
+               .psize  = 54,
+               .digest = "\x6b\x1a\xb7\xfe\x4b\xd7\xbf\x8f"
+                         "\x0b\x62\xe6\xce\x61\xb9\xd0\xcd",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa",
+               .ksize  = 80,
+               .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One "
+                          "Block-Size Data",
+               .psize  = 73,
+               .digest = "\x6f\x63\x0f\xad\x67\xcd\xa0\xee"
+                         "\x1f\xb1\xf5\x62\xdb\x3a\xa5\x3e",
+#endif /* CONFIG_CRYPTO_DEV_MD5_HMAC */
+       },
+};
+
+/*
+ * HMAC-RIPEMD128 test vectors from RFC2286
+ */
+#define HMAC_RMD128_TEST_VECTORS       7
+
+static struct hash_testvec hmac_rmd128_tv_template[] = {
+       {
+               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+               .ksize  = 16,
+               .plaintext = "Hi There",
+               .psize  = 8,
+               .digest = "\xfb\xf6\x1f\x94\x92\xaa\x4b\xbf"
+                         "\x81\xc1\x72\xe8\x4e\x07\x34\xdb",
+       }, {
+               .key    = "Jefe",
+               .ksize  = 4,
+               .plaintext = "what do ya want for nothing?",
+               .psize  = 28,
+               .digest = "\x87\x5f\x82\x88\x62\xb6\xb3\x34"
+                         "\xb4\x27\xc5\x5f\x9f\x7f\xf0\x9b",
+               .np     = 2,
+               .tap    = { 14, 14 },
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+               .ksize  = 16,
+               .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+               .psize  = 50,
+               .digest = "\x09\xf0\xb2\x84\x6d\x2f\x54\x3d"
+                         "\xa3\x63\xcb\xec\x8d\x62\xa3\x8d",
+       }, {
+               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
+                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+                         "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+               .ksize  = 25,
+               .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+               .psize  = 50,
+               .digest = "\xbd\xbb\xd7\xcf\x03\xe4\x4b\x5a"
+                         "\xa6\x0a\xf8\x15\xbe\x4d\x22\x94",
+       }, {
+               .key    = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
+               .ksize  = 16,
+               .plaintext = "Test With Truncation",
+               .psize  = 20,
+               .digest = "\xe7\x98\x08\xf2\x4b\x25\xfd\x03"
+                         "\x1c\x15\x5f\x0d\x55\x1d\x9a\x3a",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa",
+               .ksize  = 80,
+               .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
+               .psize  = 54,
+               .digest = "\xdc\x73\x29\x28\xde\x98\x10\x4a"
+                         "\x1f\x59\xd3\x73\xc1\x50\xac\xbb",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa",
+               .ksize  = 80,
+               .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One "
+                          "Block-Size Data",
+               .psize  = 73,
+               .digest = "\x5c\x6b\xec\x96\x79\x3e\x16\xd4"
+                         "\x06\x90\xc2\x37\x63\x5f\x30\xc5",
+       },
+};
+
+/*
+ * HMAC-RIPEMD160 test vectors from RFC2286
+ */
+#define HMAC_RMD160_TEST_VECTORS       7
+
+static struct hash_testvec hmac_rmd160_tv_template[] = {
+       {
+               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+               .ksize  = 20,
+               .plaintext = "Hi There",
+               .psize  = 8,
+               .digest = "\x24\xcb\x4b\xd6\x7d\x20\xfc\x1a\x5d\x2e"
+                         "\xd7\x73\x2d\xcc\x39\x37\x7f\x0a\x56\x68",
+       }, {
+               .key    = "Jefe",
+               .ksize  = 4,
+               .plaintext = "what do ya want for nothing?",
+               .psize  = 28,
+               .digest = "\xdd\xa6\xc0\x21\x3a\x48\x5a\x9e\x24\xf4"
+                         "\x74\x20\x64\xa7\xf0\x33\xb4\x3c\x40\x69",
+               .np     = 2,
+               .tap    = { 14, 14 },
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+               .ksize  = 20,
+               .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+               .psize  = 50,
+               .digest = "\xb0\xb1\x05\x36\x0d\xe7\x59\x96\x0a\xb4"
+                         "\xf3\x52\x98\xe1\x16\xe2\x95\xd8\xe7\xc1",
+       }, {
+               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
+                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+                         "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+               .ksize  = 25,
+               .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+               .psize  = 50,
+               .digest = "\xd5\xca\x86\x2f\x4d\x21\xd5\xe6\x10\xe1"
+                         "\x8b\x4c\xf1\xbe\xb9\x7a\x43\x65\xec\xf4",
+       }, {
+               .key    = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
+               .ksize  = 20,
+               .plaintext = "Test With Truncation",
+               .psize  = 20,
+               .digest = "\x76\x19\x69\x39\x78\xf9\x1d\x90\x53\x9a"
+                         "\xe7\x86\x50\x0f\xf3\xd8\xe0\x51\x8e\x39",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa",
+               .ksize  = 80,
+               .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
+               .psize  = 54,
+               .digest = "\x64\x66\xca\x07\xac\x5e\xac\x29\xe1\xbd"
+                         "\x52\x3e\x5a\xda\x76\x05\xb7\x91\xfd\x8b",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa",
+               .ksize  = 80,
+               .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One "
+                          "Block-Size Data",
+               .psize  = 73,
+               .digest = "\x69\xea\x60\x79\x8d\x71\x61\x6c\xce\x5f"
+                         "\xd0\x87\x1e\x23\x75\x4c\xd7\x5d\x5a\x0a",
+       },
+};
+
+/*
+ * HMAC-SHA1 test vectors from RFC2202
+ */
+#ifndef CONFIG_CRYPTO_DEV_SHA1_HMAC
+#define HMAC_SHA1_TEST_VECTORS 7
+#else
+#define HMAC_SHA1_TEST_VECTORS  5
+#endif
+
+static struct hash_testvec hmac_sha1_tv_template[] = {
+       {
+               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+               .ksize  = 20,
+               .plaintext = "Hi There",
+               .psize  = 8,
+               .digest = "\xb6\x17\x31\x86\x55\x05\x72\x64"
+                         "\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1"
+                         "\x46\xbe",
+       }, {
+               .key    = "Jefe",
+               .ksize  = 4,
+               .plaintext = "what do ya want for nothing?",
+               .psize  = 28,
+               .digest = "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74"
+                         "\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79",
+               .np     = 2,
+               .tap    = { 14, 14 }
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+               .ksize  = 20,
+               .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+               .psize  = 50,
+               .digest = "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3"
+                         "\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3",
+       }, {
+               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
+                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+                         "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+               .ksize  = 25,
+               .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+               .psize  = 50,
+               .digest = "\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84"
+                         "\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda",
+       }, {
+               .key    = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
+               .ksize  = 20,
+               .plaintext = "Test With Truncation",
+               .psize  = 20,
+               .digest = "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2"
+                         "\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04",
+
+#ifndef CONFIG_CRYPTO_DEV_SHA1_HMAC
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa",
+               .ksize  = 80,
+               .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
+               .psize  = 54,
+               .digest = "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70"
+                         "\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa",
+               .ksize  = 80,
+               .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One "
+                          "Block-Size Data",
+               .psize  = 73,
+               .digest = "\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b"
+                         "\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91",
+#endif
+       },
+};
+
+
+/*
+ * SHA224 HMAC test vectors from RFC4231
+ */
+#define HMAC_SHA224_TEST_VECTORS    4
+
+static struct hash_testvec hmac_sha224_tv_template[] = {
+       {
+               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                       "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                       "\x0b\x0b\x0b\x0b",
+               .ksize  = 20,
+               /*  ("Hi There") */
+               .plaintext = "\x48\x69\x20\x54\x68\x65\x72\x65",
+               .psize  = 8,
+               .digest = "\x89\x6f\xb1\x12\x8a\xbb\xdf\x19"
+                       "\x68\x32\x10\x7c\xd4\x9d\xf3\x3f"
+                       "\x47\xb4\xb1\x16\x99\x12\xba\x4f"
+                       "\x53\x68\x4b\x22",
+       }, {
+               .key    = "Jefe",
+               .ksize  = 4,
+               /* ("what do ya want for nothing?") */
+               .plaintext = "\x77\x68\x61\x74\x20\x64\x6f\x20"
+                       "\x79\x61\x20\x77\x61\x6e\x74\x20"
+                       "\x66\x6f\x72\x20\x6e\x6f\x74\x68"
+                       "\x69\x6e\x67\x3f",
+               .psize  = 28,
+               .digest = "\xa3\x0e\x01\x09\x8b\xc6\xdb\xbf"
+                       "\x45\x69\x0f\x3a\x7e\x9e\x6d\x0f"
+                       "\x8b\xbe\xa2\xa3\x9e\x61\x48\x00"
+                       "\x8f\xd0\x5e\x44",
+               .np = 4,
+               .tap    = { 7, 7, 7, 7 }
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa",
+               .ksize  = 131,
+               /* ("Test Using Larger Than Block-Size Key - Hash Key First") */
+               .plaintext = "\x54\x65\x73\x74\x20\x55\x73\x69"
+                       "\x6e\x67\x20\x4c\x61\x72\x67\x65"
+                       "\x72\x20\x54\x68\x61\x6e\x20\x42"
+                       "\x6c\x6f\x63\x6b\x2d\x53\x69\x7a"
+                       "\x65\x20\x4b\x65\x79\x20\x2d\x20"
+                       "\x48\x61\x73\x68\x20\x4b\x65\x79"
+                       "\x20\x46\x69\x72\x73\x74",
+               .psize  = 54,
+               .digest = "\x95\xe9\xa0\xdb\x96\x20\x95\xad"
+                       "\xae\xbe\x9b\x2d\x6f\x0d\xbc\xe2"
+                       "\xd4\x99\xf1\x12\xf2\xd2\xb7\x27"
+                       "\x3f\xa6\x87\x0e",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa",
+               .ksize  = 131,
+               /* ("This is a test using a larger than block-size key and a")
+               (" larger than block-size data. The key needs to be")
+                       (" hashed before being used by the HMAC algorithm.") */
+               .plaintext = "\x54\x68\x69\x73\x20\x69\x73\x20"
+                       "\x61\x20\x74\x65\x73\x74\x20\x75"
+                       "\x73\x69\x6e\x67\x20\x61\x20\x6c"
+                       "\x61\x72\x67\x65\x72\x20\x74\x68"
+                       "\x61\x6e\x20\x62\x6c\x6f\x63\x6b"
+                       "\x2d\x73\x69\x7a\x65\x20\x6b\x65"
+                       "\x79\x20\x61\x6e\x64\x20\x61\x20"
+                       "\x6c\x61\x72\x67\x65\x72\x20\x74"
+                       "\x68\x61\x6e\x20\x62\x6c\x6f\x63"
+                       "\x6b\x2d\x73\x69\x7a\x65\x20\x64"
+                       "\x61\x74\x61\x2e\x20\x54\x68\x65"
+                       "\x20\x6b\x65\x79\x20\x6e\x65\x65"
+                       "\x64\x73\x20\x74\x6f\x20\x62\x65"
+                       "\x20\x68\x61\x73\x68\x65\x64\x20"
+                       "\x62\x65\x66\x6f\x72\x65\x20\x62"
+                       "\x65\x69\x6e\x67\x20\x75\x73\x65"
+                       "\x64\x20\x62\x79\x20\x74\x68\x65"
+                       "\x20\x48\x4d\x41\x43\x20\x61\x6c"
+                       "\x67\x6f\x72\x69\x74\x68\x6d\x2e",
+               .psize  = 152,
+               .digest = "\x3a\x85\x41\x66\xac\x5d\x9f\x02"
+                       "\x3f\x54\xd5\x17\xd0\xb3\x9d\xbd"
+                       "\x94\x67\x70\xdb\x9c\x2b\x95\xc9"
+                       "\xf6\xf5\x65\xd1",
+       },
+};
+
+/*
+ * HMAC-SHA256 test vectors from
+ * draft-ietf-ipsec-ciph-sha-256-01.txt
+ */
+#define HMAC_SHA256_TEST_VECTORS       10
+
+static struct hash_testvec hmac_sha256_tv_template[] = {
+       {
+               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
+                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+                         "\x11\x12\x13\x14\x15\x16\x17\x18"
+                         "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20",
+               .ksize  = 32,
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xa2\x1b\x1f\x5d\x4c\xf4\xf7\x3a"
+                         "\x4d\xd9\x39\x75\x0f\x7a\x06\x6a"
+                         "\x7f\x98\xcc\x13\x1c\xb1\x6a\x66"
+                         "\x92\x75\x90\x21\xcf\xab\x81\x81",
+       }, {
+               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
+                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+                         "\x11\x12\x13\x14\x15\x16\x17\x18"
+                         "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20",
+               .ksize  = 32,
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+               .psize  = 56,
+               .digest = "\x10\x4f\xdc\x12\x57\x32\x8f\x08"
+                         "\x18\x4b\xa7\x31\x31\xc5\x3c\xae"
+                         "\xe6\x98\xe3\x61\x19\x42\x11\x49"
+                         "\xea\x8c\x71\x24\x56\x69\x7d\x30",
+       }, {
+               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
+                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+                         "\x11\x12\x13\x14\x15\x16\x17\x18"
+                         "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20",
+               .ksize  = 32,
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+                          "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+               .psize  = 112,
+               .digest = "\x47\x03\x05\xfc\x7e\x40\xfe\x34"
+                         "\xd3\xee\xb3\xe7\x73\xd9\x5a\xab"
+                         "\x73\xac\xf0\xfd\x06\x04\x47\xa5"
+                         "\xeb\x45\x95\xbf\x33\xa9\xd1\xa3",
+       }, {
+               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                       "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                       "\x0b\x0b\x0b\x0b\x0b\x0b",
+               .ksize  = 32,
+               .plaintext = "Hi There",
+               .psize  = 8,
+               .digest = "\x19\x8a\x60\x7e\xb4\x4b\xfb\xc6"
+                         "\x99\x03\xa0\xf1\xcf\x2b\xbd\xc5"
+                         "\xba\x0a\xa3\xf3\xd9\xae\x3c\x1c"
+                         "\x7a\x3b\x16\x96\xa0\xb6\x8c\xf7",
+       }, {
+               .key    = "Jefe",
+               .ksize  = 4,
+               .plaintext = "what do ya want for nothing?",
+               .psize  = 28,
+               .digest = "\x5b\xdc\xc1\x46\xbf\x60\x75\x4e"
+                         "\x6a\x04\x24\x26\x08\x95\x75\xc7"
+                         "\x5a\x00\x3f\x08\x9d\x27\x39\x83"
+                         "\x9d\xec\x58\xb9\x64\xec\x38\x43",
+               .np     = 2,
+               .tap    = { 14, 14 }
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+               .ksize  = 32,
+               .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+               .psize  = 50,
+               .digest = "\xcd\xcb\x12\x20\xd1\xec\xcc\xea"
+                         "\x91\xe5\x3a\xba\x30\x92\xf9\x62"
+                         "\xe5\x49\xfe\x6c\xe9\xed\x7f\xdc"
+                         "\x43\x19\x1f\xbd\xe4\x5c\x30\xb0",
+       }, {
+               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
+                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+                         "\x11\x12\x13\x14\x15\x16\x17\x18"
+                         "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
+                         "\x21\x22\x23\x24\x25",
+               .ksize  = 37,
+               .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+               .psize  = 50,
+               .digest = "\xd4\x63\x3c\x17\xf6\xfb\x8d\x74"
+                         "\x4c\x66\xde\xe0\xf8\xf0\x74\x55"
+                         "\x6e\xc4\xaf\x55\xef\x07\x99\x85"
+                         "\x41\x46\x8e\xb4\x9b\xd2\xe9\x17",
+       }, {
+               .key    = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+                       "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+                       "\x0c\x0c\x0c\x0c\x0c\x0c",
+               .ksize  = 32,
+               .plaintext = "Test With Truncation",
+               .psize  = 20,
+               .digest = "\x75\x46\xaf\x01\x84\x1f\xc0\x9b"
+                         "\x1a\xb9\xc3\x74\x9a\x5f\x1c\x17"
+                         "\xd4\xf5\x89\x66\x8a\x58\x7b\x27"
+                         "\x00\xa9\xc9\x7c\x11\x93\xcf\x42",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa",
+               .ksize  = 80,
+               .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
+               .psize  = 54,
+               .digest = "\x69\x53\x02\x5e\xd9\x6f\x0c\x09"
+                         "\xf8\x0a\x96\xf7\x8e\x65\x38\xdb"
+                         "\xe2\xe7\xb8\x20\xe3\xdd\x97\x0e"
+                         "\x7d\xdd\x39\x09\x1b\x32\x35\x2f",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa",
+               .ksize  = 80,
+               .plaintext = "Test Using Larger Than Block-Size Key and Larger Than "
+                          "One Block-Size Data",
+               .psize  = 73,
+               .digest = "\x63\x55\xac\x22\xe8\x90\xd0\xa3"
+                         "\xc8\x48\x1a\x5c\xa4\x82\x5b\xc8"
+                         "\x84\xd3\xe7\xa1\xff\x98\xa2\xfc"
+                         "\x2a\xc7\xd8\xe0\x64\xc3\xb2\xe6",
+       },
+};
+
+#define XCBC_AES_TEST_VECTORS 6
+
+static struct hash_testvec aes_xcbc128_tv_template[] = {
+       {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .plaintext = zeroed_string,
+               .digest = "\x75\xf0\x25\x1d\x52\x8a\xc0\x1c"
+                         "\x45\x73\xdf\xd5\x84\xd7\x9f\x29",
+               .psize  = 0,
+               .ksize  = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .plaintext = "\x00\x01\x02",
+               .digest = "\x5b\x37\x65\x80\xae\x2f\x19\xaf"
+                         "\xe7\x21\x9c\xee\xf1\x72\x75\x6f",
+               .psize  = 3,
+               .ksize  = 16,
+       } , {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .plaintext = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                            "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .digest = "\xd2\xa2\x46\xfa\x34\x9b\x68\xa7"
+                         "\x99\x98\xa4\x39\x4f\xf7\xa2\x63",
+               .psize  = 16,
+               .ksize  = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .plaintext = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                            "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                            "\x10\x11\x12\x13",
+               .digest = "\x47\xf5\x1b\x45\x64\x96\x62\x15"
+                         "\xb8\x98\x5c\x63\x05\x5e\xd3\x08",
+               .tap    = { 10, 10 },
+               .psize  = 20,
+               .np     = 2,
+               .ksize  = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .plaintext = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                            "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                            "\x10\x11\x12\x13\x14\x15\x16\x17"
+                            "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .digest = "\xf5\x4f\x0e\xc8\xd2\xb9\xf3\xd3"
+                         "\x68\x07\x73\x4b\xd5\x28\x3f\xd4",
+               .psize  = 32,
+               .ksize  = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .plaintext = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                            "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                            "\x10\x11\x12\x13\x14\x15\x16\x17"
+                            "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+                            "\x20\x21",
+               .digest = "\xbe\xcb\xb3\xbc\xcd\xb5\x18\xa3"
+                         "\x06\x77\xd5\x48\x1f\xb6\xb4\xd8",
+               .tap    = { 17, 17 },
+               .psize  = 34,
+               .np     = 2,
+               .ksize  = 16,
+       }
+};
+
+#define VMAC_AES_TEST_VECTORS  1
+static char vmac_string[128] = {'\x01', '\x01', '\x01', '\x01',
+                               '\x02', '\x03', '\x02', '\x02',
+                               '\x02', '\x04', '\x01', '\x07',
+                               '\x04', '\x01', '\x04', '\x03',};
+static struct hash_testvec aes_vmac128_tv_template[] = {
+       {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .plaintext = vmac_string,
+               .digest = "\xcb\xd7\x8a\xfd\xb7\x33\x79\xe7",
+               .psize  = 128,
+               .ksize  = 16,
+       },
+};
+
+/*
+ * SHA384 HMAC test vectors from RFC4231
+ */
+
+#define HMAC_SHA384_TEST_VECTORS       4
+
+static struct hash_testvec hmac_sha384_tv_template[] = {
+       {
+               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                         "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                         "\x0b\x0b\x0b\x0b",
+               .ksize  = 20,
+               .plaintext = "Hi There",
+               .psize  = 8,
+               .digest = "\xaf\xd0\x39\x44\xd8\x48\x95\x62"
+                         "\x6b\x08\x25\xf4\xab\x46\x90\x7f"
+                         "\x15\xf9\xda\xdb\xe4\x10\x1e\xc6"
+                         "\x82\xaa\x03\x4c\x7c\xeb\xc5\x9c"
+                         "\xfa\xea\x9e\xa9\x07\x6e\xde\x7f"
+                         "\x4a\xf1\x52\xe8\xb2\xfa\x9c\xb6",
+       }, {
+               .key    = "Jefe",
+               .ksize  = 4,
+               .plaintext = "what do ya want for nothing?",
+               .psize  = 28,
+               .digest = "\xaf\x45\xd2\xe3\x76\x48\x40\x31"
+                         "\x61\x7f\x78\xd2\xb5\x8a\x6b\x1b"
+                         "\x9c\x7e\xf4\x64\xf5\xa0\x1b\x47"
+                         "\xe4\x2e\xc3\x73\x63\x22\x44\x5e"
+                         "\x8e\x22\x40\xca\x5e\x69\xe2\xc7"
+                         "\x8b\x32\x39\xec\xfa\xb2\x16\x49",
+               .np     = 4,
+               .tap    = { 7, 7, 7, 7 }
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa",
+               .ksize  = 131,
+               .plaintext = "Test Using Larger Than Block-Siz"
+                          "e Key - Hash Key First",
+               .psize  = 54,
+               .digest = "\x4e\xce\x08\x44\x85\x81\x3e\x90"
+                         "\x88\xd2\xc6\x3a\x04\x1b\xc5\xb4"
+                         "\x4f\x9e\xf1\x01\x2a\x2b\x58\x8f"
+                         "\x3c\xd1\x1f\x05\x03\x3a\xc4\xc6"
+                         "\x0c\x2e\xf6\xab\x40\x30\xfe\x82"
+                         "\x96\x24\x8d\xf1\x63\xf4\x49\x52",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa",
+               .ksize  = 131,
+               .plaintext = "This is a test u"
+                          "sing a larger th"
+                          "an block-size ke"
+                          "y and a larger t"
+                          "han block-size d"
+                          "ata. The key nee"
+                          "ds to be hashed "
+                          "before being use"
+                          "d by the HMAC al"
+                          "gorithm.",
+               .psize  = 152,
+               .digest = "\x66\x17\x17\x8e\x94\x1f\x02\x0d"
+                         "\x35\x1e\x2f\x25\x4e\x8f\xd3\x2c"
+                         "\x60\x24\x20\xfe\xb0\xb8\xfb\x9a"
+                         "\xdc\xce\xbb\x82\x46\x1e\x99\xc5"
+                         "\xa6\x78\xcc\x31\xe7\x99\x17\x6d"
+                         "\x38\x60\xe6\x11\x0c\x46\x52\x3e",
+       },
+};
+
+/*
+ * SHA512 HMAC test vectors from RFC4231
+ */
+
+#define HMAC_SHA512_TEST_VECTORS       4
+
+static struct hash_testvec hmac_sha512_tv_template[] = {
+       {
+               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                         "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                         "\x0b\x0b\x0b\x0b",
+               .ksize  = 20,
+               .plaintext = "Hi There",
+               .psize  = 8,
+               .digest = "\x87\xaa\x7c\xde\xa5\xef\x61\x9d"
+                         "\x4f\xf0\xb4\x24\x1a\x1d\x6c\xb0"
+                         "\x23\x79\xf4\xe2\xce\x4e\xc2\x78"
+                         "\x7a\xd0\xb3\x05\x45\xe1\x7c\xde"
+                         "\xda\xa8\x33\xb7\xd6\xb8\xa7\x02"
+                         "\x03\x8b\x27\x4e\xae\xa3\xf4\xe4"
+                         "\xbe\x9d\x91\x4e\xeb\x61\xf1\x70"
+                         "\x2e\x69\x6c\x20\x3a\x12\x68\x54",
+       }, {
+               .key    = "Jefe",
+               .ksize  = 4,
+               .plaintext = "what do ya want for nothing?",
+               .psize  = 28,
+               .digest = "\x16\x4b\x7a\x7b\xfc\xf8\x19\xe2"
+                         "\xe3\x95\xfb\xe7\x3b\x56\xe0\xa3"
+                         "\x87\xbd\x64\x22\x2e\x83\x1f\xd6"
+                         "\x10\x27\x0c\xd7\xea\x25\x05\x54"
+                         "\x97\x58\xbf\x75\xc0\x5a\x99\x4a"
+                         "\x6d\x03\x4f\x65\xf8\xf0\xe6\xfd"
+                         "\xca\xea\xb1\xa3\x4d\x4a\x6b\x4b"
+                         "\x63\x6e\x07\x0a\x38\xbc\xe7\x37",
+               .np     = 4,
+               .tap    = { 7, 7, 7, 7 }
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa",
+               .ksize  = 131,
+               .plaintext = "Test Using Large"
+                          "r Than Block-Siz"
+                          "e Key - Hash Key"
+                          " First",
+               .psize  = 54,
+               .digest = "\x80\xb2\x42\x63\xc7\xc1\xa3\xeb"
+                       "\xb7\x14\x93\xc1\xdd\x7b\xe8\xb4"
+                       "\x9b\x46\xd1\xf4\x1b\x4a\xee\xc1"
+                       "\x12\x1b\x01\x37\x83\xf8\xf3\x52"
+                       "\x6b\x56\xd0\x37\xe0\x5f\x25\x98"
+                       "\xbd\x0f\xd2\x21\x5d\x6a\x1e\x52"
+                       "\x95\xe6\x4f\x73\xf6\x3f\x0a\xec"
+                       "\x8b\x91\x5a\x98\x5d\x78\x65\x98",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa",
+               .ksize  = 131,
+               .plaintext =
+                         "This is a test u"
+                         "sing a larger th"
+                         "an block-size ke"
+                         "y and a larger t"
+                         "han block-size d"
+                         "ata. The key nee"
+                         "ds to be hashed "
+                         "before being use"
+                         "d by the HMAC al"
+                         "gorithm.",
+               .psize  = 152,
+               .digest = "\xe3\x7b\x6a\x77\x5d\xc8\x7d\xba"
+                       "\xa4\xdf\xa9\xf9\x6e\x5e\x3f\xfd"
+                       "\xde\xbd\x71\xf8\x86\x72\x89\x86"
+                       "\x5d\xf5\xa3\x2d\x20\xcd\xc9\x44"
+                       "\xb6\x02\x2c\xac\x3c\x49\x82\xb1"
+                       "\x0d\x5e\xeb\x55\xc3\xe4\xde\x15"
+                       "\x13\x46\x76\xfb\x6d\xe0\x44\x60"
+                       "\x65\xc9\x74\x40\xfa\x8c\x6a\x58",
+       },
+};
+
+/*
+ * DES test vectors.
+ */
+#if  defined(CONFIG_CRYPTO_DEV_DES) || defined (CONFIG_CRYPTO_ASYNC_DES)
+#define DES_ENC_TEST_VECTORS            5
+#define DES_DEC_TEST_VECTORS            3
+#define DES_CBC_ENC_TEST_VECTORS        4
+#define DES_CBC_DEC_TEST_VECTORS        3
+#define DES3_EDE_ENC_TEST_VECTORS       3
+#define DES3_EDE_DEC_TEST_VECTORS       3
+#define DES3_EDE_CBC_ENC_TEST_VECTORS   1
+#define DES3_EDE_CBC_DEC_TEST_VECTORS   1
+#else
+#define DES_ENC_TEST_VECTORS           10
+#define DES_DEC_TEST_VECTORS           4
+#define DES_CBC_ENC_TEST_VECTORS       5
+#define DES_CBC_DEC_TEST_VECTORS       4
+#define DES3_EDE_ENC_TEST_VECTORS      3
+#define DES3_EDE_DEC_TEST_VECTORS      3
+#define DES3_EDE_CBC_ENC_TEST_VECTORS  1
+#define DES3_EDE_CBC_DEC_TEST_VECTORS  1
+#endif /*CONFIG_CRYPTO_DEV_DES*/
+
+static struct cipher_testvec des_enc_tv_template[] = {
+       { /* From Applied Cryptography */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7",
+               .ilen   = 8,
+               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d",
+               .rlen   = 8,
+       }, { /* Same key, different plaintext block */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x22\x33\x44\x55\x66\x77\x88\x99",
+               .ilen   = 8,
+               .result = "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b",
+               .rlen   = 8,
+       }, { /* Sbox test from NBS */
+               .key    = "\x7c\xa1\x10\x45\x4a\x1a\x6e\x57",
+               .klen   = 8,
+               .input  = "\x01\xa1\xd6\xd0\x39\x77\x67\x42",
+               .ilen   = 8,
+               .result = "\x69\x0f\x5b\x0d\x9a\x26\x93\x9b",
+               .rlen   = 8,
+       }, { /* Three blocks */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+                         "\x22\x33\x44\x55\x66\x77\x88\x99"
+                         "\xca\xfe\xba\xbe\xfe\xed\xbe\xef",
+               .ilen   = 24,
+               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+                         "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b"
+                         "\xb4\x99\x26\xf7\x1f\xe1\xd4\x90",
+               .rlen   = 24,
+//#if  !defined(CONFIG_CRYPTO_DEV_DES) && !defined(CONFIG_CRYPTO_ASYNC_DES)
+#if 0
+       }, { /* Weak key */
+               .fail   = 1,
+               .wk     = 1,
+               .key    = "\x01\x01\x01\x01\x01\x01\x01\x01",
+               .klen   = 8,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7",
+               .ilen   = 8,
+               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d",
+               .rlen   = 8,
+#endif
+       }, { /* Two blocks -- for testing encryption across pages */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+                         "\x22\x33\x44\x55\x66\x77\x88\x99",
+               .ilen   = 16,
+               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+                         "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b",
+               .rlen   = 16,
+               .np     = 2,
+               .tap    = { 8, 8 }
+//#if  !defined(CONFIG_CRYPTO_DEV_DES) && !defined(CONFIG_CRYPTO_ASYNC_DES)
+#if 0
+       }, { /* Four blocks -- for testing encryption with chunking */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+                         "\x22\x33\x44\x55\x66\x77\x88\x99"
+                         "\xca\xfe\xba\xbe\xfe\xed\xbe\xef"
+                         "\x22\x33\x44\x55\x66\x77\x88\x99",
+               .ilen   = 32,
+               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+                         "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b"
+                         "\xb4\x99\x26\xf7\x1f\xe1\xd4\x90"
+                         "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b",
+               .rlen   = 32,
+               .np     = 3,
+               .tap    = { 14, 10, 8 }
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+                         "\x22\x33\x44\x55\x66\x77\x88\x99"
+                         "\xca\xfe\xba\xbe\xfe\xed\xbe\xef",
+               .ilen   = 24,
+               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+                         "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b"
+                         "\xb4\x99\x26\xf7\x1f\xe1\xd4\x90",
+               .rlen   = 24,
+               .np     = 4,
+               .tap    = { 2, 1, 3, 18 }
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+                         "\x22\x33\x44\x55\x66\x77\x88\x99",
+               .ilen   = 16,
+               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+                         "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b",
+               .rlen   = 16,
+               .np     = 5,
+               .tap    = { 2, 2, 2, 2, 8 }
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7",
+               .ilen   = 8,
+               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d",
+               .rlen   = 8,
+               .np     = 8,
+               .tap    = { 1, 1, 1, 1, 1, 1, 1, 1 }
+#endif
+       },
+};
+
+static struct cipher_testvec des_dec_tv_template[] = {
+       { /* From Applied Cryptography */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d",
+               .ilen   = 8,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xe7",
+               .rlen   = 8,
+       }, { /* Sbox test from NBS */
+               .key    = "\x7c\xa1\x10\x45\x4a\x1a\x6e\x57",
+               .klen   = 8,
+               .input  = "\x69\x0f\x5b\x0d\x9a\x26\x93\x9b",
+               .ilen   = 8,
+               .result = "\x01\xa1\xd6\xd0\x39\x77\x67\x42",
+               .rlen   = 8,
+       }, { /* Two blocks, for chunking test */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+                         "\x69\x0f\x5b\x0d\x9a\x26\x93\x9b",
+               .ilen   = 16,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+                         "\xa3\x99\x7b\xca\xaf\x69\xa0\xf5",
+               .rlen   = 16,
+               .np     = 2,
+               .tap    = { 8, 8 }
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+                         "\x69\x0f\x5b\x0d\x9a\x26\x93\x9b",
+               .ilen   = 16,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+                         "\xa3\x99\x7b\xca\xaf\x69\xa0\xf5",
+               .rlen   = 16,
+               .np     = 3,
+               .tap    = { 3, 12, 1 }
+       },
+};
+
+static struct cipher_testvec des_cbc_enc_tv_template[] = {
+       { /* From OpenSSL */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .iv     = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .input  = "\x37\x36\x35\x34\x33\x32\x31\x20"
+                         "\x4e\x6f\x77\x20\x69\x73\x20\x74"
+                         "\x68\x65\x20\x74\x69\x6d\x65\x20",
+               .ilen   = 24,
+               .result = "\xcc\xd1\x73\xff\xab\x20\x39\xf4"
+                         "\xac\xd8\xae\xfd\xdf\xd8\xa1\xeb"
+                         "\x46\x8e\x91\x15\x78\x88\xba\x68",
+               .rlen   = 24,
+       }, { /* FIPS Pub 81 */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .iv     = "\x12\x34\x56\x78\x90\xab\xcd\xef",
+               .input  = "\x4e\x6f\x77\x20\x69\x73\x20\x74",
+               .ilen   = 8,
+               .result = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
+               .rlen   = 8,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .iv     = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
+               .input  = "\x68\x65\x20\x74\x69\x6d\x65\x20",
+               .ilen   = 8,
+               .result = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
+               .rlen   = 8,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .iv     = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
+               .input  = "\x66\x6f\x72\x20\x61\x6c\x6c\x20",
+               .ilen   = 8,
+               .result = "\x68\x37\x88\x49\x9a\x7c\x05\xf6",
+               .rlen   = 8,
+#if 0
+       }, { /* Copy of openssl vector for chunk testing */
+            /* From OpenSSL */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .iv     = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .input  = "\x37\x36\x35\x34\x33\x32\x31\x20"
+                         "\x4e\x6f\x77\x20\x69\x73\x20\x74"
+                         "\x68\x65\x20\x74\x69\x6d\x65\x20",
+               .ilen   = 24,
+               .result = "\xcc\xd1\x73\xff\xab\x20\x39\xf4"
+                         "\xac\xd8\xae\xfd\xdf\xd8\xa1\xeb"
+                         "\x46\x8e\x91\x15\x78\x88\xba\x68",
+               .rlen   = 24,
+               .np     = 2,
+               .tap    = { 13, 11 }
+#endif
+       },
+};
+
+static struct cipher_testvec des_cbc_dec_tv_template[] = {
+       { /* FIPS Pub 81 */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .iv     = "\x12\x34\x56\x78\x90\xab\xcd\xef",
+               .input  = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
+               .ilen   = 8,
+               .result = "\x4e\x6f\x77\x20\x69\x73\x20\x74",
+               .rlen   = 8,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .iv     = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
+               .input  = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
+               .ilen   = 8,
+               .result = "\x68\x65\x20\x74\x69\x6d\x65\x20",
+               .rlen   = 8,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .iv     = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
+               .input  = "\x68\x37\x88\x49\x9a\x7c\x05\xf6",
+               .ilen   = 8,
+               .result = "\x66\x6f\x72\x20\x61\x6c\x6c\x20",
+               .rlen   = 8,
+       }, { /* Copy of above, for chunk testing */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .iv     = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
+               .input  = "\x68\x37\x88\x49\x9a\x7c\x05\xf6",
+               .ilen   = 8,
+               .result = "\x66\x6f\x72\x20\x61\x6c\x6c\x20",
+               .rlen   = 8,
+               .np     = 2,
+               .tap    = { 4, 4 }
+       },
+};
+
+static struct cipher_testvec des3_ede_enc_tv_template[] = {
+       { /* These are from openssl */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\x55\x55\x55\x55\x55\x55\x55\x55"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .klen   = 24,
+               .input  = "\x73\x6f\x6d\x65\x64\x61\x74\x61",
+               .ilen   = 8,
+               .result = "\x18\xd7\x48\xe5\x63\x62\x05\x72",
+               .rlen   = 8,
+       }, {
+               .key    = "\x03\x52\x02\x07\x67\x20\x82\x17"
+                         "\x86\x02\x87\x66\x59\x08\x21\x98"
+                         "\x64\x05\x6a\xbd\xfe\xa9\x34\x57",
+               .klen   = 24,
+               .input  = "\x73\x71\x75\x69\x67\x67\x6c\x65",
+               .ilen   = 8,
+               .result = "\xc0\x7d\x2a\x0f\xa5\x66\xfa\x30",
+               .rlen   = 8,
+       }, {
+               .key    = "\x10\x46\x10\x34\x89\x98\x80\x20"
+                         "\x91\x07\xd0\x15\x89\x19\x01\x01"
+                         "\x19\x07\x92\x10\x98\x1a\x01\x01",
+               .klen   = 24,
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 8,
+               .result = "\xe1\xef\x62\xc3\x32\xfe\x82\x5b",
+               .rlen   = 8,
+       },
+};
+
+static struct cipher_testvec des3_ede_dec_tv_template[] = {
+       { /* These are from openssl */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\x55\x55\x55\x55\x55\x55\x55\x55"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .klen   = 24,
+               .input  = "\x18\xd7\x48\xe5\x63\x62\x05\x72",
+               .ilen   = 8,
+               .result = "\x73\x6f\x6d\x65\x64\x61\x74\x61",
+               .rlen   = 8,
+       }, {
+               .key    = "\x03\x52\x02\x07\x67\x20\x82\x17"
+                         "\x86\x02\x87\x66\x59\x08\x21\x98"
+                         "\x64\x05\x6a\xbd\xfe\xa9\x34\x57",
+               .klen   = 24,
+               .input  = "\xc0\x7d\x2a\x0f\xa5\x66\xfa\x30",
+               .ilen   = 8,
+               .result = "\x73\x71\x75\x69\x67\x67\x6c\x65",
+               .rlen   = 8,
+       }, {
+               .key    = "\x10\x46\x10\x34\x89\x98\x80\x20"
+                         "\x91\x07\xd0\x15\x89\x19\x01\x01"
+                         "\x19\x07\x92\x10\x98\x1a\x01\x01",
+               .klen   = 24,
+               .input  = "\xe1\xef\x62\xc3\x32\xfe\x82\x5b",
+               .ilen   = 8,
+               .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .rlen   = 8,
+       },
+};
+
+static struct cipher_testvec des3_ede_cbc_enc_tv_template[] = {
+       { /* Generated from openssl */
+               .key    = "\xE9\xC0\xFF\x2E\x76\x0B\x64\x24"
+                         "\x44\x4D\x99\x5A\x12\xD6\x40\xC0"
+                         "\xEA\xC2\x84\xE8\x14\x95\xDB\xE8",
+               .klen   = 24,
+               .iv     = "\x7D\x33\x88\x93\x0F\x93\xB2\x42",
+               .input  = "\x6f\x54\x20\x6f\x61\x4d\x79\x6e"
+                         "\x53\x20\x63\x65\x65\x72\x73\x74"
+                         "\x54\x20\x6f\x6f\x4d\x20\x6e\x61"
+                         "\x20\x79\x65\x53\x72\x63\x74\x65"
+                         "\x20\x73\x6f\x54\x20\x6f\x61\x4d"
+                         "\x79\x6e\x53\x20\x63\x65\x65\x72"
+                         "\x73\x74\x54\x20\x6f\x6f\x4d\x20"
+                         "\x6e\x61\x20\x79\x65\x53\x72\x63"
+                         "\x74\x65\x20\x73\x6f\x54\x20\x6f"
+                         "\x61\x4d\x79\x6e\x53\x20\x63\x65"
+                         "\x65\x72\x73\x74\x54\x20\x6f\x6f"
+                         "\x4d\x20\x6e\x61\x20\x79\x65\x53"
+                         "\x72\x63\x74\x65\x20\x73\x6f\x54"
+                         "\x20\x6f\x61\x4d\x79\x6e\x53\x20"
+                         "\x63\x65\x65\x72\x73\x74\x54\x20"
+                         "\x6f\x6f\x4d\x20\x6e\x61\x0a\x79",
+               .ilen   = 128,
+               .result = "\x0e\x2d\xb6\x97\x3c\x56\x33\xf4"
+                         "\x67\x17\x21\xc7\x6e\x8a\xd5\x49"
+                         "\x74\xb3\x49\x05\xc5\x1c\xd0\xed"
+                         "\x12\x56\x5c\x53\x96\xb6\x00\x7d"
+                         "\x90\x48\xfc\xf5\x8d\x29\x39\xcc"
+                         "\x8a\xd5\x35\x18\x36\x23\x4e\xd7"
+                         "\x76\xd1\xda\x0c\x94\x67\xbb\x04"
+                         "\x8b\xf2\x03\x6c\xa8\xcf\xb6\xea"
+                         "\x22\x64\x47\xaa\x8f\x75\x13\xbf"
+                         "\x9f\xc2\xc3\xf0\xc9\x56\xc5\x7a"
+                         "\x71\x63\x2e\x89\x7b\x1e\x12\xca"
+                         "\xe2\x5f\xaf\xd8\xa4\xf8\xc9\x7a"
+                         "\xd6\xf9\x21\x31\x62\x44\x45\xa6"
+                         "\xd6\xbc\x5a\xd3\x2d\x54\x43\xcc"
+                         "\x9d\xde\xa5\x70\xe9\x42\x45\x8a"
+                         "\x6b\xfa\xb1\x91\x13\xb0\xd9\x19",
+               .rlen   = 128,
+       },
+};
+
+static struct cipher_testvec des3_ede_cbc_dec_tv_template[] = {
+       { /* Generated from openssl */
+               .key    = "\xE9\xC0\xFF\x2E\x76\x0B\x64\x24"
+                         "\x44\x4D\x99\x5A\x12\xD6\x40\xC0"
+                         "\xEA\xC2\x84\xE8\x14\x95\xDB\xE8",
+               .klen   = 24,
+               .iv     = "\x7D\x33\x88\x93\x0F\x93\xB2\x42",
+               .input  = "\x0e\x2d\xb6\x97\x3c\x56\x33\xf4"
+                         "\x67\x17\x21\xc7\x6e\x8a\xd5\x49"
+                         "\x74\xb3\x49\x05\xc5\x1c\xd0\xed"
+                         "\x12\x56\x5c\x53\x96\xb6\x00\x7d"
+                         "\x90\x48\xfc\xf5\x8d\x29\x39\xcc"
+                         "\x8a\xd5\x35\x18\x36\x23\x4e\xd7"
+                         "\x76\xd1\xda\x0c\x94\x67\xbb\x04"
+                         "\x8b\xf2\x03\x6c\xa8\xcf\xb6\xea"
+                         "\x22\x64\x47\xaa\x8f\x75\x13\xbf"
+                         "\x9f\xc2\xc3\xf0\xc9\x56\xc5\x7a"
+                         "\x71\x63\x2e\x89\x7b\x1e\x12\xca"
+                         "\xe2\x5f\xaf\xd8\xa4\xf8\xc9\x7a"
+                         "\xd6\xf9\x21\x31\x62\x44\x45\xa6"
+                         "\xd6\xbc\x5a\xd3\x2d\x54\x43\xcc"
+                         "\x9d\xde\xa5\x70\xe9\x42\x45\x8a"
+                         "\x6b\xfa\xb1\x91\x13\xb0\xd9\x19",
+               .ilen   = 128,
+               .result = "\x6f\x54\x20\x6f\x61\x4d\x79\x6e"
+                         "\x53\x20\x63\x65\x65\x72\x73\x74"
+                         "\x54\x20\x6f\x6f\x4d\x20\x6e\x61"
+                         "\x20\x79\x65\x53\x72\x63\x74\x65"
+                         "\x20\x73\x6f\x54\x20\x6f\x61\x4d"
+                         "\x79\x6e\x53\x20\x63\x65\x65\x72"
+                         "\x73\x74\x54\x20\x6f\x6f\x4d\x20"
+                         "\x6e\x61\x20\x79\x65\x53\x72\x63"
+                         "\x74\x65\x20\x73\x6f\x54\x20\x6f"
+                         "\x61\x4d\x79\x6e\x53\x20\x63\x65"
+                         "\x65\x72\x73\x74\x54\x20\x6f\x6f"
+                         "\x4d\x20\x6e\x61\x20\x79\x65\x53"
+                         "\x72\x63\x74\x65\x20\x73\x6f\x54"
+                         "\x20\x6f\x61\x4d\x79\x6e\x53\x20"
+                         "\x63\x65\x65\x72\x73\x74\x54\x20"
+                         "\x6f\x6f\x4d\x20\x6e\x61\x0a\x79",
+               .rlen   = 128,
+       },
+};
+
+/*
+ * Blowfish test vectors.
+ */
+#define BF_ENC_TEST_VECTORS    6
+#define BF_DEC_TEST_VECTORS    6
+#define BF_CBC_ENC_TEST_VECTORS        1
+#define BF_CBC_DEC_TEST_VECTORS        1
+
+static struct cipher_testvec bf_enc_tv_template[] = {
+       { /* DES test vectors from OpenSSL */
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 8,
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 8,
+               .result = "\x4e\xf9\x97\x45\x61\x98\xdd\x78",
+               .rlen   = 8,
+       }, {
+               .key    = "\x1f\x1f\x1f\x1f\x0e\x0e\x0e\x0e",
+               .klen   = 8,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .ilen   = 8,
+               .result = "\xa7\x90\x79\x51\x08\xea\x3c\xae",
+               .rlen   = 8,
+       }, {
+               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+               .klen   = 8,
+               .input  = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .ilen   = 8,
+               .result = "\xe8\x7a\x24\x4e\x2c\xc8\x5e\x82",
+               .rlen   = 8,
+       }, { /* Vary the keylength... */
+               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
+                         "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f",
+               .klen   = 16,
+               .input  = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .ilen   = 8,
+               .result = "\x93\x14\x28\x87\xee\x3b\xe1\x5c",
+               .rlen   = 8,
+       }, {
+               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
+                         "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f"
+                         "\x00\x11\x22\x33\x44",
+               .klen   = 21,
+               .input  = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .ilen   = 8,
+               .result = "\xe6\xf5\x1e\xd7\x9b\x9d\xb2\x1f",
+               .rlen   = 8,
+       }, { /* Generated with bf488 */
+               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
+                         "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f"
+                         "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x04\x68\x91\x04\xc2\xfd\x3b\x2f"
+                         "\x58\x40\x23\x64\x1a\xba\x61\x76"
+                         "\x1f\x1f\x1f\x1f\x0e\x0e\x0e\x0e"
+                         "\xff\xff\xff\xff\xff\xff\xff\xff",
+               .klen   = 56,
+               .input  = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .ilen   = 8,
+               .result = "\xc0\x45\x04\x01\x2e\x4e\x1f\x53",
+               .rlen   = 8,
+       },
+};
+
+static struct cipher_testvec bf_dec_tv_template[] = {
+       { /* DES test vectors from OpenSSL */
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 8,
+               .input  = "\x4e\xf9\x97\x45\x61\x98\xdd\x78",
+               .ilen   = 8,
+               .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .rlen   = 8,
+       }, {
+               .key    = "\x1f\x1f\x1f\x1f\x0e\x0e\x0e\x0e",
+               .klen   = 8,
+               .input  = "\xa7\x90\x79\x51\x08\xea\x3c\xae",
+               .ilen   = 8,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .rlen   = 8,
+       }, {
+               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+               .klen   = 8,
+               .input  = "\xe8\x7a\x24\x4e\x2c\xc8\x5e\x82",
+               .ilen   = 8,
+               .result = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .rlen   = 8,
+       }, { /* Vary the keylength... */
+               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
+                         "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f",
+               .klen   = 16,
+               .input  = "\x93\x14\x28\x87\xee\x3b\xe1\x5c",
+               .ilen   = 8,
+               .result = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .rlen   = 8,
+       }, {
+               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
+                         "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f"
+                         "\x00\x11\x22\x33\x44",
+               .klen   = 21,
+               .input  = "\xe6\xf5\x1e\xd7\x9b\x9d\xb2\x1f",
+               .ilen   = 8,
+               .result = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .rlen   = 8,
+       }, { /* Generated with bf488, using OpenSSL, Libgcrypt and Nettle */
+               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
+                         "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f"
+                         "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x04\x68\x91\x04\xc2\xfd\x3b\x2f"
+                         "\x58\x40\x23\x64\x1a\xba\x61\x76"
+                         "\x1f\x1f\x1f\x1f\x0e\x0e\x0e\x0e"
+                         "\xff\xff\xff\xff\xff\xff\xff\xff",
+               .klen   = 56,
+               .input  = "\xc0\x45\x04\x01\x2e\x4e\x1f\x53",
+               .ilen   = 8,
+               .result = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .rlen   = 8,
+       },
+};
+
+static struct cipher_testvec bf_cbc_enc_tv_template[] = {
+       { /* From OpenSSL */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+               .klen   = 16,
+               .iv     = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .input  = "\x37\x36\x35\x34\x33\x32\x31\x20"
+                         "\x4e\x6f\x77\x20\x69\x73\x20\x74"
+                         "\x68\x65\x20\x74\x69\x6d\x65\x20"
+                         "\x66\x6f\x72\x20\x00\x00\x00\x00",
+               .ilen   = 32,
+               .result = "\x6b\x77\xb4\xd6\x30\x06\xde\xe6"
+                         "\x05\xb1\x56\xe2\x74\x03\x97\x93"
+                         "\x58\xde\xb9\xe7\x15\x46\x16\xd9"
+                         "\x59\xf1\x65\x2b\xd5\xff\x92\xcc",
+               .rlen   = 32,
+       },
+};
+
+static struct cipher_testvec bf_cbc_dec_tv_template[] = {
+       { /* From OpenSSL */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+               .klen   = 16,
+               .iv     = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .input  = "\x6b\x77\xb4\xd6\x30\x06\xde\xe6"
+                         "\x05\xb1\x56\xe2\x74\x03\x97\x93"
+                         "\x58\xde\xb9\xe7\x15\x46\x16\xd9"
+                         "\x59\xf1\x65\x2b\xd5\xff\x92\xcc",
+               .ilen   = 32,
+               .result = "\x37\x36\x35\x34\x33\x32\x31\x20"
+                         "\x4e\x6f\x77\x20\x69\x73\x20\x74"
+                         "\x68\x65\x20\x74\x69\x6d\x65\x20"
+                         "\x66\x6f\x72\x20\x00\x00\x00\x00",
+               .rlen   = 32,
+       },
+};
+
+/*
+ * Twofish test vectors.
+ */
+#define TF_ENC_TEST_VECTORS            3
+#define TF_DEC_TEST_VECTORS            3
+#define TF_CBC_ENC_TEST_VECTORS                4
+#define TF_CBC_DEC_TEST_VECTORS                4
+
+static struct cipher_testvec tf_enc_tv_template[] = {
+       {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
+               .rlen   = 16,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+                         "\x00\x11\x22\x33\x44\x55\x66\x77",
+               .klen   = 24,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\xcf\xd1\xd2\xe5\xa9\xbe\x9c\xdf"
+                         "\x50\x1f\x13\xb8\x92\xbd\x22\x48",
+               .rlen   = 16,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+                         "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               .klen   = 32,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\x37\x52\x7b\xe0\x05\x23\x34\xb8"
+                         "\x9f\x0c\xfc\xca\xe8\x7c\xfa\x20",
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec tf_dec_tv_template[] = {
+       {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+                         "\x00\x11\x22\x33\x44\x55\x66\x77",
+               .klen   = 24,
+               .input  = "\xcf\xd1\xd2\xe5\xa9\xbe\x9c\xdf"
+                         "\x50\x1f\x13\xb8\x92\xbd\x22\x48",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+                         "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               .klen   = 32,
+               .input  = "\x37\x52\x7b\xe0\x05\x23\x34\xb8"
+                         "\x9f\x0c\xfc\xca\xe8\x7c\xfa\x20",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec tf_cbc_enc_tv_template[] = {
+       { /* Generated with Nettle */
+               .key    = zeroed_string,
+               .klen   = 16,
+               .iv     = zeroed_string,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
+               .rlen   = 16,
+       }, {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .iv     = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
+                         "\x86\xcb\x08\x6b\x78\x9f\x54\x19",
+               .rlen   = 16,
+       }, {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .iv     = "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
+                         "\x86\xcb\x08\x6b\x78\x9f\x54\x19",
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\x05\xef\x8c\x61\xa8\x11\x58\x26"
+                         "\x34\xba\x5c\xb7\x10\x6a\xa6\x41",
+               .rlen   = 16,
+       }, {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .iv     = zeroed_string,
+               .input  = zeroed_string,
+               .ilen   = 48,
+               .result = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a"
+                         "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
+                         "\x86\xcb\x08\x6b\x78\x9f\x54\x19"
+                         "\x05\xef\x8c\x61\xa8\x11\x58\x26"
+                         "\x34\xba\x5c\xb7\x10\x6a\xa6\x41",
+               .rlen   = 48,
+       },
+};
+
+static struct cipher_testvec tf_cbc_dec_tv_template[] = {
+       { /* Reverse of the first four above */
+               .key    = zeroed_string,
+               .klen   = 16,
+               .iv     = zeroed_string,
+               .input  = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       }, {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .iv     = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
+               .input  = "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
+                         "\x86\xcb\x08\x6b\x78\x9f\x54\x19",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       }, {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .iv     = "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
+                         "\x86\xcb\x08\x6b\x78\x9f\x54\x19",
+               .input  = "\x05\xef\x8c\x61\xa8\x11\x58\x26"
+                         "\x34\xba\x5c\xb7\x10\x6a\xa6\x41",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       }, {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .iv     = zeroed_string,
+               .input  = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a"
+                         "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
+                         "\x86\xcb\x08\x6b\x78\x9f\x54\x19"
+                         "\x05\xef\x8c\x61\xa8\x11\x58\x26"
+                         "\x34\xba\x5c\xb7\x10\x6a\xa6\x41",
+               .ilen   = 48,
+               .result = zeroed_string,
+               .rlen   = 48,
+       },
+};
+
+/*
+ * Serpent test vectors.  These are backwards because Serpent writes
+ * octet sequences in right-to-left mode.
+ */
+#define SERPENT_ENC_TEST_VECTORS       4
+#define SERPENT_DEC_TEST_VECTORS       4
+
+#define TNEPRES_ENC_TEST_VECTORS       4
+#define TNEPRES_DEC_TEST_VECTORS       4
+
+static struct cipher_testvec serpent_enc_tv_template[] = {
+       {
+               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .ilen   = 16,
+               .result = "\x12\x07\xfc\xce\x9b\xd0\xd6\x47"
+                         "\x6a\xe9\x8f\xbe\xd1\x43\xa0\xe2",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .klen   = 16,
+               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .ilen   = 16,
+               .result = "\x4c\x7d\x8a\x32\x80\x72\xa2\x2c"
+                         "\x82\x3e\x4a\x1f\x3a\xcd\xa1\x6d",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .klen   = 32,
+               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .ilen   = 16,
+               .result = "\xde\x26\x9f\xf8\x33\xe4\x32\xb8"
+                         "\x5b\x2e\x88\xd2\x70\x1c\xe7\x5c",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80",
+               .klen   = 16,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\xdd\xd2\x6b\x98\xa5\xff\xd8\x2c"
+                         "\x05\x34\x5a\x9d\xad\xbf\xaf\x49",
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec tnepres_enc_tv_template[] = {
+       { /* KeySize=128, PT=0, I=1 */
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .key    = "\x80\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 16,
+               .ilen   = 16,
+               .result = "\x49\xaf\xbf\xad\x9d\x5a\x34\x05"
+                         "\x2c\xd8\xff\xa5\x98\x6b\xd2\xdd",
+               .rlen   = 16,
+       }, { /* KeySize=192, PT=0, I=1 */
+               .key    = "\x80\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 24,
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 16,
+               .result = "\xe7\x8e\x54\x02\xc7\x19\x55\x68"
+                         "\xac\x36\x78\xf7\xa3\xf6\x0c\x66",
+               .rlen   = 16,
+       }, { /* KeySize=256, PT=0, I=1 */
+               .key    = "\x80\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 32,
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 16,
+               .result = "\xab\xed\x96\xe7\x66\xbf\x28\xcb"
+                         "\xc0\xeb\xd2\x1a\x82\xef\x08\x19",
+               .rlen   = 16,
+       }, { /* KeySize=256, I=257 */
+               .key    = "\x1f\x1e\x1d\x1c\x1b\x1a\x19\x18"
+                         "\x17\x16\x15\x14\x13\x12\x11\x10"
+                         "\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08"
+                         "\x07\x06\x05\x04\x03\x02\x01\x00",
+               .klen   = 32,
+               .input  = "\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08"
+                         "\x07\x06\x05\x04\x03\x02\x01\x00",
+               .ilen   = 16,
+               .result = "\x5c\xe7\x1c\x70\xd2\x88\x2e\x5b"
+                         "\xb8\x32\xe4\x33\xf8\x9f\x26\xde",
+               .rlen   = 16,
+       },
+};
+
+
+static struct cipher_testvec serpent_dec_tv_template[] = {
+       {
+               .input  = "\x12\x07\xfc\xce\x9b\xd0\xd6\x47"
+                         "\x6a\xe9\x8f\xbe\xd1\x43\xa0\xe2",
+               .ilen   = 16,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .klen   = 16,
+               .input  = "\x4c\x7d\x8a\x32\x80\x72\xa2\x2c"
+                         "\x82\x3e\x4a\x1f\x3a\xcd\xa1\x6d",
+               .ilen   = 16,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .klen   = 32,
+               .input  = "\xde\x26\x9f\xf8\x33\xe4\x32\xb8"
+                         "\x5b\x2e\x88\xd2\x70\x1c\xe7\x5c",
+               .ilen   = 16,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80",
+               .klen   = 16,
+               .input  = "\xdd\xd2\x6b\x98\xa5\xff\xd8\x2c"
+                         "\x05\x34\x5a\x9d\xad\xbf\xaf\x49",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec tnepres_dec_tv_template[] = {
+       {
+               .input  = "\x41\xcc\x6b\x31\x59\x31\x45\x97"
+                         "\x6d\x6f\xbb\x38\x4b\x37\x21\x28",
+               .ilen   = 16,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .klen   = 16,
+               .input  = "\xea\xf4\xd7\xfc\xd8\x01\x34\x47"
+                         "\x81\x45\x0b\xfa\x0c\xd6\xad\x6e",
+               .ilen   = 16,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .klen   = 32,
+               .input  = "\x64\xa9\x1a\x37\xed\x9f\xe7\x49"
+                         "\xa8\x4e\x76\xd6\xf5\x0d\x78\xee",
+               .ilen   = 16,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .rlen   = 16,
+       }, { /* KeySize=128, I=121 */
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80",
+               .klen   = 16,
+               .input  = "\x3d\xda\xbf\xc0\x06\xda\xab\x06"
+                         "\x46\x2a\xf4\xef\x81\x54\x4e\x26",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       },
+};
+
+
+/* Cast6 test vectors from RFC 2612 */
+#define CAST6_ENC_TEST_VECTORS 3
+#define CAST6_DEC_TEST_VECTORS  3
+
+static struct cipher_testvec cast6_enc_tv_template[] = {
+       {
+               .key    = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
+                         "\x0a\xf7\x56\x47\xf2\x9f\x61\x5d",
+               .klen   = 16,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\xc8\x42\xa0\x89\x72\xb4\x3d\x20"
+                         "\x83\x6c\x91\xd1\xb7\x53\x0f\x6b",
+               .rlen   = 16,
+       }, {
+               .key    = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
+                         "\xbe\xd0\xac\x83\x94\x0a\xc2\x98"
+                         "\xba\xc7\x7a\x77\x17\x94\x28\x63",
+               .klen   = 24,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\x1b\x38\x6c\x02\x10\xdc\xad\xcb"
+                         "\xdd\x0e\x41\xaa\x08\xa7\xa7\xe8",
+               .rlen   = 16,
+       }, {
+               .key    = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
+                         "\xbe\xd0\xac\x83\x94\x0a\xc2\x98"
+                         "\x8d\x7c\x47\xce\x26\x49\x08\x46"
+                         "\x1c\xc1\xb5\x13\x7a\xe6\xb6\x04",
+               .klen   = 32,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\x4f\x6a\x20\x38\x28\x68\x97\xb9"
+                         "\xc9\x87\x01\x36\x55\x33\x17\xfa",
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec cast6_dec_tv_template[] = {
+       {
+               .key    = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
+                         "\x0a\xf7\x56\x47\xf2\x9f\x61\x5d",
+               .klen   = 16,
+               .input  = "\xc8\x42\xa0\x89\x72\xb4\x3d\x20"
+                         "\x83\x6c\x91\xd1\xb7\x53\x0f\x6b",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       }, {
+               .key    = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
+                         "\xbe\xd0\xac\x83\x94\x0a\xc2\x98"
+                         "\xba\xc7\x7a\x77\x17\x94\x28\x63",
+               .klen   = 24,
+               .input  = "\x1b\x38\x6c\x02\x10\xdc\xad\xcb"
+                         "\xdd\x0e\x41\xaa\x08\xa7\xa7\xe8",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       }, {
+               .key    = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
+                         "\xbe\xd0\xac\x83\x94\x0a\xc2\x98"
+                         "\x8d\x7c\x47\xce\x26\x49\x08\x46"
+                         "\x1c\xc1\xb5\x13\x7a\xe6\xb6\x04",
+               .klen   = 32,
+               .input  = "\x4f\x6a\x20\x38\x28\x68\x97\xb9"
+                         "\xc9\x87\x01\x36\x55\x33\x17\xfa",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       },
+};
+
+
+/*
+ * AES test vectors.
+ */
+#if !defined(CONFIG_CRYPTO_DEV_AES) && !defined(CONFIG_CRYPTO_ASYNC_AES)
+#define AES_ENC_TEST_VECTORS 3
+#define AES_DEC_TEST_VECTORS 3
+#define AES_CBC_ENC_TEST_VECTORS 4
+#define AES_CBC_DEC_TEST_VECTORS 4
+#define AES_LRW_ENC_TEST_VECTORS 8
+#define AES_LRW_DEC_TEST_VECTORS 8
+#define AES_XTS_ENC_TEST_VECTORS 4
+#define AES_XTS_DEC_TEST_VECTORS 4
+#define AES_CTR_ENC_TEST_VECTORS 3
+#define AES_CTR_DEC_TEST_VECTORS 3
+#define AES_CTR_3686_ENC_TEST_VECTORS 7
+#define AES_CTR_3686_DEC_TEST_VECTORS 6
+#define AES_GCM_ENC_TEST_VECTORS 9
+#define AES_GCM_DEC_TEST_VECTORS 8
+#define AES_CCM_ENC_TEST_VECTORS 7
+#define AES_CCM_DEC_TEST_VECTORS 7
+#define AES_CCM_4309_ENC_TEST_VECTORS 7
+#define AES_CCM_4309_DEC_TEST_VECTORS 10
+#else
+#define AES_ENC_TEST_VECTORS 3
+#define AES_DEC_TEST_VECTORS 3
+#define AES_CBC_ENC_TEST_VECTORS 3
+#define AES_CBC_DEC_TEST_VECTORS 3
+#define AES_CTR_ENC_TEST_VECTORS 3
+#define AES_CTR_DEC_TEST_VECTORS 3
+#define AES_GCM_ENC_TEST_VECTORS 9
+#define AES_GCM_DEC_TEST_VECTORS 8
+#define AES_CCM_ENC_TEST_VECTORS 7
+#define AES_CCM_DEC_TEST_VECTORS 7
+#define AES_CCM_4309_ENC_TEST_VECTORS 7
+#define AES_CCM_4309_DEC_TEST_VECTORS 10
+#define AES_CTR_3686_ENC_TEST_VECTORS 6
+#define AES_CTR_3686_DEC_TEST_VECTORS 6
+#endif /* CONFIG_CRYPTO_DEV_AES */
+
+static struct cipher_testvec aes_enc_tv_template[] = {
+       { /* From FIPS-197 */
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .klen   = 16,
+               .input  = "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               .ilen   = 16,
+               .result = "\x69\xc4\xe0\xd8\x6a\x7b\x04\x30"
+                         "\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17",
+               .klen   = 24,
+               .input  = "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               .ilen   = 16,
+               .result = "\xdd\xa9\x7c\xa4\x86\x4c\xdf\xe0"
+                         "\x6e\xaf\x70\xa0\xec\x0d\x71\x91",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .klen   = 32,
+               .input  = "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               .ilen   = 16,
+               .result = "\x8e\xa2\xb7\xca\x51\x67\x45\xbf"
+                         "\xea\xfc\x49\x90\x4b\x49\x60\x89",
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec aes_dec_tv_template[] = {
+       { /* From FIPS-197 */
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .klen   = 16,
+               .input  = "\x69\xc4\xe0\xd8\x6a\x7b\x04\x30"
+                         "\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a",
+               .ilen   = 16,
+               .result = "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17",
+               .klen   = 24,
+               .input  = "\xdd\xa9\x7c\xa4\x86\x4c\xdf\xe0"
+                         "\x6e\xaf\x70\xa0\xec\x0d\x71\x91",
+               .ilen   = 16,
+               .result = "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .klen   = 32,
+               .input  = "\x8e\xa2\xb7\xca\x51\x67\x45\xbf"
+                         "\xea\xfc\x49\x90\x4b\x49\x60\x89",
+               .ilen   = 16,
+               .result = "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec aes_cbc_enc_tv_template[] = {
+       { /* From RFC 3602 */
+               .key    = "\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
+                         "\x51\x2e\x03\xd5\x34\x12\x00\x06",
+               .klen   = 16,
+               .iv     = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
+                         "\xb4\x22\xda\x80\x2c\x9f\xac\x41",
+               .input  = "Single block msg",
+               .ilen   = 16,
+               .result = "\xe3\x53\x77\x9c\x10\x79\xae\xb8"
+                         "\x27\x08\x94\x2d\xbe\x77\x18\x1a",
+               .rlen   = 16,
+       }, {
+               .key    = "\xc2\x86\x69\x6d\x88\x7c\x9a\xa0"
+                         "\x61\x1b\xbb\x3e\x20\x25\xa4\x5a",
+               .klen   = 16,
+               .iv     = "\x56\x2e\x17\x99\x6d\x09\x3d\x28"
+                         "\xdd\xb3\xba\x69\x5a\x2e\x6f\x58",
+               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .ilen   = 32,
+               .result = "\xd2\x96\xcd\x94\xc2\xcc\xcf\x8a"
+                         "\x3a\x86\x30\x28\xb5\xe1\xdc\x0a"
+                         "\x75\x86\x60\x2d\x25\x3c\xff\xf9"
+                         "\x1b\x82\x66\xbe\xa6\xd6\x1a\xb1",
+               .rlen   = 32,
+       }, { /* From NIST SP800-38A */
+               .key    = "\x8e\x73\xb0\xf7\xda\x0e\x64\x52"
+                         "\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
+                         "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+               .klen   = 24,
+               .iv     = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .input  = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+               .ilen   = 64,
+               .result = "\x4f\x02\x1d\xb2\x43\xbc\x63\x3d"
+                         "\x71\x78\x18\x3a\x9f\xa0\x71\xe8"
+                         "\xb4\xd9\xad\xa9\xad\x7d\xed\xf4"
+                         "\xe5\xe7\x38\x76\x3f\x69\x14\x5a"
+                         "\x57\x1b\x24\x20\x12\xfb\x7a\xe0"
+                         "\x7f\xa9\xba\xac\x3d\xf1\x02\xe0"
+                         "\x08\xb0\xe2\x79\x88\x59\x88\x81"
+                         "\xd9\x20\xa9\xe6\x4f\x56\x15\xcd",
+               .rlen   = 64,
+#if !defined(CONFIG_CRYPTO_DEV_AES) && !defined(CONFIG_CRYPTO_ASYNC_AES)
+       }, {
+               .key    = "\x60\x3d\xeb\x10\x15\xca\x71\xbe"
+                         "\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+                         "\x1f\x35\x2c\x07\x3b\x61\x08\xd7"
+                         "\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+               .klen   = 32,
+               .iv     = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .input  = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+               .ilen   = 64,
+               .result = "\xf5\x8c\x4c\x04\xd6\xe5\xf1\xba"
+                         "\x77\x9e\xab\xfb\x5f\x7b\xfb\xd6"
+                         "\x9c\xfc\x4e\x96\x7e\xdb\x80\x8d"
+                         "\x67\x9f\x77\x7b\xc6\x70\x2c\x7d"
+                         "\x39\xf2\x33\x69\xa9\xd9\xba\xcf"
+                         "\xa5\x30\xe2\x63\x04\x23\x14\x61"
+                         "\xb2\xeb\x05\xe2\xc3\x9b\xe9\xfc"
+                         "\xda\x6c\x19\x07\x8c\x6a\x9d\x1b",
+               .rlen   = 64,
+#endif
+       },
+};
+
+static struct cipher_testvec aes_cbc_dec_tv_template[] = {
+       { /* From RFC 3602 */
+               .key    = "\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
+                         "\x51\x2e\x03\xd5\x34\x12\x00\x06",
+               .klen   = 16,
+               .iv     = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
+                         "\xb4\x22\xda\x80\x2c\x9f\xac\x41",
+               .input  = "\xe3\x53\x77\x9c\x10\x79\xae\xb8"
+                         "\x27\x08\x94\x2d\xbe\x77\x18\x1a",
+               .ilen   = 16,
+               .result = "Single block msg",
+               .rlen   = 16,
+       }, {
+               .key    = "\xc2\x86\x69\x6d\x88\x7c\x9a\xa0"
+                         "\x61\x1b\xbb\x3e\x20\x25\xa4\x5a",
+               .klen   = 16,
+               .iv     = "\x56\x2e\x17\x99\x6d\x09\x3d\x28"
+                         "\xdd\xb3\xba\x69\x5a\x2e\x6f\x58",
+               .input  = "\xd2\x96\xcd\x94\xc2\xcc\xcf\x8a"
+                         "\x3a\x86\x30\x28\xb5\xe1\xdc\x0a"
+                         "\x75\x86\x60\x2d\x25\x3c\xff\xf9"
+                         "\x1b\x82\x66\xbe\xa6\xd6\x1a\xb1",
+               .ilen   = 32,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .rlen   = 32,
+       }, { /* From NIST SP800-38A */
+               .key    = "\x8e\x73\xb0\xf7\xda\x0e\x64\x52"
+                         "\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
+                         "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+               .klen   = 24,
+               .iv     = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .input  = "\x4f\x02\x1d\xb2\x43\xbc\x63\x3d"
+                         "\x71\x78\x18\x3a\x9f\xa0\x71\xe8"
+                         "\xb4\xd9\xad\xa9\xad\x7d\xed\xf4"
+                         "\xe5\xe7\x38\x76\x3f\x69\x14\x5a"
+                         "\x57\x1b\x24\x20\x12\xfb\x7a\xe0"
+                         "\x7f\xa9\xba\xac\x3d\xf1\x02\xe0"
+                         "\x08\xb0\xe2\x79\x88\x59\x88\x81"
+                         "\xd9\x20\xa9\xe6\x4f\x56\x15\xcd",
+               .ilen   = 64,
+               .result = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+               .rlen   = 64,
+#if !defined(CONFIG_CRYPTO_DEV_AES) && !defined(CONFIG_CRYPTO_ASYNC_AES)
+       }, {
+               .key    = "\x60\x3d\xeb\x10\x15\xca\x71\xbe"
+                         "\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+                         "\x1f\x35\x2c\x07\x3b\x61\x08\xd7"
+                         "\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+               .klen   = 32,
+               .iv     = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .input  = "\xf5\x8c\x4c\x04\xd6\xe5\xf1\xba"
+                         "\x77\x9e\xab\xfb\x5f\x7b\xfb\xd6"
+                         "\x9c\xfc\x4e\x96\x7e\xdb\x80\x8d"
+                         "\x67\x9f\x77\x7b\xc6\x70\x2c\x7d"
+                         "\x39\xf2\x33\x69\xa9\xd9\xba\xcf"
+                         "\xa5\x30\xe2\x63\x04\x23\x14\x61"
+                         "\xb2\xeb\x05\xe2\xc3\x9b\xe9\xfc"
+                         "\xda\x6c\x19\x07\x8c\x6a\x9d\x1b",
+               .ilen   = 64,
+               .result = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+               .rlen   = 64,
+#endif
+       },
+};
+
+#if !defined(CONFIG_CRYPTO_DEV_AES) && !defined(CONFIG_CRYPTO_ASYNC_AES)
+
+static struct cipher_testvec aes_lrw_enc_tv_template[] = {
+       /* from http://grouper.ieee.org/groups/1619/email/pdf00017.pdf */
+       { /* LRW-32-AES 1 */
+               .key    = "\x45\x62\xac\x25\xf8\x28\x17\x6d"
+                         "\x4c\x26\x84\x14\xb5\x68\x01\x85"
+                         "\x25\x8e\x2a\x05\xe7\x3e\x9d\x03"
+                         "\xee\x5a\x83\x0c\xcc\x09\x4c\x87",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x01",
+               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .ilen   = 16,
+               .result = "\xf1\xb2\x73\xcd\x65\xa3\xdf\x5f"
+                         "\xe9\x5d\x48\x92\x54\x63\x4e\xb8",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 2 */
+               .key    = "\x59\x70\x47\x14\xf5\x57\x47\x8c"
+                         "\xd7\x79\xe8\x0f\x54\x88\x79\x44"
+                         "\x0d\x48\xf0\xb7\xb1\x5a\x53\xea"
+                         "\x1c\xaa\x6b\x29\xc2\xca\xfb\xaf",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x02",
+               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .ilen   = 16,
+               .result = "\x00\xc8\x2b\xae\x95\xbb\xcd\xe5"
+                         "\x27\x4f\x07\x69\xb2\x60\xe1\x36",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 3 */
+               .key    = "\xd8\x2a\x91\x34\xb2\x6a\x56\x50"
+                         "\x30\xfe\x69\xe2\x37\x7f\x98\x47"
+                         "\xcd\xf9\x0b\x16\x0c\x64\x8f\xb6"
+                         "\xb0\x0d\x0d\x1b\xae\x85\x87\x1f",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x02\x00\x00\x00\x00",
+               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .ilen   = 16,
+               .result = "\x76\x32\x21\x83\xed\x8f\xf1\x82"
+                         "\xf9\x59\x62\x03\x69\x0e\x5e\x01",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 4 */
+               .key    = "\x0f\x6a\xef\xf8\xd3\xd2\xbb\x15"
+                         "\x25\x83\xf7\x3c\x1f\x01\x28\x74"
+                         "\xca\xc6\xbc\x35\x4d\x4a\x65\x54"
+                         "\x90\xae\x61\xcf\x7b\xae\xbd\xcc"
+                         "\xad\xe4\x94\xc5\x4a\x29\xae\x70",
+               .klen   = 40,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x01",
+               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .ilen   = 16,
+               .result = "\x9c\x0f\x15\x2f\x55\xa2\xd8\xf0"
+                         "\xd6\x7b\x8f\x9e\x28\x22\xbc\x41",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 5 */
+               .key    = "\x8a\xd4\xee\x10\x2f\xbd\x81\xff"
+                         "\xf8\x86\xce\xac\x93\xc5\xad\xc6"
+                         "\xa0\x19\x07\xc0\x9d\xf7\xbb\xdd"
+                         "\x52\x13\xb2\xb7\xf0\xff\x11\xd8"
+                         "\xd6\x08\xd0\xcd\x2e\xb1\x17\x6f",
+               .klen   = 40,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x02\x00\x00\x00\x00",
+               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .ilen   = 16,
+               .result = "\xd4\x27\x6a\x7f\x14\x91\x3d\x65"
+                         "\xc8\x60\x48\x02\x87\xe3\x34\x06",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 6 */
+               .key    = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+                         "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+                         "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+                         "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+                         "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+                         "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+               .klen   = 48,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x01",
+               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .ilen   = 16,
+               .result = "\xbd\x06\xb8\xe1\xdb\x98\x89\x9e"
+                         "\xc4\x98\xe4\x91\xcf\x1c\x70\x2b",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 7 */
+               .key    = "\xfb\x76\x15\xb2\x3d\x80\x89\x1d"
+                         "\xd4\x70\x98\x0b\xc7\x95\x84\xc8"
+                         "\xb2\xfb\x64\xce\x60\x97\x87\x8d"
+                         "\x17\xfc\xe4\x5a\x49\xe8\x30\xb7"
+                         "\x6e\x78\x17\xe7\x2d\x5e\x12\xd4"
+                         "\x60\x64\x04\x7a\xf1\x2f\x9e\x0c",
+               .klen   = 48,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x02\x00\x00\x00\x00",
+               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .ilen   = 16,
+               .result = "\x5b\x90\x8e\xc1\xab\xdd\x67\x5f"
+                         "\x3d\x69\x8a\x95\x53\xc8\x9c\xe5",
+               .rlen   = 16,
+       }, {
+/* http://www.mail-archive.com/stds-p1619@listserv.ieee.org/msg00173.html */
+               .key    = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+                         "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+                         "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+                         "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+                         "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+                         "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+               .klen   = 48,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x01",
+               .input  = "\x05\x11\xb7\x18\xab\xc6\x2d\xac"
+                         "\x70\x5d\xf6\x22\x94\xcd\xe5\x6c"
+                         "\x17\x6b\xf6\x1c\xf0\xf3\x6e\xf8"
+                         "\x50\x38\x1f\x71\x49\xb6\x57\xd6"
+                         "\x8f\xcb\x8d\x6b\xe3\xa6\x29\x90"
+                         "\xfe\x2a\x62\x82\xae\x6d\x8b\xf6"
+                         "\xad\x1e\x9e\x20\x5f\x38\xbe\x04"
+                         "\xda\x10\x8e\xed\xa2\xa4\x87\xab"
+                         "\xda\x6b\xb4\x0c\x75\xba\xd3\x7c"
+                         "\xc9\xac\x42\x31\x95\x7c\xc9\x04"
+                         "\xeb\xd5\x6e\x32\x69\x8a\xdb\xa6"
+                         "\x15\xd7\x3f\x4f\x2f\x66\x69\x03"
+                         "\x9c\x1f\x54\x0f\xde\x1f\xf3\x65"
+                         "\x4c\x96\x12\xed\x7c\x92\x03\x01"
+                         "\x6f\xbc\x35\x93\xac\xf1\x27\xf1"
+                         "\xb4\x96\x82\x5a\x5f\xb0\xa0\x50"
+                         "\x89\xa4\x8e\x66\x44\x85\xcc\xfd"
+                         "\x33\x14\x70\xe3\x96\xb2\xc3\xd3"
+                         "\xbb\x54\x5a\x1a\xf9\x74\xa2\xc5"
+                         "\x2d\x64\x75\xdd\xb4\x54\xe6\x74"
+                         "\x8c\xd3\x9d\x9e\x86\xab\x51\x53"
+                         "\xb7\x93\x3e\x6f\xd0\x4e\x2c\x40"
+                         "\xf6\xa8\x2e\x3e\x9d\xf4\x66\xa5"
+                         "\x76\x12\x73\x44\x1a\x56\xd7\x72"
+                         "\x88\xcd\x21\x8c\x4c\x0f\xfe\xda"
+                         "\x95\xe0\x3a\xa6\xa5\x84\x46\xcd"
+                         "\xd5\x3e\x9d\x3a\xe2\x67\xe6\x60"
+                         "\x1a\xe2\x70\x85\x58\xc2\x1b\x09"
+                         "\xe1\xd7\x2c\xca\xad\xa8\x8f\xf9"
+                         "\xac\xb3\x0e\xdb\xca\x2e\xe2\xb8"
+                         "\x51\x71\xd9\x3c\x6c\xf1\x56\xf8"
+                         "\xea\x9c\xf1\xfb\x0c\xe6\xb7\x10"
+                         "\x1c\xf8\xa9\x7c\xe8\x53\x35\xc1"
+                         "\x90\x3e\x76\x4a\x74\xa4\x21\x2c"
+                         "\xf6\x2c\x4e\x0f\x94\x3a\x88\x2e"
+                         "\x41\x09\x6a\x33\x7d\xf6\xdd\x3f"
+                         "\x8d\x23\x31\x74\x84\xeb\x88\x6e"
+                         "\xcc\xb9\xbc\x22\x83\x19\x07\x22"
+                         "\xa5\x2d\xdf\xa5\xf3\x80\x85\x78"
+                         "\x84\x39\x6a\x6d\x6a\x99\x4f\xa5"
+                         "\x15\xfe\x46\xb0\xe4\x6c\xa5\x41"
+                         "\x3c\xce\x8f\x42\x60\x71\xa7\x75"
+                         "\x08\x40\x65\x8a\x82\xbf\xf5\x43"
+                         "\x71\x96\xa9\x4d\x44\x8a\x20\xbe"
+                         "\xfa\x4d\xbb\xc0\x7d\x31\x96\x65"
+                         "\xe7\x75\xe5\x3e\xfd\x92\x3b\xc9"
+                         "\x55\xbb\x16\x7e\xf7\xc2\x8c\xa4"
+                         "\x40\x1d\xe5\xef\x0e\xdf\xe4\x9a"
+                         "\x62\x73\x65\xfd\x46\x63\x25\x3d"
+                         "\x2b\xaf\xe5\x64\xfe\xa5\x5c\xcf"
+                         "\x24\xf3\xb4\xac\x64\xba\xdf\x4b"
+                         "\xc6\x96\x7d\x81\x2d\x8d\x97\xf7"
+                         "\xc5\x68\x77\x84\x32\x2b\xcc\x85"
+                         "\x74\x96\xf0\x12\x77\x61\xb9\xeb"
+                         "\x71\xaa\x82\xcb\x1c\xdb\x89\xc8"
+                         "\xc6\xb5\xe3\x5c\x7d\x39\x07\x24"
+                         "\xda\x39\x87\x45\xc0\x2b\xbb\x01"
+                         "\xac\xbc\x2a\x5c\x7f\xfc\xe8\xce"
+                         "\x6d\x9c\x6f\xed\xd3\xc1\xa1\xd6"
+                         "\xc5\x55\xa9\x66\x2f\xe1\xc8\x32"
+                         "\xa6\x5d\xa4\x3a\x98\x73\xe8\x45"
+                         "\xa4\xc7\xa8\xb4\xf6\x13\x03\xf6"
+                         "\xe9\x2e\xc4\x29\x0f\x84\xdb\xc4"
+                         "\x21\xc4\xc2\x75\x67\x89\x37\x0a",
+               .ilen   = 512,
+               .result = "\x1a\x1d\xa9\x30\xad\xf9\x2f\x9b"
+                         "\xb6\x1d\xae\xef\xf0\x2f\xf8\x5a"
+                         "\x39\x3c\xbf\x2a\xb2\x45\xb2\x23"
+                         "\x1b\x63\x3c\xcf\xaa\xbe\xcf\x4e"
+                         "\xfa\xe8\x29\xc2\x20\x68\x2b\x3c"
+                         "\x2e\x8b\xf7\x6e\x25\xbd\xe3\x3d"
+                         "\x66\x27\xd6\xaf\xd6\x64\x3e\xe3"
+                         "\xe8\x58\x46\x97\x39\x51\x07\xde"
+                         "\xcb\x37\xbc\xa9\xc0\x5f\x75\xc3"
+                         "\x0e\x84\x23\x1d\x16\xd4\x1c\x59"
+                         "\x9c\x1a\x02\x55\xab\x3a\x97\x1d"
+                         "\xdf\xdd\xc7\x06\x51\xd7\x70\xae"
+                         "\x23\xc6\x8c\xf5\x1e\xa0\xe5\x82"
+                         "\xb8\xb2\xbf\x04\xa0\x32\x8e\x68"
+                         "\xeb\xaf\x6e\x2d\x94\x22\x2f\xce"
+                         "\x4c\xb5\x59\xe2\xa2\x2f\xa0\x98"
+                         "\x1a\x97\xc6\xd4\xb5\x00\x59\xf2"
+                         "\x84\x14\x72\xb1\x9a\x6e\xa3\x7f"
+                         "\xea\x20\xe7\xcb\x65\x77\x3a\xdf"
+                         "\xc8\x97\x67\x15\xc2\x2a\x27\xcc"
+                         "\x18\x55\xa1\x24\x0b\x24\x24\xaf"
+                         "\x5b\xec\x68\xb8\xc8\xf5\xba\x63"
+                         "\xff\xed\x89\xce\xd5\x3d\x88\xf3"
+                         "\x25\xef\x05\x7c\x3a\xef\xeb\xd8"
+                         "\x7a\x32\x0d\xd1\x1e\x58\x59\x99"
+                         "\x90\x25\xb5\x26\xb0\xe3\x2b\x6c"
+                         "\x4c\xa9\x8b\x84\x4f\x5e\x01\x50"
+                         "\x41\x30\x58\xc5\x62\x74\x52\x1d"
+                         "\x45\x24\x6a\x42\x64\x4f\x97\x1c"
+                         "\xa8\x66\xb5\x6d\x79\xd4\x0d\x48"
+                         "\xc5\x5f\xf3\x90\x32\xdd\xdd\xe1"
+                         "\xe4\xa9\x9f\xfc\xc3\x52\x5a\x46"
+                         "\xe4\x81\x84\x95\x36\x59\x7a\x6b"
+                         "\xaa\xb3\x60\xad\xce\x9f\x9f\x28"
+                         "\xe0\x01\x75\x22\xc4\x4e\xa9\x62"
+                         "\x5c\x62\x0d\x00\xcb\x13\xe8\x43"
+                         "\x72\xd4\x2d\x53\x46\xb5\xd1\x16"
+                         "\x22\x18\xdf\x34\x33\xf5\xd6\x1c"
+                         "\xb8\x79\x78\x97\x94\xff\x72\x13"
+                         "\x4c\x27\xfc\xcb\xbf\x01\x53\xa6"
+                         "\xb4\x50\x6e\xde\xdf\xb5\x43\xa4"
+                         "\x59\xdf\x52\xf9\x7c\xe0\x11\x6f"
+                         "\x2d\x14\x8e\x24\x61\x2c\xe1\x17"
+                         "\xcc\xce\x51\x0c\x19\x8a\x82\x30"
+                         "\x94\xd5\x3d\x6a\x53\x06\x5e\xbd"
+                         "\xb7\xeb\xfa\xfd\x27\x51\xde\x85"
+                         "\x1e\x86\x53\x11\x53\x94\x00\xee"
+                         "\x2b\x8c\x08\x2a\xbf\xdd\xae\x11"
+                         "\xcb\x1e\xa2\x07\x9a\x80\xcf\x62"
+                         "\x9b\x09\xdc\x95\x3c\x96\x8e\xb1"
+                         "\x09\xbd\xe4\xeb\xdb\xca\x70\x7a"
+                         "\x9e\xfa\x31\x18\x45\x3c\x21\x33"
+                         "\xb0\xb3\x2b\xea\xf3\x71\x2d\xe1"
+                         "\x03\xad\x1b\x48\xd4\x67\x27\xf0"
+                         "\x62\xe4\x3d\xfb\x9b\x08\x76\xe7"
+                         "\xdd\x2b\x01\x39\x04\x5a\x58\x7a"
+                         "\xf7\x11\x90\xec\xbd\x51\x5c\x32"
+                         "\x6b\xd7\x35\x39\x02\x6b\xf2\xa6"
+                         "\xd0\x0d\x07\xe1\x06\xc4\x5b\x7d"
+                         "\xe4\x6a\xd7\xee\x15\x1f\x83\xb4"
+                         "\xa3\xa7\x5e\xc3\x90\xb7\xef\xd3"
+                         "\xb7\x4f\xf8\x92\x4c\xb7\x3c\x29"
+                         "\xcd\x7e\x2b\x5d\x43\xea\x42\xe7"
+                         "\x74\x3f\x7d\x58\x88\x75\xde\x3e",
+               .rlen   = 512,
+       }
+};
+
+static struct cipher_testvec aes_lrw_dec_tv_template[] = {
+       /* from http://grouper.ieee.org/groups/1619/email/pdf00017.pdf */
+       /* same as enc vectors with input and result reversed */
+       { /* LRW-32-AES 1 */
+               .key    = "\x45\x62\xac\x25\xf8\x28\x17\x6d"
+                         "\x4c\x26\x84\x14\xb5\x68\x01\x85"
+                         "\x25\x8e\x2a\x05\xe7\x3e\x9d\x03"
+                         "\xee\x5a\x83\x0c\xcc\x09\x4c\x87",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x01",
+               .input  = "\xf1\xb2\x73\xcd\x65\xa3\xdf\x5f"
+                         "\xe9\x5d\x48\x92\x54\x63\x4e\xb8",
+               .ilen   = 16,
+               .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 2 */
+               .key    = "\x59\x70\x47\x14\xf5\x57\x47\x8c"
+                         "\xd7\x79\xe8\x0f\x54\x88\x79\x44"
+                         "\x0d\x48\xf0\xb7\xb1\x5a\x53\xea"
+                         "\x1c\xaa\x6b\x29\xc2\xca\xfb\xaf",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x02",
+               .input  = "\x00\xc8\x2b\xae\x95\xbb\xcd\xe5"
+                         "\x27\x4f\x07\x69\xb2\x60\xe1\x36",
+               .ilen   = 16,
+               .result  = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                          "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 3 */
+               .key    = "\xd8\x2a\x91\x34\xb2\x6a\x56\x50"
+                         "\x30\xfe\x69\xe2\x37\x7f\x98\x47"
+                         "\xcd\xf9\x0b\x16\x0c\x64\x8f\xb6"
+                         "\xb0\x0d\x0d\x1b\xae\x85\x87\x1f",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x02\x00\x00\x00\x00",
+               .input  = "\x76\x32\x21\x83\xed\x8f\xf1\x82"
+                         "\xf9\x59\x62\x03\x69\x0e\x5e\x01",
+               .ilen   = 16,
+               .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 4 */
+               .key    = "\x0f\x6a\xef\xf8\xd3\xd2\xbb\x15"
+                         "\x25\x83\xf7\x3c\x1f\x01\x28\x74"
+                         "\xca\xc6\xbc\x35\x4d\x4a\x65\x54"
+                         "\x90\xae\x61\xcf\x7b\xae\xbd\xcc"
+                         "\xad\xe4\x94\xc5\x4a\x29\xae\x70",
+               .klen   = 40,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x01",
+               .input  = "\x9c\x0f\x15\x2f\x55\xa2\xd8\xf0"
+                         "\xd6\x7b\x8f\x9e\x28\x22\xbc\x41",
+               .ilen   = 16,
+               .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 5 */
+               .key    = "\x8a\xd4\xee\x10\x2f\xbd\x81\xff"
+                         "\xf8\x86\xce\xac\x93\xc5\xad\xc6"
+                         "\xa0\x19\x07\xc0\x9d\xf7\xbb\xdd"
+                         "\x52\x13\xb2\xb7\xf0\xff\x11\xd8"
+                         "\xd6\x08\xd0\xcd\x2e\xb1\x17\x6f",
+               .klen   = 40,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x02\x00\x00\x00\x00",
+               .input  = "\xd4\x27\x6a\x7f\x14\x91\x3d\x65"
+                         "\xc8\x60\x48\x02\x87\xe3\x34\x06",
+               .ilen   = 16,
+               .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 6 */
+               .key    = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+                         "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+                         "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+                         "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+                         "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+                         "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+               .klen   = 48,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x01",
+               .input  = "\xbd\x06\xb8\xe1\xdb\x98\x89\x9e"
+                         "\xc4\x98\xe4\x91\xcf\x1c\x70\x2b",
+               .ilen   = 16,
+               .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 7 */
+               .key    = "\xfb\x76\x15\xb2\x3d\x80\x89\x1d"
+                         "\xd4\x70\x98\x0b\xc7\x95\x84\xc8"
+                         "\xb2\xfb\x64\xce\x60\x97\x87\x8d"
+                         "\x17\xfc\xe4\x5a\x49\xe8\x30\xb7"
+                         "\x6e\x78\x17\xe7\x2d\x5e\x12\xd4"
+                         "\x60\x64\x04\x7a\xf1\x2f\x9e\x0c",
+               .klen   = 48,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x02\x00\x00\x00\x00",
+               .input  = "\x5b\x90\x8e\xc1\xab\xdd\x67\x5f"
+                         "\x3d\x69\x8a\x95\x53\xc8\x9c\xe5",
+               .ilen   = 16,
+               .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .rlen   = 16,
+       }, {
+/* http://www.mail-archive.com/stds-p1619@listserv.ieee.org/msg00173.html */
+               .key    = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+                         "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+                         "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+                         "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+                         "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+                         "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+               .klen   = 48,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x01",
+               .input  = "\x1a\x1d\xa9\x30\xad\xf9\x2f\x9b"
+                         "\xb6\x1d\xae\xef\xf0\x2f\xf8\x5a"
+                         "\x39\x3c\xbf\x2a\xb2\x45\xb2\x23"
+                         "\x1b\x63\x3c\xcf\xaa\xbe\xcf\x4e"
+                         "\xfa\xe8\x29\xc2\x20\x68\x2b\x3c"
+                         "\x2e\x8b\xf7\x6e\x25\xbd\xe3\x3d"
+                         "\x66\x27\xd6\xaf\xd6\x64\x3e\xe3"
+                         "\xe8\x58\x46\x97\x39\x51\x07\xde"
+                         "\xcb\x37\xbc\xa9\xc0\x5f\x75\xc3"
+                         "\x0e\x84\x23\x1d\x16\xd4\x1c\x59"
+                         "\x9c\x1a\x02\x55\xab\x3a\x97\x1d"
+                         "\xdf\xdd\xc7\x06\x51\xd7\x70\xae"
+                         "\x23\xc6\x8c\xf5\x1e\xa0\xe5\x82"
+                         "\xb8\xb2\xbf\x04\xa0\x32\x8e\x68"
+                         "\xeb\xaf\x6e\x2d\x94\x22\x2f\xce"
+                         "\x4c\xb5\x59\xe2\xa2\x2f\xa0\x98"
+                         "\x1a\x97\xc6\xd4\xb5\x00\x59\xf2"
+                         "\x84\x14\x72\xb1\x9a\x6e\xa3\x7f"
+                         "\xea\x20\xe7\xcb\x65\x77\x3a\xdf"
+                         "\xc8\x97\x67\x15\xc2\x2a\x27\xcc"
+                         "\x18\x55\xa1\x24\x0b\x24\x24\xaf"
+                         "\x5b\xec\x68\xb8\xc8\xf5\xba\x63"
+                         "\xff\xed\x89\xce\xd5\x3d\x88\xf3"
+                         "\x25\xef\x05\x7c\x3a\xef\xeb\xd8"
+                         "\x7a\x32\x0d\xd1\x1e\x58\x59\x99"
+                         "\x90\x25\xb5\x26\xb0\xe3\x2b\x6c"
+                         "\x4c\xa9\x8b\x84\x4f\x5e\x01\x50"
+                         "\x41\x30\x58\xc5\x62\x74\x52\x1d"
+                         "\x45\x24\x6a\x42\x64\x4f\x97\x1c"
+                         "\xa8\x66\xb5\x6d\x79\xd4\x0d\x48"
+                         "\xc5\x5f\xf3\x90\x32\xdd\xdd\xe1"
+                         "\xe4\xa9\x9f\xfc\xc3\x52\x5a\x46"
+                         "\xe4\x81\x84\x95\x36\x59\x7a\x6b"
+                         "\xaa\xb3\x60\xad\xce\x9f\x9f\x28"
+                         "\xe0\x01\x75\x22\xc4\x4e\xa9\x62"
+                         "\x5c\x62\x0d\x00\xcb\x13\xe8\x43"
+                         "\x72\xd4\x2d\x53\x46\xb5\xd1\x16"
+                         "\x22\x18\xdf\x34\x33\xf5\xd6\x1c"
+                         "\xb8\x79\x78\x97\x94\xff\x72\x13"
+                         "\x4c\x27\xfc\xcb\xbf\x01\x53\xa6"
+                         "\xb4\x50\x6e\xde\xdf\xb5\x43\xa4"
+                         "\x59\xdf\x52\xf9\x7c\xe0\x11\x6f"
+                         "\x2d\x14\x8e\x24\x61\x2c\xe1\x17"
+                         "\xcc\xce\x51\x0c\x19\x8a\x82\x30"
+                         "\x94\xd5\x3d\x6a\x53\x06\x5e\xbd"
+                         "\xb7\xeb\xfa\xfd\x27\x51\xde\x85"
+                         "\x1e\x86\x53\x11\x53\x94\x00\xee"
+                         "\x2b\x8c\x08\x2a\xbf\xdd\xae\x11"
+                         "\xcb\x1e\xa2\x07\x9a\x80\xcf\x62"
+                         "\x9b\x09\xdc\x95\x3c\x96\x8e\xb1"
+                         "\x09\xbd\xe4\xeb\xdb\xca\x70\x7a"
+                         "\x9e\xfa\x31\x18\x45\x3c\x21\x33"
+                         "\xb0\xb3\x2b\xea\xf3\x71\x2d\xe1"
+                         "\x03\xad\x1b\x48\xd4\x67\x27\xf0"
+                         "\x62\xe4\x3d\xfb\x9b\x08\x76\xe7"
+                         "\xdd\x2b\x01\x39\x04\x5a\x58\x7a"
+                         "\xf7\x11\x90\xec\xbd\x51\x5c\x32"
+                         "\x6b\xd7\x35\x39\x02\x6b\xf2\xa6"
+                         "\xd0\x0d\x07\xe1\x06\xc4\x5b\x7d"
+                         "\xe4\x6a\xd7\xee\x15\x1f\x83\xb4"
+                         "\xa3\xa7\x5e\xc3\x90\xb7\xef\xd3"
+                         "\xb7\x4f\xf8\x92\x4c\xb7\x3c\x29"
+                         "\xcd\x7e\x2b\x5d\x43\xea\x42\xe7"
+                         "\x74\x3f\x7d\x58\x88\x75\xde\x3e",
+               .ilen   = 512,
+               .result = "\x05\x11\xb7\x18\xab\xc6\x2d\xac"
+                         "\x70\x5d\xf6\x22\x94\xcd\xe5\x6c"
+                         "\x17\x6b\xf6\x1c\xf0\xf3\x6e\xf8"
+                         "\x50\x38\x1f\x71\x49\xb6\x57\xd6"
+                         "\x8f\xcb\x8d\x6b\xe3\xa6\x29\x90"
+                         "\xfe\x2a\x62\x82\xae\x6d\x8b\xf6"
+                         "\xad\x1e\x9e\x20\x5f\x38\xbe\x04"
+                         "\xda\x10\x8e\xed\xa2\xa4\x87\xab"
+                         "\xda\x6b\xb4\x0c\x75\xba\xd3\x7c"
+                         "\xc9\xac\x42\x31\x95\x7c\xc9\x04"
+                         "\xeb\xd5\x6e\x32\x69\x8a\xdb\xa6"
+                         "\x15\xd7\x3f\x4f\x2f\x66\x69\x03"
+                         "\x9c\x1f\x54\x0f\xde\x1f\xf3\x65"
+                         "\x4c\x96\x12\xed\x7c\x92\x03\x01"
+                         "\x6f\xbc\x35\x93\xac\xf1\x27\xf1"
+                         "\xb4\x96\x82\x5a\x5f\xb0\xa0\x50"
+                         "\x89\xa4\x8e\x66\x44\x85\xcc\xfd"
+                         "\x33\x14\x70\xe3\x96\xb2\xc3\xd3"
+                         "\xbb\x54\x5a\x1a\xf9\x74\xa2\xc5"
+                         "\x2d\x64\x75\xdd\xb4\x54\xe6\x74"
+                         "\x8c\xd3\x9d\x9e\x86\xab\x51\x53"
+                         "\xb7\x93\x3e\x6f\xd0\x4e\x2c\x40"
+                         "\xf6\xa8\x2e\x3e\x9d\xf4\x66\xa5"
+                         "\x76\x12\x73\x44\x1a\x56\xd7\x72"
+                         "\x88\xcd\x21\x8c\x4c\x0f\xfe\xda"
+                         "\x95\xe0\x3a\xa6\xa5\x84\x46\xcd"
+                         "\xd5\x3e\x9d\x3a\xe2\x67\xe6\x60"
+                         "\x1a\xe2\x70\x85\x58\xc2\x1b\x09"
+                         "\xe1\xd7\x2c\xca\xad\xa8\x8f\xf9"
+                         "\xac\xb3\x0e\xdb\xca\x2e\xe2\xb8"
+                         "\x51\x71\xd9\x3c\x6c\xf1\x56\xf8"
+                         "\xea\x9c\xf1\xfb\x0c\xe6\xb7\x10"
+                         "\x1c\xf8\xa9\x7c\xe8\x53\x35\xc1"
+                         "\x90\x3e\x76\x4a\x74\xa4\x21\x2c"
+                         "\xf6\x2c\x4e\x0f\x94\x3a\x88\x2e"
+                         "\x41\x09\x6a\x33\x7d\xf6\xdd\x3f"
+                         "\x8d\x23\x31\x74\x84\xeb\x88\x6e"
+                         "\xcc\xb9\xbc\x22\x83\x19\x07\x22"
+                         "\xa5\x2d\xdf\xa5\xf3\x80\x85\x78"
+                         "\x84\x39\x6a\x6d\x6a\x99\x4f\xa5"
+                         "\x15\xfe\x46\xb0\xe4\x6c\xa5\x41"
+                         "\x3c\xce\x8f\x42\x60\x71\xa7\x75"
+                         "\x08\x40\x65\x8a\x82\xbf\xf5\x43"
+                         "\x71\x96\xa9\x4d\x44\x8a\x20\xbe"
+                         "\xfa\x4d\xbb\xc0\x7d\x31\x96\x65"
+                         "\xe7\x75\xe5\x3e\xfd\x92\x3b\xc9"
+                         "\x55\xbb\x16\x7e\xf7\xc2\x8c\xa4"
+                         "\x40\x1d\xe5\xef\x0e\xdf\xe4\x9a"
+                         "\x62\x73\x65\xfd\x46\x63\x25\x3d"
+                         "\x2b\xaf\xe5\x64\xfe\xa5\x5c\xcf"
+                         "\x24\xf3\xb4\xac\x64\xba\xdf\x4b"
+                         "\xc6\x96\x7d\x81\x2d\x8d\x97\xf7"
+                         "\xc5\x68\x77\x84\x32\x2b\xcc\x85"
+                         "\x74\x96\xf0\x12\x77\x61\xb9\xeb"
+                         "\x71\xaa\x82\xcb\x1c\xdb\x89\xc8"
+                         "\xc6\xb5\xe3\x5c\x7d\x39\x07\x24"
+                         "\xda\x39\x87\x45\xc0\x2b\xbb\x01"
+                         "\xac\xbc\x2a\x5c\x7f\xfc\xe8\xce"
+                         "\x6d\x9c\x6f\xed\xd3\xc1\xa1\xd6"
+                         "\xc5\x55\xa9\x66\x2f\xe1\xc8\x32"
+                         "\xa6\x5d\xa4\x3a\x98\x73\xe8\x45"
+                         "\xa4\xc7\xa8\xb4\xf6\x13\x03\xf6"
+                         "\xe9\x2e\xc4\x29\x0f\x84\xdb\xc4"
+                         "\x21\xc4\xc2\x75\x67\x89\x37\x0a",
+               .rlen   = 512,
+       }
+};
+
+static struct cipher_testvec aes_xts_enc_tv_template[] = {
+       /* http://grouper.ieee.org/groups/1619/email/pdf00086.pdf */
+       { /* XTS-AES 1 */
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 32,
+               .result = "\x91\x7c\xf6\x9e\xbd\x68\xb2\xec"
+                         "\x9b\x9f\xe9\xa3\xea\xdd\xa6\x92"
+                         "\xcd\x43\xd2\xf5\x95\x98\xed\x85"
+                         "\x8c\x02\xc2\x65\x2f\xbf\x92\x2e",
+               .rlen   = 32,
+       }, { /* XTS-AES 2 */
+               .key    = "\x11\x11\x11\x11\x11\x11\x11\x11"
+                         "\x11\x11\x11\x11\x11\x11\x11\x11"
+                         "\x22\x22\x22\x22\x22\x22\x22\x22"
+                         "\x22\x22\x22\x22\x22\x22\x22\x22",
+               .klen   = 32,
+               .iv     = "\x33\x33\x33\x33\x33\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44",
+               .ilen   = 32,
+               .result = "\xc4\x54\x18\x5e\x6a\x16\x93\x6e"
+                         "\x39\x33\x40\x38\xac\xef\x83\x8b"
+                         "\xfb\x18\x6f\xff\x74\x80\xad\xc4"
+                         "\x28\x93\x82\xec\xd6\xd3\x94\xf0",
+               .rlen   = 32,
+       }, { /* XTS-AES 3 */
+               .key    = "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8"
+                         "\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0"
+                         "\x22\x22\x22\x22\x22\x22\x22\x22"
+                         "\x22\x22\x22\x22\x22\x22\x22\x22",
+               .klen   = 32,
+               .iv     = "\x33\x33\x33\x33\x33\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44",
+               .ilen   = 32,
+               .result = "\xaf\x85\x33\x6b\x59\x7a\xfc\x1a"
+                         "\x90\x0b\x2e\xb2\x1e\xc9\x49\xd2"
+                         "\x92\xdf\x4c\x04\x7e\x0b\x21\x53"
+                         "\x21\x86\xa5\x97\x1a\x22\x7a\x89",
+               .rlen   = 32,
+       }, { /* XTS-AES 4 */
+               .key    = "\x27\x18\x28\x18\x28\x45\x90\x45"
+                         "\x23\x53\x60\x28\x74\x71\x35\x26"
+                         "\x31\x41\x59\x26\x53\x58\x97\x93"
+                         "\x23\x84\x62\x64\x33\x83\x27\x95",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+                         "\x20\x21\x22\x23\x24\x25\x26\x27"
+                         "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+                         "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+                         "\x40\x41\x42\x43\x44\x45\x46\x47"
+                         "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+                         "\x50\x51\x52\x53\x54\x55\x56\x57"
+                         "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+                         "\x60\x61\x62\x63\x64\x65\x66\x67"
+                         "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+                         "\x70\x71\x72\x73\x74\x75\x76\x77"
+                         "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+                         "\x80\x81\x82\x83\x84\x85\x86\x87"
+                         "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+                         "\x90\x91\x92\x93\x94\x95\x96\x97"
+                         "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+                         "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+                         "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+                         "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+                         "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+                         "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+                         "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+                         "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+                         "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+                         "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+                         "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+                         "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+                         "\x20\x21\x22\x23\x24\x25\x26\x27"
+                         "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+                         "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+                         "\x40\x41\x42\x43\x44\x45\x46\x47"
+                         "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+                         "\x50\x51\x52\x53\x54\x55\x56\x57"
+                         "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+                         "\x60\x61\x62\x63\x64\x65\x66\x67"
+                         "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+                         "\x70\x71\x72\x73\x74\x75\x76\x77"
+                         "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+                         "\x80\x81\x82\x83\x84\x85\x86\x87"
+                         "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+                         "\x90\x91\x92\x93\x94\x95\x96\x97"
+                         "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+                         "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+                         "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+                         "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+                         "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+                         "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+                         "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+                         "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+                         "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+                         "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+                         "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+               .ilen   = 512,
+               .result = "\x27\xa7\x47\x9b\xef\xa1\xd4\x76"
+                         "\x48\x9f\x30\x8c\xd4\xcf\xa6\xe2"
+                         "\xa9\x6e\x4b\xbe\x32\x08\xff\x25"
+                         "\x28\x7d\xd3\x81\x96\x16\xe8\x9c"
+                         "\xc7\x8c\xf7\xf5\xe5\x43\x44\x5f"
+                         "\x83\x33\xd8\xfa\x7f\x56\x00\x00"
+                         "\x05\x27\x9f\xa5\xd8\xb5\xe4\xad"
+                         "\x40\xe7\x36\xdd\xb4\xd3\x54\x12"
+                         "\x32\x80\x63\xfd\x2a\xab\x53\xe5"
+                         "\xea\x1e\x0a\x9f\x33\x25\x00\xa5"
+                         "\xdf\x94\x87\xd0\x7a\x5c\x92\xcc"
+                         "\x51\x2c\x88\x66\xc7\xe8\x60\xce"
+                         "\x93\xfd\xf1\x66\xa2\x49\x12\xb4"
+                         "\x22\x97\x61\x46\xae\x20\xce\x84"
+                         "\x6b\xb7\xdc\x9b\xa9\x4a\x76\x7a"
+                         "\xae\xf2\x0c\x0d\x61\xad\x02\x65"
+                         "\x5e\xa9\x2d\xc4\xc4\xe4\x1a\x89"
+                         "\x52\xc6\x51\xd3\x31\x74\xbe\x51"
+                         "\xa1\x0c\x42\x11\x10\xe6\xd8\x15"
+                         "\x88\xed\xe8\x21\x03\xa2\x52\xd8"
+                         "\xa7\x50\xe8\x76\x8d\xef\xff\xed"
+                         "\x91\x22\x81\x0a\xae\xb9\x9f\x91"
+                         "\x72\xaf\x82\xb6\x04\xdc\x4b\x8e"
+                         "\x51\xbc\xb0\x82\x35\xa6\xf4\x34"
+                         "\x13\x32\xe4\xca\x60\x48\x2a\x4b"
+                         "\xa1\xa0\x3b\x3e\x65\x00\x8f\xc5"
+                         "\xda\x76\xb7\x0b\xf1\x69\x0d\xb4"
+                         "\xea\xe2\x9c\x5f\x1b\xad\xd0\x3c"
+                         "\x5c\xcf\x2a\x55\xd7\x05\xdd\xcd"
+                         "\x86\xd4\x49\x51\x1c\xeb\x7e\xc3"
+                         "\x0b\xf1\x2b\x1f\xa3\x5b\x91\x3f"
+                         "\x9f\x74\x7a\x8a\xfd\x1b\x13\x0e"
+                         "\x94\xbf\xf9\x4e\xff\xd0\x1a\x91"
+                         "\x73\x5c\xa1\x72\x6a\xcd\x0b\x19"
+                         "\x7c\x4e\x5b\x03\x39\x36\x97\xe1"
+                         "\x26\x82\x6f\xb6\xbb\xde\x8e\xcc"
+                         "\x1e\x08\x29\x85\x16\xe2\xc9\xed"
+                         "\x03\xff\x3c\x1b\x78\x60\xf6\xde"
+                         "\x76\xd4\xce\xcd\x94\xc8\x11\x98"
+                         "\x55\xef\x52\x97\xca\x67\xe9\xf3"
+                         "\xe7\xff\x72\xb1\xe9\x97\x85\xca"
+                         "\x0a\x7e\x77\x20\xc5\xb3\x6d\xc6"
+                         "\xd7\x2c\xac\x95\x74\xc8\xcb\xbc"
+                         "\x2f\x80\x1e\x23\xe5\x6f\xd3\x44"
+                         "\xb0\x7f\x22\x15\x4b\xeb\xa0\xf0"
+                         "\x8c\xe8\x89\x1e\x64\x3e\xd9\x95"
+                         "\xc9\x4d\x9a\x69\xc9\xf1\xb5\xf4"
+                         "\x99\x02\x7a\x78\x57\x2a\xee\xbd"
+                         "\x74\xd2\x0c\xc3\x98\x81\xc2\x13"
+                         "\xee\x77\x0b\x10\x10\xe4\xbe\xa7"
+                         "\x18\x84\x69\x77\xae\x11\x9f\x7a"
+                         "\x02\x3a\xb5\x8c\xca\x0a\xd7\x52"
+                         "\xaf\xe6\x56\xbb\x3c\x17\x25\x6a"
+                         "\x9f\x6e\x9b\xf1\x9f\xdd\x5a\x38"
+                         "\xfc\x82\xbb\xe8\x72\xc5\x53\x9e"
+                         "\xdb\x60\x9e\xf4\xf7\x9c\x20\x3e"
+                         "\xbb\x14\x0f\x2e\x58\x3c\xb2\xad"
+                         "\x15\xb4\xaa\x5b\x65\x50\x16\xa8"
+                         "\x44\x92\x77\xdb\xd4\x77\xef\x2c"
+                         "\x8d\x6c\x01\x7d\xb7\x38\xb1\x8d"
+                         "\xeb\x4a\x42\x7d\x19\x23\xce\x3f"
+                         "\xf2\x62\x73\x57\x79\xa4\x18\xf2"
+                         "\x0a\x28\x2d\xf9\x20\x14\x7b\xea"
+                         "\xbe\x42\x1e\xe5\x31\x9d\x05\x68",
+               .rlen   = 512,
+       }
+};
+
+static struct cipher_testvec aes_xts_dec_tv_template[] = {
+       /* http://grouper.ieee.org/groups/1619/email/pdf00086.pdf */
+       { /* XTS-AES 1 */
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input = "\x91\x7c\xf6\x9e\xbd\x68\xb2\xec"
+                        "\x9b\x9f\xe9\xa3\xea\xdd\xa6\x92"
+                        "\xcd\x43\xd2\xf5\x95\x98\xed\x85"
+                        "\x8c\x02\xc2\x65\x2f\xbf\x92\x2e",
+               .ilen   = 32,
+               .result  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                          "\x00\x00\x00\x00\x00\x00\x00\x00"
+                          "\x00\x00\x00\x00\x00\x00\x00\x00"
+                          "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .rlen   = 32,
+       }, { /* XTS-AES 2 */
+               .key    = "\x11\x11\x11\x11\x11\x11\x11\x11"
+                         "\x11\x11\x11\x11\x11\x11\x11\x11"
+                         "\x22\x22\x22\x22\x22\x22\x22\x22"
+                         "\x22\x22\x22\x22\x22\x22\x22\x22",
+               .klen   = 32,
+               .iv     = "\x33\x33\x33\x33\x33\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\xc4\x54\x18\x5e\x6a\x16\x93\x6e"
+                         "\x39\x33\x40\x38\xac\xef\x83\x8b"
+                         "\xfb\x18\x6f\xff\x74\x80\xad\xc4"
+                         "\x28\x93\x82\xec\xd6\xd3\x94\xf0",
+               .ilen   = 32,
+               .result = "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44",
+               .rlen   = 32,
+       }, { /* XTS-AES 3 */
+               .key    = "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8"
+                         "\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0"
+                         "\x22\x22\x22\x22\x22\x22\x22\x22"
+                         "\x22\x22\x22\x22\x22\x22\x22\x22",
+               .klen   = 32,
+               .iv     = "\x33\x33\x33\x33\x33\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input = "\xaf\x85\x33\x6b\x59\x7a\xfc\x1a"
+                         "\x90\x0b\x2e\xb2\x1e\xc9\x49\xd2"
+                         "\x92\xdf\x4c\x04\x7e\x0b\x21\x53"
+                         "\x21\x86\xa5\x97\x1a\x22\x7a\x89",
+               .ilen   = 32,
+               .result  = "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44",
+               .rlen   = 32,
+       }, { /* XTS-AES 4 */
+               .key    = "\x27\x18\x28\x18\x28\x45\x90\x45"
+                         "\x23\x53\x60\x28\x74\x71\x35\x26"
+                         "\x31\x41\x59\x26\x53\x58\x97\x93"
+                         "\x23\x84\x62\x64\x33\x83\x27\x95",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x27\xa7\x47\x9b\xef\xa1\xd4\x76"
+                         "\x48\x9f\x30\x8c\xd4\xcf\xa6\xe2"
+                         "\xa9\x6e\x4b\xbe\x32\x08\xff\x25"
+                         "\x28\x7d\xd3\x81\x96\x16\xe8\x9c"
+                         "\xc7\x8c\xf7\xf5\xe5\x43\x44\x5f"
+                         "\x83\x33\xd8\xfa\x7f\x56\x00\x00"
+                         "\x05\x27\x9f\xa5\xd8\xb5\xe4\xad"
+                         "\x40\xe7\x36\xdd\xb4\xd3\x54\x12"
+                         "\x32\x80\x63\xfd\x2a\xab\x53\xe5"
+                         "\xea\x1e\x0a\x9f\x33\x25\x00\xa5"
+                         "\xdf\x94\x87\xd0\x7a\x5c\x92\xcc"
+                         "\x51\x2c\x88\x66\xc7\xe8\x60\xce"
+                         "\x93\xfd\xf1\x66\xa2\x49\x12\xb4"
+                         "\x22\x97\x61\x46\xae\x20\xce\x84"
+                         "\x6b\xb7\xdc\x9b\xa9\x4a\x76\x7a"
+                         "\xae\xf2\x0c\x0d\x61\xad\x02\x65"
+                         "\x5e\xa9\x2d\xc4\xc4\xe4\x1a\x89"
+                         "\x52\xc6\x51\xd3\x31\x74\xbe\x51"
+                         "\xa1\x0c\x42\x11\x10\xe6\xd8\x15"
+                         "\x88\xed\xe8\x21\x03\xa2\x52\xd8"
+                         "\xa7\x50\xe8\x76\x8d\xef\xff\xed"
+                         "\x91\x22\x81\x0a\xae\xb9\x9f\x91"
+                         "\x72\xaf\x82\xb6\x04\xdc\x4b\x8e"
+                         "\x51\xbc\xb0\x82\x35\xa6\xf4\x34"
+                         "\x13\x32\xe4\xca\x60\x48\x2a\x4b"
+                         "\xa1\xa0\x3b\x3e\x65\x00\x8f\xc5"
+                         "\xda\x76\xb7\x0b\xf1\x69\x0d\xb4"
+                         "\xea\xe2\x9c\x5f\x1b\xad\xd0\x3c"
+                         "\x5c\xcf\x2a\x55\xd7\x05\xdd\xcd"
+                         "\x86\xd4\x49\x51\x1c\xeb\x7e\xc3"
+                         "\x0b\xf1\x2b\x1f\xa3\x5b\x91\x3f"
+                         "\x9f\x74\x7a\x8a\xfd\x1b\x13\x0e"
+                         "\x94\xbf\xf9\x4e\xff\xd0\x1a\x91"
+                         "\x73\x5c\xa1\x72\x6a\xcd\x0b\x19"
+                         "\x7c\x4e\x5b\x03\x39\x36\x97\xe1"
+                         "\x26\x82\x6f\xb6\xbb\xde\x8e\xcc"
+                         "\x1e\x08\x29\x85\x16\xe2\xc9\xed"
+                         "\x03\xff\x3c\x1b\x78\x60\xf6\xde"
+                         "\x76\xd4\xce\xcd\x94\xc8\x11\x98"
+                         "\x55\xef\x52\x97\xca\x67\xe9\xf3"
+                         "\xe7\xff\x72\xb1\xe9\x97\x85\xca"
+                         "\x0a\x7e\x77\x20\xc5\xb3\x6d\xc6"
+                         "\xd7\x2c\xac\x95\x74\xc8\xcb\xbc"
+                         "\x2f\x80\x1e\x23\xe5\x6f\xd3\x44"
+                         "\xb0\x7f\x22\x15\x4b\xeb\xa0\xf0"
+                         "\x8c\xe8\x89\x1e\x64\x3e\xd9\x95"
+                         "\xc9\x4d\x9a\x69\xc9\xf1\xb5\xf4"
+                         "\x99\x02\x7a\x78\x57\x2a\xee\xbd"
+                         "\x74\xd2\x0c\xc3\x98\x81\xc2\x13"
+                         "\xee\x77\x0b\x10\x10\xe4\xbe\xa7"
+                         "\x18\x84\x69\x77\xae\x11\x9f\x7a"
+                         "\x02\x3a\xb5\x8c\xca\x0a\xd7\x52"
+                         "\xaf\xe6\x56\xbb\x3c\x17\x25\x6a"
+                         "\x9f\x6e\x9b\xf1\x9f\xdd\x5a\x38"
+                         "\xfc\x82\xbb\xe8\x72\xc5\x53\x9e"
+                         "\xdb\x60\x9e\xf4\xf7\x9c\x20\x3e"
+                         "\xbb\x14\x0f\x2e\x58\x3c\xb2\xad"
+                         "\x15\xb4\xaa\x5b\x65\x50\x16\xa8"
+                         "\x44\x92\x77\xdb\xd4\x77\xef\x2c"
+                         "\x8d\x6c\x01\x7d\xb7\x38\xb1\x8d"
+                         "\xeb\x4a\x42\x7d\x19\x23\xce\x3f"
+                         "\xf2\x62\x73\x57\x79\xa4\x18\xf2"
+                         "\x0a\x28\x2d\xf9\x20\x14\x7b\xea"
+                         "\xbe\x42\x1e\xe5\x31\x9d\x05\x68",
+               .ilen   = 512,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+                         "\x20\x21\x22\x23\x24\x25\x26\x27"
+                         "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+                         "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+                         "\x40\x41\x42\x43\x44\x45\x46\x47"
+                         "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+                         "\x50\x51\x52\x53\x54\x55\x56\x57"
+                         "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+                         "\x60\x61\x62\x63\x64\x65\x66\x67"
+                         "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+                         "\x70\x71\x72\x73\x74\x75\x76\x77"
+                         "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+                         "\x80\x81\x82\x83\x84\x85\x86\x87"
+                         "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+                         "\x90\x91\x92\x93\x94\x95\x96\x97"
+                         "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+                         "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+                         "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+                         "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+                         "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+                         "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+                         "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+                         "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+                         "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+                         "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+                         "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+                         "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+                         "\x20\x21\x22\x23\x24\x25\x26\x27"
+                         "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+                         "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+                         "\x40\x41\x42\x43\x44\x45\x46\x47"
+                         "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+                         "\x50\x51\x52\x53\x54\x55\x56\x57"
+                         "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+                         "\x60\x61\x62\x63\x64\x65\x66\x67"
+                         "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+                         "\x70\x71\x72\x73\x74\x75\x76\x77"
+                         "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+                         "\x80\x81\x82\x83\x84\x85\x86\x87"
+                         "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+                         "\x90\x91\x92\x93\x94\x95\x96\x97"
+                         "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+                         "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+                         "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+                         "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+                         "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+                         "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+                         "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+                         "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+                         "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+                         "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+                         "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+               .rlen   = 512,
+       }
+};
+
+#endif
+
+static struct cipher_testvec aes_ctr_enc_tv_template[] = {
+       { /* From NIST Special Publication 800-38A, Appendix F.5 */
+               .key    = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6"
+                         "\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+               .klen   = 16,
+               .iv     = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+                         "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+               .input  = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+               .ilen   = 64,
+               .result = "\x87\x4d\x61\x91\xb6\x20\xe3\x26"
+                         "\x1b\xef\x68\x64\x99\x0d\xb6\xce"
+                         "\x98\x06\xf6\x6b\x79\x70\xfd\xff"
+                         "\x86\x17\x18\x7b\xb9\xff\xfd\xff"
+                         "\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e"
+                         "\x5b\x4f\x09\x02\x0d\xb0\x3e\xab"
+                         "\x1e\x03\x1d\xda\x2f\xbe\x03\xd1"
+                         "\x79\x21\x70\xa0\xf3\x00\x9c\xee",
+               .rlen   = 64,
+       }, {
+               .key    = "\x8e\x73\xb0\xf7\xda\x0e\x64\x52"
+                         "\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
+                         "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+               .klen   = 24,
+               .iv     = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+                         "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+               .input  = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+               .ilen   = 64,
+               .result = "\x1a\xbc\x93\x24\x17\x52\x1c\xa2"
+                         "\x4f\x2b\x04\x59\xfe\x7e\x6e\x0b"
+                         "\x09\x03\x39\xec\x0a\xa6\xfa\xef"
+                         "\xd5\xcc\xc2\xc6\xf4\xce\x8e\x94"
+                         "\x1e\x36\xb2\x6b\xd1\xeb\xc6\x70"
+                         "\xd1\xbd\x1d\x66\x56\x20\xab\xf7"
+                         "\x4f\x78\xa7\xf6\xd2\x98\x09\x58"
+                         "\x5a\x97\xda\xec\x58\xc6\xb0\x50",
+               .rlen   = 64,
+       }, {
+               .key    = "\x60\x3d\xeb\x10\x15\xca\x71\xbe"
+                         "\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+                         "\x1f\x35\x2c\x07\x3b\x61\x08\xd7"
+                         "\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+               .klen   = 32,
+               .iv     = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+                         "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+               .input  = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+               .ilen   = 64,
+               .result = "\x60\x1e\xc3\x13\x77\x57\x89\xa5"
+                         "\xb7\xa7\xf5\x04\xbb\xf3\xd2\x28"
+                         "\xf4\x43\xe3\xca\x4d\x62\xb5\x9a"
+                         "\xca\x84\xe9\x90\xca\xca\xf5\xc5"
+                         "\x2b\x09\x30\xda\xa2\x3d\xe9\x4c"
+                         "\xe8\x70\x17\xba\x2d\x84\x98\x8d"
+                         "\xdf\xc9\xc5\x8d\xb6\x7a\xad\xa6"
+                         "\x13\xc2\xdd\x08\x45\x79\x41\xa6",
+               .rlen   = 64,
+       }
+};
+
+static struct cipher_testvec aes_ctr_dec_tv_template[] = {
+       { /* From NIST Special Publication 800-38A, Appendix F.5 */
+               .key    = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6"
+                         "\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+               .klen   = 16,
+               .iv     = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+                         "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+               .input  = "\x87\x4d\x61\x91\xb6\x20\xe3\x26"
+                         "\x1b\xef\x68\x64\x99\x0d\xb6\xce"
+                         "\x98\x06\xf6\x6b\x79\x70\xfd\xff"
+                         "\x86\x17\x18\x7b\xb9\xff\xfd\xff"
+                         "\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e"
+                         "\x5b\x4f\x09\x02\x0d\xb0\x3e\xab"
+                         "\x1e\x03\x1d\xda\x2f\xbe\x03\xd1"
+                         "\x79\x21\x70\xa0\xf3\x00\x9c\xee",
+               .ilen   = 64,
+               .result = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+               .rlen   = 64,
+       }, {
+               .key    = "\x8e\x73\xb0\xf7\xda\x0e\x64\x52"
+                         "\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
+                         "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+               .klen   = 24,
+               .iv     = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+                         "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+               .input  = "\x1a\xbc\x93\x24\x17\x52\x1c\xa2"
+                         "\x4f\x2b\x04\x59\xfe\x7e\x6e\x0b"
+                         "\x09\x03\x39\xec\x0a\xa6\xfa\xef"
+                         "\xd5\xcc\xc2\xc6\xf4\xce\x8e\x94"
+                         "\x1e\x36\xb2\x6b\xd1\xeb\xc6\x70"
+                         "\xd1\xbd\x1d\x66\x56\x20\xab\xf7"
+                         "\x4f\x78\xa7\xf6\xd2\x98\x09\x58"
+                         "\x5a\x97\xda\xec\x58\xc6\xb0\x50",
+               .ilen   = 64,
+               .result = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+               .rlen   = 64,
+       }, {
+               .key    = "\x60\x3d\xeb\x10\x15\xca\x71\xbe"
+                         "\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+                         "\x1f\x35\x2c\x07\x3b\x61\x08\xd7"
+                         "\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+               .klen   = 32,
+               .iv     = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+                         "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+               .input  = "\x60\x1e\xc3\x13\x77\x57\x89\xa5"
+                         "\xb7\xa7\xf5\x04\xbb\xf3\xd2\x28"
+                         "\xf4\x43\xe3\xca\x4d\x62\xb5\x9a"
+                         "\xca\x84\xe9\x90\xca\xca\xf5\xc5"
+                         "\x2b\x09\x30\xda\xa2\x3d\xe9\x4c"
+                         "\xe8\x70\x17\xba\x2d\x84\x98\x8d"
+                         "\xdf\xc9\xc5\x8d\xb6\x7a\xad\xa6"
+                         "\x13\xc2\xdd\x08\x45\x79\x41\xa6",
+               .ilen   = 64,
+               .result = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+               .rlen   = 64,
+       }
+};
+
+static struct cipher_testvec aes_ctr_rfc3686_enc_tv_template[] = {
+       { /* From RFC 3686 */
+               .key    = "\xae\x68\x52\xf8\x12\x10\x67\xcc"
+                         "\x4b\xf7\xa5\x76\x55\x77\xf3\x9e"
+                         "\x00\x00\x00\x30",
+               .klen   = 20,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "Single block msg",
+               .ilen   = 16,
+               .result = "\xe4\x09\x5d\x4f\xb7\xa7\xb3\x79"
+                         "\x2d\x61\x75\xa3\x26\x13\x11\xb8",
+               .rlen   = 16,
+       }, {
+               .key    = "\x7e\x24\x06\x78\x17\xfa\xe0\xd7"
+                         "\x43\xd6\xce\x1f\x32\x53\x91\x63"
+                         "\x00\x6c\xb6\xdb",
+               .klen   = 20,
+               .iv     = "\xc0\x54\x3b\x59\xda\x48\xd9\x0b",
+               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .ilen   = 32,
+               .result = "\x51\x04\xa1\x06\x16\x8a\x72\xd9"
+                         "\x79\x0d\x41\xee\x8e\xda\xd3\x88"
+                         "\xeb\x2e\x1e\xfc\x46\xda\x57\xc8"
+                         "\xfc\xe6\x30\xdf\x91\x41\xbe\x28",
+               .rlen   = 32,
+       }, {
+               .key    = "\x16\xaf\x5b\x14\x5f\xc9\xf5\x79"
+                         "\xc1\x75\xf9\x3e\x3b\xfb\x0e\xed"
+                         "\x86\x3d\x06\xcc\xfd\xb7\x85\x15"
+                         "\x00\x00\x00\x48",
+               .klen   = 28,
+               .iv     = "\x36\x73\x3c\x14\x7d\x6d\x93\xcb",
+               .input  = "Single block msg",
+               .ilen   = 16,
+               .result = "\x4b\x55\x38\x4f\xe2\x59\xc9\xc8"
+                         "\x4e\x79\x35\xa0\x03\xcb\xe9\x28",
+               .rlen   = 16,
+       }, {
+               .key    = "\x7c\x5c\xb2\x40\x1b\x3d\xc3\x3c"
+                         "\x19\xe7\x34\x08\x19\xe0\xf6\x9c"
+                         "\x67\x8c\x3d\xb8\xe6\xf6\xa9\x1a"
+                         "\x00\x96\xb0\x3b",
+               .klen   = 28,
+               .iv     = "\x02\x0c\x6e\xad\xc2\xcb\x50\x0d",
+               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .ilen   = 32,
+               .result = "\x45\x32\x43\xfc\x60\x9b\x23\x32"
+                         "\x7e\xdf\xaa\xfa\x71\x31\xcd\x9f"
+                         "\x84\x90\x70\x1c\x5a\xd4\xa7\x9c"
+                         "\xfc\x1f\xe0\xff\x42\xf4\xfb\x00",
+               .rlen   = 32,
+       }, {
+               .key    = "\x77\x6b\xef\xf2\x85\x1d\xb0\x6f"
+                         "\x4c\x8a\x05\x42\xc8\x69\x6f\x6c"
+                         "\x6a\x81\xaf\x1e\xec\x96\xb4\xd3"
+                         "\x7f\xc1\xd6\x89\xe6\xc1\xc1\x04"
+                         "\x00\x00\x00\x60",
+               .klen   = 36,
+               .iv     = "\xdb\x56\x72\xc9\x7a\xa8\xf0\xb2",
+               .input  = "Single block msg",
+               .ilen   = 16,
+               .result = "\x14\x5a\xd0\x1d\xbf\x82\x4e\xc7"
+                         "\x56\x08\x63\xdc\x71\xe3\xe0\xc0",
+               .rlen   = 16,
+       }, {
+               .key    = "\xf6\xd6\x6d\x6b\xd5\x2d\x59\xbb"
+                         "\x07\x96\x36\x58\x79\xef\xf8\x86"
+                         "\xc6\x6d\xd5\x1a\x5b\x6a\x99\x74"
+                         "\x4b\x50\x59\x0c\x87\xa2\x38\x84"
+                         "\x00\xfa\xac\x24",
+               .klen   = 36,
+               .iv     = "\xc1\x58\x5e\xf1\x5a\x43\xd8\x75",
+               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .ilen   = 32,
+               .result = "\xf0\x5e\x23\x1b\x38\x94\x61\x2c"
+                         "\x49\xee\x00\x0b\x80\x4e\xb2\xa9"
+                         "\xb8\x30\x6b\x50\x8f\x83\x9d\x6a"
+                         "\x55\x30\x83\x1d\x93\x44\xaf\x1c",
+               .rlen   = 32,
+       }, {
+#if 0
+       // generated using Crypto++
+               .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                       "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                       "\x10\x11\x12\x13\x14\x15\x16\x17"
+                       "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+                       "\x00\x00\x00\x00",
+               .klen = 32 + 4,
+               .iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input =
+                       "\x00\x01\x02\x03\x04\x05\x06\x07"
+                       "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                       "\x10\x11\x12\x13\x14\x15\x16\x17"
+                       "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+                       "\x20\x21\x22\x23\x24\x25\x26\x27"
+                       "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+                       "\x30\x31\x32\x33\x34\x35\x36\x37"
+                       "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+                       "\x40\x41\x42\x43\x44\x45\x46\x47"
+                       "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+                       "\x50\x51\x52\x53\x54\x55\x56\x57"
+                       "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+                       "\x60\x61\x62\x63\x64\x65\x66\x67"
+                       "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+                       "\x70\x71\x72\x73\x74\x75\x76\x77"
+                       "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+                       "\x80\x81\x82\x83\x84\x85\x86\x87"
+                       "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+                       "\x90\x91\x92\x93\x94\x95\x96\x97"
+                       "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+                       "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+                       "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+                       "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+                       "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+                       "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                       "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+                       "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+                       "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+                       "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+                       "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+                       "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+                       "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+                       "\x00\x03\x06\x09\x0c\x0f\x12\x15"
+                       "\x18\x1b\x1e\x21\x24\x27\x2a\x2d"
+                       "\x30\x33\x36\x39\x3c\x3f\x42\x45"
+                       "\x48\x4b\x4e\x51\x54\x57\x5a\x5d"
+                       "\x60\x63\x66\x69\x6c\x6f\x72\x75"
+                       "\x78\x7b\x7e\x81\x84\x87\x8a\x8d"
+                       "\x90\x93\x96\x99\x9c\x9f\xa2\xa5"
+                       "\xa8\xab\xae\xb1\xb4\xb7\xba\xbd"
+                       "\xc0\xc3\xc6\xc9\xcc\xcf\xd2\xd5"
+                       "\xd8\xdb\xde\xe1\xe4\xe7\xea\xed"
+                       "\xf0\xf3\xf6\xf9\xfc\xff\x02\x05"
+                       "\x08\x0b\x0e\x11\x14\x17\x1a\x1d"
+                       "\x20\x23\x26\x29\x2c\x2f\x32\x35"
+                       "\x38\x3b\x3e\x41\x44\x47\x4a\x4d"
+                       "\x50\x53\x56\x59\x5c\x5f\x62\x65"
+                       "\x68\x6b\x6e\x71\x74\x77\x7a\x7d"
+                       "\x80\x83\x86\x89\x8c\x8f\x92\x95"
+                       "\x98\x9b\x9e\xa1\xa4\xa7\xaa\xad"
+                       "\xb0\xb3\xb6\xb9\xbc\xbf\xc2\xc5"
+                       "\xc8\xcb\xce\xd1\xd4\xd7\xda\xdd"
+                       "\xe0\xe3\xe6\xe9\xec\xef\xf2\xf5"
+                       "\xf8\xfb\xfe\x01\x04\x07\x0a\x0d"
+                       "\x10\x13\x16\x19\x1c\x1f\x22\x25"
+                       "\x28\x2b\x2e\x31\x34\x37\x3a\x3d"
+                       "\x40\x43\x46\x49\x4c\x4f\x52\x55"
+                       "\x58\x5b\x5e\x61\x64\x67\x6a\x6d"
+                       "\x70\x73\x76\x79\x7c\x7f\x82\x85"
+                       "\x88\x8b\x8e\x91\x94\x97\x9a\x9d"
+                       "\xa0\xa3\xa6\xa9\xac\xaf\xb2\xb5"
+                       "\xb8\xbb\xbe\xc1\xc4\xc7\xca\xcd"
+                       "\xd0\xd3\xd6\xd9\xdc\xdf\xe2\xe5"
+                       "\xe8\xeb\xee\xf1\xf4\xf7\xfa\xfd"
+                       "\x00\x05\x0a\x0f\x14\x19\x1e\x23"
+                       "\x28\x2d\x32\x37\x3c\x41\x46\x4b"
+                       "\x50\x55\x5a\x5f\x64\x69\x6e\x73"
+                       "\x78\x7d\x82\x87\x8c\x91\x96\x9b"
+                       "\xa0\xa5\xaa\xaf\xb4\xb9\xbe\xc3"
+                       "\xc8\xcd\xd2\xd7\xdc\xe1\xe6\xeb"
+                       "\xf0\xf5\xfa\xff\x04\x09\x0e\x13"
+                       "\x18\x1d\x22\x27\x2c\x31\x36\x3b"
+                       "\x40\x45\x4a\x4f\x54\x59\x5e\x63"
+                       "\x68\x6d\x72\x77\x7c\x81\x86\x8b"
+                       "\x90\x95\x9a\x9f\xa4\xa9\xae\xb3"
+                       "\xb8\xbd\xc2\xc7\xcc\xd1\xd6\xdb"
+                       "\xe0\xe5\xea\xef\xf4\xf9\xfe\x03"
+                       "\x08\x0d\x12\x17\x1c\x21\x26\x2b"
+                       "\x30\x35\x3a\x3f\x44\x49\x4e\x53"
+                       "\x58\x5d\x62\x67\x6c\x71\x76\x7b"
+                       "\x80\x85\x8a\x8f\x94\x99\x9e\xa3"
+                       "\xa8\xad\xb2\xb7\xbc\xc1\xc6\xcb"
+                       "\xd0\xd5\xda\xdf\xe4\xe9\xee\xf3"
+                       "\xf8\xfd\x02\x07\x0c\x11\x16\x1b"
+                       "\x20\x25\x2a\x2f\x34\x39\x3e\x43"
+                       "\x48\x4d\x52\x57\x5c\x61\x66\x6b"
+                       "\x70\x75\x7a\x7f\x84\x89\x8e\x93"
+                       "\x98\x9d\xa2\xa7\xac\xb1\xb6\xbb"
+                       "\xc0\xc5\xca\xcf\xd4\xd9\xde\xe3"
+                       "\xe8\xed\xf2\xf7\xfc\x01\x06\x0b"
+                       "\x10\x15\x1a\x1f\x24\x29\x2e\x33"
+                       "\x38\x3d\x42\x47\x4c\x51\x56\x5b"
+                       "\x60\x65\x6a\x6f\x74\x79\x7e\x83"
+                       "\x88\x8d\x92\x97\x9c\xa1\xa6\xab"
+                       "\xb0\xb5\xba\xbf\xc4\xc9\xce\xd3"
+                       "\xd8\xdd\xe2\xe7\xec\xf1\xf6\xfb"
+                       "\x00\x07\x0e\x15\x1c\x23\x2a\x31"
+                       "\x38\x3f\x46\x4d\x54\x5b\x62\x69"
+                       "\x70\x77\x7e\x85\x8c\x93\x9a\xa1"
+                       "\xa8\xaf\xb6\xbd\xc4\xcb\xd2\xd9"
+                       "\xe0\xe7\xee\xf5\xfc\x03\x0a\x11"
+                       "\x18\x1f\x26\x2d\x34\x3b\x42\x49"
+                       "\x50\x57\x5e\x65\x6c\x73\x7a\x81"
+                       "\x88\x8f\x96\x9d\xa4\xab\xb2\xb9"
+                       "\xc0\xc7\xce\xd5\xdc\xe3\xea\xf1"
+                       "\xf8\xff\x06\x0d\x14\x1b\x22\x29"
+                       "\x30\x37\x3e\x45\x4c\x53\x5a\x61"
+                       "\x68\x6f\x76\x7d\x84\x8b\x92\x99"
+                       "\xa0\xa7\xae\xb5\xbc\xc3\xca\xd1"
+                       "\xd8\xdf\xe6\xed\xf4\xfb\x02\x09"
+                       "\x10\x17\x1e\x25\x2c\x33\x3a\x41"
+                       "\x48\x4f\x56\x5d\x64\x6b\x72\x79"
+                       "\x80\x87\x8e\x95\x9c\xa3\xaa\xb1"
+                       "\xb8\xbf\xc6\xcd\xd4\xdb\xe2\xe9"
+                       "\xf0\xf7\xfe\x05\x0c\x13\x1a\x21"
+                       "\x28\x2f\x36\x3d\x44\x4b\x52\x59"
+                       "\x60\x67\x6e\x75\x7c\x83\x8a\x91"
+                       "\x98\x9f\xa6\xad\xb4\xbb\xc2\xc9"
+                       "\xd0\xd7\xde\xe5\xec\xf3\xfa\x01"
+                       "\x08\x0f\x16\x1d\x24\x2b\x32\x39"
+                       "\x40\x47\x4e\x55\x5c\x63\x6a\x71"
+                       "\x78\x7f\x86\x8d\x94\x9b\xa2\xa9"
+                       "\xb0\xb7\xbe\xc5\xcc\xd3\xda\xe1"
+                       "\xe8\xef\xf6\xfd\x04\x0b\x12\x19"
+                       "\x20\x27\x2e\x35\x3c\x43\x4a\x51"
+                       "\x58\x5f\x66\x6d\x74\x7b\x82\x89"
+                       "\x90\x97\x9e\xa5\xac\xb3\xba\xc1"
+                       "\xc8\xcf\xd6\xdd\xe4\xeb\xf2\xf9"
+                       "\x00\x09\x12\x1b\x24\x2d\x36\x3f"
+                       "\x48\x51\x5a\x63\x6c\x75\x7e\x87"
+                       "\x90\x99\xa2\xab\xb4\xbd\xc6\xcf"
+                       "\xd8\xe1\xea\xf3\xfc\x05\x0e\x17"
+                       "\x20\x29\x32\x3b\x44\x4d\x56\x5f"
+                       "\x68\x71\x7a\x83\x8c\x95\x9e\xa7"
+                       "\xb0\xb9\xc2\xcb\xd4\xdd\xe6\xef"
+                       "\xf8\x01\x0a\x13\x1c\x25\x2e\x37"
+                       "\x40\x49\x52\x5b\x64\x6d\x76\x7f"
+                       "\x88\x91\x9a\xa3\xac\xb5\xbe\xc7"
+                       "\xd0\xd9\xe2\xeb\xf4\xfd\x06\x0f"
+                       "\x18\x21\x2a\x33\x3c\x45\x4e\x57"
+                       "\x60\x69\x72\x7b\x84\x8d\x96\x9f"
+                       "\xa8\xb1\xba\xc3\xcc\xd5\xde\xe7"
+                       "\xf0\xf9\x02\x0b\x14\x1d\x26\x2f"
+                       "\x38\x41\x4a\x53\x5c\x65\x6e\x77"
+                       "\x80\x89\x92\x9b\xa4\xad\xb6\xbf"
+                       "\xc8\xd1\xda\xe3\xec\xf5\xfe\x07"
+                       "\x10\x19\x22\x2b\x34\x3d\x46\x4f"
+                       "\x58\x61\x6a\x73\x7c\x85\x8e\x97"
+                       "\xa0\xa9\xb2\xbb\xc4\xcd\xd6\xdf"
+                       "\xe8\xf1\xfa\x03\x0c\x15\x1e\x27"
+                       "\x30\x39\x42\x4b\x54\x5d\x66\x6f"
+                       "\x78\x81\x8a\x93\x9c\xa5\xae\xb7"
+                       "\xc0\xc9\xd2\xdb\xe4\xed\xf6\xff"
+                       "\x08\x11\x1a\x23\x2c\x35\x3e\x47"
+                       "\x50\x59\x62\x6b\x74\x7d\x86\x8f"
+                       "\x98\xa1\xaa\xb3\xbc\xc5\xce\xd7"
+                       "\xe0\xe9\xf2\xfb\x04\x0d\x16\x1f"
+                       "\x28\x31\x3a\x43\x4c\x55\x5e\x67"
+                       "\x70\x79\x82\x8b\x94\x9d\xa6\xaf"
+                       "\xb8\xc1\xca\xd3\xdc\xe5\xee\xf7"
+                       "\x00\x0b\x16\x21\x2c\x37\x42\x4d"
+                       "\x58\x63\x6e\x79\x84\x8f\x9a\xa5"
+                       "\xb0\xbb\xc6\xd1\xdc\xe7\xf2\xfd"
+                       "\x08\x13\x1e\x29\x34\x3f\x4a\x55"
+                       "\x60\x6b\x76\x81\x8c\x97\xa2\xad"
+                       "\xb8\xc3\xce\xd9\xe4\xef\xfa\x05"
+                       "\x10\x1b\x26\x31\x3c\x47\x52\x5d"
+                       "\x68\x73\x7e\x89\x94\x9f\xaa\xb5"
+                       "\xc0\xcb\xd6\xe1\xec\xf7\x02\x0d"
+                       "\x18\x23\x2e\x39\x44\x4f\x5a\x65"
+                       "\x70\x7b\x86\x91\x9c\xa7\xb2\xbd"
+                       "\xc8\xd3\xde\xe9\xf4\xff\x0a\x15"
+                       "\x20\x2b\x36\x41\x4c\x57\x62\x6d"
+                       "\x78\x83\x8e\x99\xa4\xaf\xba\xc5"
+                       "\xd0\xdb\xe6\xf1\xfc\x07\x12\x1d"
+                       "\x28\x33\x3e\x49\x54\x5f\x6a\x75"
+                       "\x80\x8b\x96\xa1\xac\xb7\xc2\xcd"
+                       "\xd8\xe3\xee\xf9\x04\x0f\x1a\x25"
+                       "\x30\x3b\x46\x51\x5c\x67\x72\x7d"
+                       "\x88\x93\x9e\xa9\xb4\xbf\xca\xd5"
+                       "\xe0\xeb\xf6\x01\x0c\x17\x22\x2d"
+                       "\x38\x43\x4e\x59\x64\x6f\x7a\x85"
+                       "\x90\x9b\xa6\xb1\xbc\xc7\xd2\xdd"
+                       "\xe8\xf3\xfe\x09\x14\x1f\x2a\x35"
+                       "\x40\x4b\x56\x61\x6c\x77\x82\x8d"
+                       "\x98\xa3\xae\xb9\xc4\xcf\xda\xe5"
+                       "\xf0\xfb\x06\x11\x1c\x27\x32\x3d"
+                       "\x48\x53\x5e\x69\x74\x7f\x8a\x95"
+                       "\xa0\xab\xb6\xc1\xcc\xd7\xe2\xed"
+                       "\xf8\x03\x0e\x19\x24\x2f\x3a\x45"
+                       "\x50\x5b\x66\x71\x7c\x87\x92\x9d"
+                       "\xa8\xb3\xbe\xc9\xd4\xdf\xea\xf5"
+                       "\x00\x0d\x1a\x27\x34\x41\x4e\x5b"
+                       "\x68\x75\x82\x8f\x9c\xa9\xb6\xc3"
+                       "\xd0\xdd\xea\xf7\x04\x11\x1e\x2b"
+                       "\x38\x45\x52\x5f\x6c\x79\x86\x93"
+                       "\xa0\xad\xba\xc7\xd4\xe1\xee\xfb"
+                       "\x08\x15\x22\x2f\x3c\x49\x56\x63"
+                       "\x70\x7d\x8a\x97\xa4\xb1\xbe\xcb"
+                       "\xd8\xe5\xf2\xff\x0c\x19\x26\x33"
+                       "\x40\x4d\x5a\x67\x74\x81\x8e\x9b"
+                       "\xa8\xb5\xc2\xcf\xdc\xe9\xf6\x03"
+                       "\x10\x1d\x2a\x37\x44\x51\x5e\x6b"
+                       "\x78\x85\x92\x9f\xac\xb9\xc6\xd3"
+                       "\xe0\xed\xfa\x07\x14\x21\x2e\x3b"
+                       "\x48\x55\x62\x6f\x7c\x89\x96\xa3"
+                       "\xb0\xbd\xca\xd7\xe4\xf1\xfe\x0b"
+                       "\x18\x25\x32\x3f\x4c\x59\x66\x73"
+                       "\x80\x8d\x9a\xa7\xb4\xc1\xce\xdb"
+                       "\xe8\xf5\x02\x0f\x1c\x29\x36\x43"
+                       "\x50\x5d\x6a\x77\x84\x91\x9e\xab"
+                       "\xb8\xc5\xd2\xdf\xec\xf9\x06\x13"
+                       "\x20\x2d\x3a\x47\x54\x61\x6e\x7b"
+                       "\x88\x95\xa2\xaf\xbc\xc9\xd6\xe3"
+                       "\xf0\xfd\x0a\x17\x24\x31\x3e\x4b"
+                       "\x58\x65\x72\x7f\x8c\x99\xa6\xb3"
+                       "\xc0\xcd\xda\xe7\xf4\x01\x0e\x1b"
+                       "\x28\x35\x42\x4f\x5c\x69\x76\x83"
+                       "\x90\x9d\xaa\xb7\xc4\xd1\xde\xeb"
+                       "\xf8\x05\x12\x1f\x2c\x39\x46\x53"
+                       "\x60\x6d\x7a\x87\x94\xa1\xae\xbb"
+                       "\xc8\xd5\xe2\xef\xfc\x09\x16\x23"
+                       "\x30\x3d\x4a\x57\x64\x71\x7e\x8b"
+                       "\x98\xa5\xb2\xbf\xcc\xd9\xe6\xf3"
+                       "\x00\x0f\x1e\x2d\x3c\x4b\x5a\x69"
+                       "\x78\x87\x96\xa5\xb4\xc3\xd2\xe1"
+                       "\xf0\xff\x0e\x1d\x2c\x3b\x4a\x59"
+                       "\x68\x77\x86\x95\xa4\xb3\xc2\xd1"
+                       "\xe0\xef\xfe\x0d\x1c\x2b\x3a\x49"
+                       "\x58\x67\x76\x85\x94\xa3\xb2\xc1"
+                       "\xd0\xdf\xee\xfd\x0c\x1b\x2a\x39"
+                       "\x48\x57\x66\x75\x84\x93\xa2\xb1"
+                       "\xc0\xcf\xde\xed\xfc\x0b\x1a\x29"
+                       "\x38\x47\x56\x65\x74\x83\x92\xa1"
+                       "\xb0\xbf\xce\xdd\xec\xfb\x0a\x19"
+                       "\x28\x37\x46\x55\x64\x73\x82\x91"
+                       "\xa0\xaf\xbe\xcd\xdc\xeb\xfa\x09"
+                       "\x18\x27\x36\x45\x54\x63\x72\x81"
+                       "\x90\x9f\xae\xbd\xcc\xdb\xea\xf9"
+                       "\x08\x17\x26\x35\x44\x53\x62\x71"
+                       "\x80\x8f\x9e\xad\xbc\xcb\xda\xe9"
+                       "\xf8\x07\x16\x25\x34\x43\x52\x61"
+                       "\x70\x7f\x8e\x9d\xac\xbb\xca\xd9"
+                       "\xe8\xf7\x06\x15\x24\x33\x42\x51"
+                       "\x60\x6f\x7e\x8d\x9c\xab\xba\xc9"
+                       "\xd8\xe7\xf6\x05\x14\x23\x32\x41"
+                       "\x50\x5f\x6e\x7d\x8c\x9b\xaa\xb9"
+                       "\xc8\xd7\xe6\xf5\x04\x13\x22\x31"
+                       "\x40\x4f\x5e\x6d\x7c\x8b\x9a\xa9"
+                       "\xb8\xc7\xd6\xe5\xf4\x03\x12\x21"
+                       "\x30\x3f\x4e\x5d\x6c\x7b\x8a\x99"
+                       "\xa8\xb7\xc6\xd5\xe4\xf3\x02\x11"
+                       "\x20\x2f\x3e\x4d\x5c\x6b\x7a\x89"
+                       "\x98\xa7\xb6\xc5\xd4\xe3\xf2\x01"
+                       "\x10\x1f\x2e\x3d\x4c\x5b\x6a\x79"
+                       "\x88\x97\xa6\xb5\xc4\xd3\xe2\xf1"
+                       "\x00\x11\x22\x33\x44\x55\x66\x77"
+                       "\x88\x99\xaa\xbb\xcc\xdd\xee\xff"
+                       "\x10\x21\x32\x43\x54\x65\x76\x87"
+                       "\x98\xa9\xba\xcb\xdc\xed\xfe\x0f"
+                       "\x20\x31\x42\x53\x64\x75\x86\x97"
+                       "\xa8\xb9\xca\xdb\xec\xfd\x0e\x1f"
+                       "\x30\x41\x52\x63\x74\x85\x96\xa7"
+                       "\xb8\xc9\xda\xeb\xfc\x0d\x1e\x2f"
+                       "\x40\x51\x62\x73\x84\x95\xa6\xb7"
+                       "\xc8\xd9\xea\xfb\x0c\x1d\x2e\x3f"
+                       "\x50\x61\x72\x83\x94\xa5\xb6\xc7"
+                       "\xd8\xe9\xfa\x0b\x1c\x2d\x3e\x4f"
+                       "\x60\x71\x82\x93\xa4\xb5\xc6\xd7"
+                       "\xe8\xf9\x0a\x1b\x2c\x3d\x4e\x5f"
+                       "\x70\x81\x92\xa3\xb4\xc5\xd6\xe7"
+                       "\xf8\x09\x1a\x2b\x3c\x4d\x5e\x6f"
+                       "\x80\x91\xa2\xb3\xc4\xd5\xe6\xf7"
+                       "\x08\x19\x2a\x3b\x4c\x5d\x6e\x7f"
+                       "\x90\xa1\xb2\xc3\xd4\xe5\xf6\x07"
+                       "\x18\x29\x3a\x4b\x5c\x6d\x7e\x8f"
+                       "\xa0\xb1\xc2\xd3\xe4\xf5\x06\x17"
+                       "\x28\x39\x4a\x5b\x6c\x7d\x8e\x9f"
+                       "\xb0\xc1\xd2\xe3\xf4\x05\x16\x27"
+                       "\x38\x49\x5a\x6b\x7c\x8d\x9e\xaf"
+                       "\xc0\xd1\xe2\xf3\x04\x15\x26\x37"
+                       "\x48\x59\x6a\x7b\x8c\x9d\xae\xbf"
+                       "\xd0\xe1\xf2\x03\x14\x25\x36\x47"
+                       "\x58\x69\x7a\x8b\x9c\xad\xbe\xcf"
+                       "\xe0\xf1\x02\x13\x24\x35\x46\x57"
+                       "\x68\x79\x8a\x9b\xac\xbd\xce\xdf"
+                       "\xf0\x01\x12\x23\x34\x45\x56\x67"
+                       "\x78\x89\x9a\xab\xbc\xcd\xde\xef"
+                       "\x00\x13\x26\x39\x4c\x5f\x72\x85"
+                       "\x98\xab\xbe\xd1\xe4\xf7\x0a\x1d"
+                       "\x30\x43\x56\x69\x7c\x8f\xa2\xb5"
+                       "\xc8\xdb\xee\x01\x14\x27\x3a\x4d"
+                       "\x60\x73\x86\x99\xac\xbf\xd2\xe5"
+                       "\xf8\x0b\x1e\x31\x44\x57\x6a\x7d"
+                       "\x90\xa3\xb6\xc9\xdc\xef\x02\x15"
+                       "\x28\x3b\x4e\x61\x74\x87\x9a\xad"
+                       "\xc0\xd3\xe6\xf9\x0c\x1f\x32\x45"
+                       "\x58\x6b\x7e\x91\xa4\xb7\xca\xdd"
+                       "\xf0\x03\x16\x29\x3c\x4f\x62\x75"
+                       "\x88\x9b\xae\xc1\xd4\xe7\xfa\x0d"
+                       "\x20\x33\x46\x59\x6c\x7f\x92\xa5"
+                       "\xb8\xcb\xde\xf1\x04\x17\x2a\x3d"
+                       "\x50\x63\x76\x89\x9c\xaf\xc2\xd5"
+                       "\xe8\xfb\x0e\x21\x34\x47\x5a\x6d"
+                       "\x80\x93\xa6\xb9\xcc\xdf\xf2\x05"
+                       "\x18\x2b\x3e\x51\x64\x77\x8a\x9d"
+                       "\xb0\xc3\xd6\xe9\xfc\x0f\x22\x35"
+                       "\x48\x5b\x6e\x81\x94\xa7\xba\xcd"
+                       "\xe0\xf3\x06\x19\x2c\x3f\x52\x65"
+                       "\x78\x8b\x9e\xb1\xc4\xd7\xea\xfd"
+                       "\x10\x23\x36\x49\x5c\x6f\x82\x95"
+                       "\xa8\xbb\xce\xe1\xf4\x07\x1a\x2d"
+                       "\x40\x53\x66\x79\x8c\x9f\xb2\xc5"
+                       "\xd8\xeb\xfe\x11\x24\x37\x4a\x5d"
+                       "\x70\x83\x96\xa9\xbc\xcf\xe2\xf5"
+                       "\x08\x1b\x2e\x41\x54\x67\x7a\x8d"
+                       "\xa0\xb3\xc6\xd9\xec\xff\x12\x25"
+                       "\x38\x4b\x5e\x71\x84\x97\xaa\xbd"
+                       "\xd0\xe3\xf6\x09\x1c\x2f\x42\x55"
+                       "\x68\x7b\x8e\xa1\xb4\xc7\xda\xed"
+                       "\x00\x15\x2a\x3f\x54\x69\x7e\x93"
+                       "\xa8\xbd\xd2\xe7\xfc\x11\x26\x3b"
+                       "\x50\x65\x7a\x8f\xa4\xb9\xce\xe3"
+                       "\xf8\x0d\x22\x37\x4c\x61\x76\x8b"
+                       "\xa0\xb5\xca\xdf\xf4\x09\x1e\x33"
+                       "\x48\x5d\x72\x87\x9c\xb1\xc6\xdb"
+                       "\xf0\x05\x1a\x2f\x44\x59\x6e\x83"
+                       "\x98\xad\xc2\xd7\xec\x01\x16\x2b"
+                       "\x40\x55\x6a\x7f\x94\xa9\xbe\xd3"
+                       "\xe8\xfd\x12\x27\x3c\x51\x66\x7b"
+                       "\x90\xa5\xba\xcf\xe4\xf9\x0e\x23"
+                       "\x38\x4d\x62\x77\x8c\xa1\xb6\xcb"
+                       "\xe0\xf5\x0a\x1f\x34\x49\x5e\x73"
+                       "\x88\x9d\xb2\xc7\xdc\xf1\x06\x1b"
+                       "\x30\x45\x5a\x6f\x84\x99\xae\xc3"
+                       "\xd8\xed\x02\x17\x2c\x41\x56\x6b"
+                       "\x80\x95\xaa\xbf\xd4\xe9\xfe\x13"
+                       "\x28\x3d\x52\x67\x7c\x91\xa6\xbb"
+                       "\xd0\xe5\xfa\x0f\x24\x39\x4e\x63"
+                       "\x78\x8d\xa2\xb7\xcc\xe1\xf6\x0b"
+                       "\x20\x35\x4a\x5f\x74\x89\x9e\xb3"
+                       "\xc8\xdd\xf2\x07\x1c\x31\x46\x5b"
+                       "\x70\x85\x9a\xaf\xc4\xd9\xee\x03"
+                       "\x18\x2d\x42\x57\x6c\x81\x96\xab"
+                       "\xc0\xd5\xea\xff\x14\x29\x3e\x53"
+                       "\x68\x7d\x92\xa7\xbc\xd1\xe6\xfb"
+                       "\x10\x25\x3a\x4f\x64\x79\x8e\xa3"
+                       "\xb8\xcd\xe2\xf7\x0c\x21\x36\x4b"
+                       "\x60\x75\x8a\x9f\xb4\xc9\xde\xf3"
+                       "\x08\x1d\x32\x47\x5c\x71\x86\x9b"
+                       "\xb0\xc5\xda\xef\x04\x19\x2e\x43"
+                       "\x58\x6d\x82\x97\xac\xc1\xd6\xeb"
+                       "\x00\x17\x2e\x45\x5c\x73\x8a\xa1"
+                       "\xb8\xcf\xe6\xfd\x14\x2b\x42\x59"
+                       "\x70\x87\x9e\xb5\xcc\xe3\xfa\x11"
+                       "\x28\x3f\x56\x6d\x84\x9b\xb2\xc9"
+                       "\xe0\xf7\x0e\x25\x3c\x53\x6a\x81"
+                       "\x98\xaf\xc6\xdd\xf4\x0b\x22\x39"
+                       "\x50\x67\x7e\x95\xac\xc3\xda\xf1"
+                       "\x08\x1f\x36\x4d\x64\x7b\x92\xa9"
+                       "\xc0\xd7\xee\x05\x1c\x33\x4a\x61"
+                       "\x78\x8f\xa6\xbd\xd4\xeb\x02\x19"
+                       "\x30\x47\x5e\x75\x8c\xa3\xba\xd1"
+                       "\xe8\xff\x16\x2d\x44\x5b\x72\x89"
+                       "\xa0\xb7\xce\xe5\xfc\x13\x2a\x41"
+                       "\x58\x6f\x86\x9d\xb4\xcb\xe2\xf9"
+                       "\x10\x27\x3e\x55\x6c\x83\x9a\xb1"
+                       "\xc8\xdf\xf6\x0d\x24\x3b\x52\x69"
+                       "\x80\x97\xae\xc5\xdc\xf3\x0a\x21"
+                       "\x38\x4f\x66\x7d\x94\xab\xc2\xd9"
+                       "\xf0\x07\x1e\x35\x4c\x63\x7a\x91"
+                       "\xa8\xbf\xd6\xed\x04\x1b\x32\x49"
+                       "\x60\x77\x8e\xa5\xbc\xd3\xea\x01"
+                       "\x18\x2f\x46\x5d\x74\x8b\xa2\xb9"
+                       "\xd0\xe7\xfe\x15\x2c\x43\x5a\x71"
+                       "\x88\x9f\xb6\xcd\xe4\xfb\x12\x29"
+                       "\x40\x57\x6e\x85\x9c\xb3\xca\xe1"
+                       "\xf8\x0f\x26\x3d\x54\x6b\x82\x99"
+                       "\xb0\xc7\xde\xf5\x0c\x23\x3a\x51"
+                       "\x68\x7f\x96\xad\xc4\xdb\xf2\x09"
+                       "\x20\x37\x4e\x65\x7c\x93\xaa\xc1"
+                       "\xd8\xef\x06\x1d\x34\x4b\x62\x79"
+                       "\x90\xa7\xbe\xd5\xec\x03\x1a\x31"
+                       "\x48\x5f\x76\x8d\xa4\xbb\xd2\xe9"
+                       "\x00\x19\x32\x4b\x64\x7d\x96\xaf"
+                       "\xc8\xe1\xfa\x13\x2c\x45\x5e\x77"
+                       "\x90\xa9\xc2\xdb\xf4\x0d\x26\x3f"
+                       "\x58\x71\x8a\xa3\xbc\xd5\xee\x07"
+                       "\x20\x39\x52\x6b\x84\x9d\xb6\xcf"
+                       "\xe8\x01\x1a\x33\x4c\x65\x7e\x97"
+                       "\xb0\xc9\xe2\xfb\x14\x2d\x46\x5f"
+                       "\x78\x91\xaa\xc3\xdc\xf5\x0e\x27"
+                       "\x40\x59\x72\x8b\xa4\xbd\xd6\xef"
+                       "\x08\x21\x3a\x53\x6c\x85\x9e\xb7"
+                       "\xd0\xe9\x02\x1b\x34\x4d\x66\x7f"
+                       "\x98\xb1\xca\xe3\xfc\x15\x2e\x47"
+                       "\x60\x79\x92\xab\xc4\xdd\xf6\x0f"
+                       "\x28\x41\x5a\x73\x8c\xa5\xbe\xd7"
+                       "\xf0\x09\x22\x3b\x54\x6d\x86\x9f"
+                       "\xb8\xd1\xea\x03\x1c\x35\x4e\x67"
+                       "\x80\x99\xb2\xcb\xe4\xfd\x16\x2f"
+                       "\x48\x61\x7a\x93\xac\xc5\xde\xf7"
+                       "\x10\x29\x42\x5b\x74\x8d\xa6\xbf"
+                       "\xd8\xf1\x0a\x23\x3c\x55\x6e\x87"
+                       "\xa0\xb9\xd2\xeb\x04\x1d\x36\x4f"
+                       "\x68\x81\x9a\xb3\xcc\xe5\xfe\x17"
+                       "\x30\x49\x62\x7b\x94\xad\xc6\xdf"
+                       "\xf8\x11\x2a\x43\x5c\x75\x8e\xa7"
+                       "\xc0\xd9\xf2\x0b\x24\x3d\x56\x6f"
+                       "\x88\xa1\xba\xd3\xec\x05\x1e\x37"
+                       "\x50\x69\x82\x9b\xb4\xcd\xe6\xff"
+                       "\x18\x31\x4a\x63\x7c\x95\xae\xc7"
+                       "\xe0\xf9\x12\x2b\x44\x5d\x76\x8f"
+                       "\xa8\xc1\xda\xf3\x0c\x25\x3e\x57"
+                       "\x70\x89\xa2\xbb\xd4\xed\x06\x1f"
+                       "\x38\x51\x6a\x83\x9c\xb5\xce\xe7"
+                       "\x00\x1b\x36\x51\x6c\x87\xa2\xbd"
+                       "\xd8\xf3\x0e\x29\x44\x5f\x7a\x95"
+                       "\xb0\xcb\xe6\x01\x1c\x37\x52\x6d"
+                       "\x88\xa3\xbe\xd9\xf4\x0f\x2a\x45"
+                       "\x60\x7b\x96\xb1\xcc\xe7\x02\x1d"
+                       "\x38\x53\x6e\x89\xa4\xbf\xda\xf5"
+                       "\x10\x2b\x46\x61\x7c\x97\xb2\xcd"
+                       "\xe8\x03\x1e\x39\x54\x6f\x8a\xa5"
+                       "\xc0\xdb\xf6\x11\x2c\x47\x62\x7d"
+                       "\x98\xb3\xce\xe9\x04\x1f\x3a\x55"
+                       "\x70\x8b\xa6\xc1\xdc\xf7\x12\x2d"
+                       "\x48\x63\x7e\x99\xb4\xcf\xea\x05"
+                       "\x20\x3b\x56\x71\x8c\xa7\xc2\xdd"
+                       "\xf8\x13\x2e\x49\x64\x7f\x9a\xb5"
+                       "\xd0\xeb\x06\x21\x3c\x57\x72\x8d"
+                       "\xa8\xc3\xde\xf9\x14\x2f\x4a\x65"
+                       "\x80\x9b\xb6\xd1\xec\x07\x22\x3d"
+                       "\x58\x73\x8e\xa9\xc4\xdf\xfa\x15"
+                       "\x30\x4b\x66\x81\x9c\xb7\xd2\xed"
+                       "\x08\x23\x3e\x59\x74\x8f\xaa\xc5"
+                       "\xe0\xfb\x16\x31\x4c\x67\x82\x9d"
+                       "\xb8\xd3\xee\x09\x24\x3f\x5a\x75"
+                       "\x90\xab\xc6\xe1\xfc\x17\x32\x4d"
+                       "\x68\x83\x9e\xb9\xd4\xef\x0a\x25"
+                       "\x40\x5b\x76\x91\xac\xc7\xe2\xfd"
+                       "\x18\x33\x4e\x69\x84\x9f\xba\xd5"
+                       "\xf0\x0b\x26\x41\x5c\x77\x92\xad"
+                       "\xc8\xe3\xfe\x19\x34\x4f\x6a\x85"
+                       "\xa0\xbb\xd6\xf1\x0c\x27\x42\x5d"
+                       "\x78\x93\xae\xc9\xe4\xff\x1a\x35"
+                       "\x50\x6b\x86\xa1\xbc\xd7\xf2\x0d"
+                       "\x28\x43\x5e\x79\x94\xaf\xca\xe5"
+                       "\x00\x1d\x3a\x57\x74\x91\xae\xcb"
+                       "\xe8\x05\x22\x3f\x5c\x79\x96\xb3"
+                       "\xd0\xed\x0a\x27\x44\x61\x7e\x9b"
+                       "\xb8\xd5\xf2\x0f\x2c\x49\x66\x83"
+                       "\xa0\xbd\xda\xf7\x14\x31\x4e\x6b"
+                       "\x88\xa5\xc2\xdf\xfc\x19\x36\x53"
+                       "\x70\x8d\xaa\xc7\xe4\x01\x1e\x3b"
+                       "\x58\x75\x92\xaf\xcc\xe9\x06\x23"
+                       "\x40\x5d\x7a\x97\xb4\xd1\xee\x0b"
+                       "\x28\x45\x62\x7f\x9c\xb9\xd6\xf3"
+                       "\x10\x2d\x4a\x67\x84\xa1\xbe\xdb"
+                       "\xf8\x15\x32\x4f\x6c\x89\xa6\xc3"
+                       "\xe0\xfd\x1a\x37\x54\x71\x8e\xab"
+                       "\xc8\xe5\x02\x1f\x3c\x59\x76\x93"
+                       "\xb0\xcd\xea\x07\x24\x41\x5e\x7b"
+                       "\x98\xb5\xd2\xef\x0c\x29\x46\x63"
+                       "\x80\x9d\xba\xd7\xf4\x11\x2e\x4b"
+                       "\x68\x85\xa2\xbf\xdc\xf9\x16\x33"
+                       "\x50\x6d\x8a\xa7\xc4\xe1\xfe\x1b"
+                       "\x38\x55\x72\x8f\xac\xc9\xe6\x03"
+                       "\x20\x3d\x5a\x77\x94\xb1\xce\xeb"
+                       "\x08\x25\x42\x5f\x7c\x99\xb6\xd3"
+                       "\xf0\x0d\x2a\x47\x64\x81\x9e\xbb"
+                       "\xd8\xf5\x12\x2f\x4c\x69\x86\xa3"
+                       "\xc0\xdd\xfa\x17\x34\x51\x6e\x8b"
+                       "\xa8\xc5\xe2\xff\x1c\x39\x56\x73"
+                       "\x90\xad\xca\xe7\x04\x21\x3e\x5b"
+                       "\x78\x95\xb2\xcf\xec\x09\x26\x43"
+                       "\x60\x7d\x9a\xb7\xd4\xf1\x0e\x2b"
+                       "\x48\x65\x82\x9f\xbc\xd9\xf6\x13"
+                       "\x30\x4d\x6a\x87\xa4\xc1\xde\xfb"
+                       "\x18\x35\x52\x6f\x8c\xa9\xc6\xe3"
+                       "\x00\x1f\x3e\x5d\x7c\x9b\xba\xd9"
+                       "\xf8\x17\x36\x55\x74\x93\xb2\xd1"
+                       "\xf0\x0f\x2e\x4d\x6c\x8b\xaa\xc9"
+                       "\xe8\x07\x26\x45\x64\x83\xa2\xc1"
+                       "\xe0\xff\x1e\x3d\x5c\x7b\x9a\xb9"
+                       "\xd8\xf7\x16\x35\x54\x73\x92\xb1"
+                       "\xd0\xef\x0e\x2d\x4c\x6b\x8a\xa9"
+                       "\xc8\xe7\x06\x25\x44\x63\x82\xa1"
+                       "\xc0\xdf\xfe\x1d\x3c\x5b\x7a\x99"
+                       "\xb8\xd7\xf6\x15\x34\x53\x72\x91"
+                       "\xb0\xcf\xee\x0d\x2c\x4b\x6a\x89"
+                       "\xa8\xc7\xe6\x05\x24\x43\x62\x81"
+                       "\xa0\xbf\xde\xfd\x1c\x3b\x5a\x79"
+                       "\x98\xb7\xd6\xf5\x14\x33\x52\x71"
+                       "\x90\xaf\xce\xed\x0c\x2b\x4a\x69"
+                       "\x88\xa7\xc6\xe5\x04\x23\x42\x61"
+                       "\x80\x9f\xbe\xdd\xfc\x1b\x3a\x59"
+                       "\x78\x97\xb6\xd5\xf4\x13\x32\x51"
+                       "\x70\x8f\xae\xcd\xec\x0b\x2a\x49"
+                       "\x68\x87\xa6\xc5\xe4\x03\x22\x41"
+                       "\x60\x7f\x9e\xbd\xdc\xfb\x1a\x39"
+                       "\x58\x77\x96\xb5\xd4\xf3\x12\x31"
+                       "\x50\x6f\x8e\xad\xcc\xeb\x0a\x29"
+                       "\x48\x67\x86\xa5\xc4\xe3\x02\x21"
+                       "\x40\x5f\x7e\x9d\xbc\xdb\xfa\x19"
+                       "\x38\x57\x76\x95\xb4\xd3\xf2\x11"
+                       "\x30\x4f\x6e\x8d\xac\xcb\xea\x09"
+                       "\x28\x47\x66\x85\xa4\xc3\xe2\x01"
+                       "\x20\x3f\x5e\x7d\x9c\xbb\xda\xf9"
+                       "\x18\x37\x56\x75\x94\xb3\xd2\xf1"
+                       "\x10\x2f\x4e\x6d\x8c\xab\xca\xe9"
+                       "\x08\x27\x46\x65\x84\xa3\xc2\xe1"
+                       "\x00\x21\x42\x63",
+               .ilen = 4100,
+               .result =
+                       "\xf0\x5c\x74\xad\x4e\xbc\x99\xe2"
+                       "\xae\xff\x91\x3a\x44\xcf\x38\x32"
+                       "\x1e\xad\xa7\xcd\xa1\x39\x95\xaa"
+                       "\x10\xb1\xb3\x2e\x04\x31\x8f\x86"
+                       "\xf2\x62\x74\x70\x0c\xa4\x46\x08"
+                       "\xa8\xb7\x99\xa8\xe9\xd2\x73\x79"
+                       "\x7e\x6e\xd4\x8f\x1e\xc7\x8e\x31"
+                       "\x0b\xfa\x4b\xce\xfd\xf3\x57\x71"
+                       "\xe9\x46\x03\xa5\x3d\x34\x00\xe2"
+                       "\x18\xff\x75\x6d\x06\x2d\x00\xab"
+                       "\xb9\x3e\x6c\x59\xc5\x84\x06\xb5"
+                       "\x8b\xd0\x89\x9c\x4a\x79\x16\xc6"
+                       "\x3d\x74\x54\xfa\x44\xcd\x23\x26"
+                       "\x5c\xcf\x7e\x28\x92\x32\xbf\xdf"
+                       "\xa7\x20\x3c\x74\x58\x2a\x9a\xde"
+                       "\x61\x00\x1c\x4f\xff\x59\xc4\x22"
+                       "\xac\x3c\xd0\xe8\x6c\xf9\x97\x1b"
+                       "\x58\x9b\xad\x71\xe8\xa9\xb5\x0d"
+                       "\xee\x2f\x04\x1f\x7f\xbc\x99\xee"
+                       "\x84\xff\x42\x60\xdc\x3a\x18\xa5"
+                       "\x81\xf9\xef\xdc\x7a\x0f\x65\x41"
+                       "\x2f\xa3\xd3\xf9\xc2\xcb\xc0\x4d"
+                       "\x8f\xd3\x76\x96\xad\x49\x6d\x38"
+                       "\x3d\x39\x0b\x6c\x80\xb7\x54\x69"
+                       "\xf0\x2c\x90\x02\x29\x0d\x1c\x12"
+                       "\xad\x55\xc3\x8b\x68\xd9\xcc\xb3"
+                       "\xb2\x64\x33\x90\x5e\xca\x4b\xe2"
+                       "\xfb\x75\xdc\x63\xf7\x9f\x82\x74"
+                       "\xf0\xc9\xaa\x7f\xe9\x2a\x9b\x33"
+                       "\xbc\x88\x00\x7f\xca\xb2\x1f\x14"
+                       "\xdb\xc5\x8e\x7b\x11\x3c\x3e\x08"
+                       "\xf3\x83\xe8\xe0\x94\x86\x2e\x92"
+                       "\x78\x6b\x01\xc9\xc7\x83\xba\x21"
+                       "\x6a\x25\x15\x33\x4e\x45\x08\xec"
+                       "\x35\xdb\xe0\x6e\x31\x51\x79\xa9"
+                       "\x42\x44\x65\xc1\xa0\xf1\xf9\x2a"
+                       "\x70\xd5\xb6\xc6\xc1\x8c\x39\xfc"
+                       "\x25\xa6\x55\xd9\xdd\x2d\x4c\xec"
+                       "\x49\xc6\xeb\x0e\xa8\x25\x2a\x16"
+                       "\x1b\x66\x84\xda\xe2\x92\xe5\xc0"
+                       "\xc8\x53\x07\xaf\x80\x84\xec\xfd"
+                       "\xcd\xd1\x6e\xcd\x6f\x6a\xf5\x36"
+                       "\xc5\x15\xe5\x25\x7d\x77\xd1\x1a"
+                       "\x93\x36\xa9\xcf\x7c\xa4\x54\x4a"
+                       "\x06\x51\x48\x4e\xf6\x59\x87\xd2"
+                       "\x04\x02\xef\xd3\x44\xde\x76\x31"
+                       "\xb3\x34\x17\x1b\x9d\x66\x11\x9f"
+                       "\x1e\xcc\x17\xe9\xc7\x3c\x1b\xe7"
+                       "\xcb\x50\x08\xfc\xdc\x2b\x24\xdb"
+                       "\x65\x83\xd0\x3b\xe3\x30\xea\x94"
+                       "\x6c\xe7\xe8\x35\x32\xc7\xdb\x64"
+                       "\xb4\x01\xab\x36\x2c\x77\x13\xaf"
+                       "\xf8\x2b\x88\x3f\x54\x39\xc4\x44"
+                       "\xfe\xef\x6f\x68\x34\xbe\x0f\x05"
+                       "\x16\x6d\xf6\x0a\x30\xe7\xe3\xed"
+                       "\xc4\xde\x3c\x1b\x13\xd8\xdb\xfe"
+                       "\x41\x62\xe5\x28\xd4\x8d\xa3\xc7"
+                       "\x93\x97\xc6\x48\x45\x1d\x9f\x83"
+                       "\xdf\x4b\x40\x3e\x42\x25\x87\x80"
+                       "\x4c\x7d\xa8\xd4\x98\x23\x95\x75"
+                       "\x41\x8c\xda\x41\x9b\xd4\xa7\x06"
+                       "\xb5\xf1\x71\x09\x53\xbe\xca\xbf"
+                       "\x32\x03\xed\xf0\x50\x1c\x56\x39"
+                       "\x5b\xa4\x75\x18\xf7\x9b\x58\xef"
+                       "\x53\xfc\x2a\x38\x23\x15\x75\xcd"
+                       "\x45\xe5\x5a\x82\x55\xba\x21\xfa"
+                       "\xd4\xbd\xc6\x94\x7c\xc5\x80\x12"
+                       "\xf7\x4b\x32\xc4\x9a\x82\xd8\x28"
+                       "\x8f\xd9\xc2\x0f\x60\x03\xbe\x5e"
+                       "\x21\xd6\x5f\x58\xbf\x5c\xb1\x32"
+                       "\x82\x8d\xa9\xe5\xf2\x66\x1a\xc0"
+                       "\xa0\xbc\x58\x2f\x71\xf5\x2f\xed"
+                       "\xd1\x26\xb9\xd8\x49\x5a\x07\x19"
+                       "\x01\x7c\x59\xb0\xf8\xa4\xb7\xd3"
+                       "\x7b\x1a\x8c\x38\xf4\x50\xa4\x59"
+                       "\xb0\xcc\x41\x0b\x88\x7f\xe5\x31"
+                       "\xb3\x42\xba\xa2\x7e\xd4\x32\x71"
+                       "\x45\x87\x48\xa9\xc2\xf2\x89\xb3"
+                       "\xe4\xa7\x7e\x52\x15\x61\xfa\xfe"
+                       "\xc9\xdd\x81\xeb\x13\xab\xab\xc3"
+                       "\x98\x59\xd8\x16\x3d\x14\x7a\x1c"
+                       "\x3c\x41\x9a\x16\x16\x9b\xd2\xd2"
+                       "\x69\x3a\x29\x23\xac\x86\x32\xa5"
+                       "\x48\x9c\x9e\xf3\x47\x77\x81\x70"
+                       "\x24\xe8\x85\xd2\xf5\xb5\xfa\xff"
+                       "\x59\x6a\xd3\x50\x59\x43\x59\xde"
+                       "\xd9\xf1\x55\xa5\x0c\xc3\x1a\x1a"
+                       "\x18\x34\x0d\x1a\x63\x33\xed\x10"
+                       "\xe0\x1d\x2a\x18\xd2\xc0\x54\xa8"
+                       "\xca\xb5\x9a\xd3\xdd\xca\x45\x84"
+                       "\x50\xe7\x0f\xfe\xa4\x99\x5a\xbe"
+                       "\x43\x2d\x9a\xcb\x92\x3f\x5a\x1d"
+                       "\x85\xd8\xc9\xdf\x68\xc9\x12\x80"
+                       "\x56\x0c\xdc\x00\xdc\x3a\x7d\x9d"
+                       "\xa3\xa2\xe8\x4d\xbf\xf9\x70\xa0"
+                       "\xa4\x13\x4f\x6b\xaf\x0a\x89\x7f"
+                       "\xda\xf0\xbf\x9b\xc8\x1d\xe5\xf8"
+                       "\x2e\x8b\x07\xb5\x73\x1b\xcc\xa2"
+                       "\xa6\xad\x30\xbc\x78\x3c\x5b\x10"
+                       "\xfa\x5e\x62\x2d\x9e\x64\xb3\x33"
+                       "\xce\xf9\x1f\x86\xe7\x8b\xa2\xb8"
+                       "\xe8\x99\x57\x8c\x11\xed\x66\xd9"
+                       "\x3c\x72\xb9\xc3\xe6\x4e\x17\x3a"
+                       "\x6a\xcb\x42\x24\x06\xed\x3e\x4e"
+                       "\xa3\xe8\x6a\x94\xda\x0d\x4e\xd5"
+                       "\x14\x19\xcf\xb6\x26\xd8\x2e\xcc"
+                       "\x64\x76\x38\x49\x4d\xfe\x30\x6d"
+                       "\xe4\xc8\x8c\x7b\xc4\xe0\x35\xba"
+                       "\x22\x6e\x76\xe1\x1a\xf2\x53\xc3"
+                       "\x28\xa2\x82\x1f\x61\x69\xad\xc1"
+                       "\x7b\x28\x4b\x1e\x6c\x85\x95\x9b"
+                       "\x51\xb5\x17\x7f\x12\x69\x8c\x24"
+                       "\xd5\xc7\x5a\x5a\x11\x54\xff\x5a"
+                       "\xf7\x16\xc3\x91\xa6\xf0\xdc\x0a"
+                       "\xb6\xa7\x4a\x0d\x7a\x58\xfe\xa5"
+                       "\xf5\xcb\x8f\x7b\x0e\xea\x57\xe7"
+                       "\xbd\x79\xd6\x1c\x88\x23\x6c\xf2"
+                       "\x4d\x29\x77\x53\x35\x6a\x00\x8d"
+                       "\xcd\xa3\x58\xbe\x77\x99\x18\xf8"
+                       "\xe6\xe1\x8f\xe9\x37\x8f\xe3\xe2"
+                       "\x5a\x8a\x93\x25\xaf\xf3\x78\x80"
+                       "\xbe\xa6\x1b\xc6\xac\x8b\x1c\x91"
+                       "\x58\xe1\x9f\x89\x35\x9d\x1d\x21"
+                       "\x29\x9f\xf4\x99\x02\x27\x0f\xa8"
+                       "\x4f\x79\x94\x2b\x33\x2c\xda\xa2"
+                       "\x26\x39\x83\x94\xef\x27\xd8\x53"
+                       "\x8f\x66\x0d\xe4\x41\x7d\x34\xcd"
+                       "\x43\x7c\x95\x0a\x53\xef\x66\xda"
+                       "\x7e\x9b\xf3\x93\xaf\xd0\x73\x71"
+                       "\xba\x40\x9b\x74\xf8\xd7\xd7\x41"
+                       "\x6d\xaf\x72\x9c\x8d\x21\x87\x3c"
+                       "\xfd\x0a\x90\xa9\x47\x96\x9e\xd3"
+                       "\x88\xee\x73\xcf\x66\x2f\x52\x56"
+                       "\x6d\xa9\x80\x4c\xe2\x6f\x62\x88"
+                       "\x3f\x0e\x54\x17\x48\x80\x5d\xd3"
+                       "\xc3\xda\x25\x3d\xa1\xc8\xcb\x9f"
+                       "\x9b\x70\xb3\xa1\xeb\x04\x52\xa1"
+                       "\xf2\x22\x0f\xfc\xc8\x18\xfa\xf9"
+                       "\x85\x9c\xf1\xac\xeb\x0c\x02\x46"
+                       "\x75\xd2\xf5\x2c\xe3\xd2\x59\x94"
+                       "\x12\xf3\x3c\xfc\xd7\x92\xfa\x36"
+                       "\xba\x61\x34\x38\x7c\xda\x48\x3e"
+                       "\x08\xc9\x39\x23\x5e\x02\x2c\x1a"
+                       "\x18\x7e\xb4\xd9\xfd\x9e\x40\x02"
+                       "\xb1\x33\x37\x32\xe7\xde\xd6\xd0"
+                       "\x7c\x58\x65\x4b\xf8\x34\x27\x9c"
+                       "\x44\xb4\xbd\xe9\xe9\x4c\x78\x7d"
+                       "\x4b\x9f\xce\xb1\xcd\x47\xa5\x37"
+                       "\xe5\x6d\xbd\xb9\x43\x94\x0a\xd4"
+                       "\xd6\xf9\x04\x5f\xb5\x66\x6c\x1a"
+                       "\x35\x12\xe3\x36\x28\x27\x36\x58"
+                       "\x01\x2b\x79\xe4\xba\x6d\x10\x7d"
+                       "\x65\xdf\x84\x95\xf4\xd5\xb6\x8f"
+                       "\x2b\x9f\x96\x00\x86\x60\xf0\x21"
+                       "\x76\xa8\x6a\x8c\x28\x1c\xb3\x6b"
+                       "\x97\xd7\xb6\x53\x2a\xcc\xab\x40"
+                       "\x9d\x62\x79\x58\x52\xe6\x65\xb7"
+                       "\xab\x55\x67\x9c\x89\x7c\x03\xb0"
+                       "\x73\x59\xc5\x81\xf5\x18\x17\x5c"
+                       "\x89\xf3\x78\x35\x44\x62\x78\x72"
+                       "\xd0\x96\xeb\x31\xe7\x87\x77\x14"
+                       "\x99\x51\xf2\x59\x26\x9e\xb5\xa6"
+                       "\x45\xfe\x6e\xbd\x07\x4c\x94\x5a"
+                       "\xa5\x7d\xfc\xf1\x2b\x77\xe2\xfe"
+                       "\x17\xd4\x84\xa0\xac\xb5\xc7\xda"
+                       "\xa9\x1a\xb6\xf3\x74\x11\xb4\x9d"
+                       "\xfb\x79\x2e\x04\x2d\x50\x28\x83"
+                       "\xbf\xc6\x52\xd3\x34\xd6\xe8\x7a"
+                       "\xb6\xea\xe7\xa8\x6c\x15\x1e\x2c"
+                       "\x57\xbc\x48\x4e\x5f\x5c\xb6\x92"
+                       "\xd2\x49\x77\x81\x6d\x90\x70\xae"
+                       "\x98\xa1\x03\x0d\x6b\xb9\x77\x14"
+                       "\xf1\x4e\x23\xd3\xf8\x68\xbd\xc2"
+                       "\xfe\x04\xb7\x5c\xc5\x17\x60\x8f"
+                       "\x65\x54\xa4\x7a\x42\xdc\x18\x0d"
+                       "\xb5\xcf\x0f\xd3\xc7\x91\x66\x1b"
+                       "\x45\x42\x27\x75\x50\xe5\xee\xb8"
+                       "\x7f\x33\x2c\xba\x4a\x92\x4d\x2c"
+                       "\x3c\xe3\x0d\x80\x01\xba\x0d\x29"
+                       "\xd8\x3c\xe9\x13\x16\x57\xe6\xea"
+                       "\x94\x52\xe7\x00\x4d\x30\xb0\x0f"
+                       "\x35\xb8\xb8\xa7\xb1\xb5\x3b\x44"
+                       "\xe1\x2f\xfd\x88\xed\x43\xe7\x52"
+                       "\x10\x93\xb3\x8a\x30\x6b\x0a\xf7"
+                       "\x23\xc6\x50\x9d\x4a\xb0\xde\xc3"
+                       "\xdc\x9b\x2f\x01\x56\x36\x09\xc5"
+                       "\x2f\x6b\xfe\xf1\xd8\x27\x45\x03"
+                       "\x30\x5e\x5c\x5b\xb4\x62\x0e\x1a"
+                       "\xa9\x21\x2b\x92\x94\x87\x62\x57"
+                       "\x4c\x10\x74\x1a\xf1\x0a\xc5\x84"
+                       "\x3b\x9e\x72\x02\xd7\xcc\x09\x56"
+                       "\xbd\x54\xc1\xf0\xc3\xe3\xb3\xf8"
+                       "\xd2\x0d\x61\xcb\xef\xce\x0d\x05"
+                       "\xb0\x98\xd9\x8e\x4f\xf9\xbc\x93"
+                       "\xa6\xea\xc8\xcf\x10\x53\x4b\xf1"
+                       "\xec\xfc\x89\xf9\x64\xb0\x22\xbf"
+                       "\x9e\x55\x46\x9f\x7c\x50\x8e\x84"
+                       "\x54\x20\x98\xd7\x6c\x40\x1e\xdb"
+                       "\x69\x34\x78\x61\x24\x21\x9c\x8a"
+                       "\xb3\x62\x31\x8b\x6e\xf5\x2a\x35"
+                       "\x86\x13\xb1\x6c\x64\x2e\x41\xa5"
+                       "\x05\xf2\x42\xba\xd2\x3a\x0d\x8e"
+                       "\x8a\x59\x94\x3c\xcf\x36\x27\x82"
+                       "\xc2\x45\xee\x58\xcd\x88\xb4\xec"
+                       "\xde\xb2\x96\x0a\xaf\x38\x6f\x88"
+                       "\xd7\xd8\xe1\xdf\xb9\x96\xa9\x0a"
+                       "\xb1\x95\x28\x86\x20\xe9\x17\x49"
+                       "\xa2\x29\x38\xaa\xa5\xe9\x6e\xf1"
+                       "\x19\x27\xc0\xd5\x2a\x22\xc3\x0b"
+                       "\xdb\x7c\x73\x10\xb9\xba\x89\x76"
+                       "\x54\xae\x7d\x71\xb3\x93\xf6\x32"
+                       "\xe6\x47\x43\x55\xac\xa0\x0d\xc2"
+                       "\x93\x27\x4a\x8e\x0e\x74\x15\xc7"
+                       "\x0b\x85\xd9\x0c\xa9\x30\x7a\x3e"
+                       "\xea\x8f\x85\x6d\x3a\x12\x4f\x72"
+                       "\x69\x58\x7a\x80\xbb\xb5\x97\xf3"
+                       "\xcf\x70\xd2\x5d\xdd\x4d\x21\x79"
+                       "\x54\x4d\xe4\x05\xe8\xbd\xc2\x62"
+                       "\xb1\x3b\x77\x1c\xd6\x5c\xf3\xa0"
+                       "\x79\x00\xa8\x6c\x29\xd9\x18\x24"
+                       "\x36\xa2\x46\xc0\x96\x65\x7f\xbd"
+                       "\x2a\xed\x36\x16\x0c\xaa\x9f\xf4"
+                       "\xc5\xb4\xe2\x12\xed\x69\xed\x4f"
+                       "\x26\x2c\x39\x52\x89\x98\xe7\x2c"
+                       "\x99\xa4\x9e\xa3\x9b\x99\x46\x7a"
+                       "\x3a\xdc\xa8\x59\xa3\xdb\xc3\x3b"
+                       "\x95\x0d\x3b\x09\x6e\xee\x83\x5d"
+                       "\x32\x4d\xed\xab\xfa\x98\x14\x4e"
+                       "\xc3\x15\x45\x53\x61\xc4\x93\xbd"
+                       "\x90\xf4\x99\x95\x4c\xe6\x76\x92"
+                       "\x29\x90\x46\x30\x92\x69\x7d\x13"
+                       "\xf2\xa5\xcd\x69\x49\x44\xb2\x0f"
+                       "\x63\x40\x36\x5f\x09\xe2\x78\xf8"
+                       "\x91\xe3\xe2\xfa\x10\xf7\xc8\x24"
+                       "\xa8\x89\x32\x5c\x37\x25\x1d\xb2"
+                       "\xea\x17\x8a\x0a\xa9\x64\xc3\x7c"
+                       "\x3c\x7c\xbd\xc6\x79\x34\xe7\xe2"
+                       "\x85\x8e\xbf\xf8\xde\x92\xa0\xae"
+                       "\x20\xc4\xf6\xbb\x1f\x38\x19\x0e"
+                       "\xe8\x79\x9c\xa1\x23\xe9\x54\x7e"
+                       "\x37\x2f\xe2\x94\x32\xaf\xa0\x23"
+                       "\x49\xe4\xc0\xb3\xac\x00\x8f\x36"
+                       "\x05\xc4\xa6\x96\xec\x05\x98\x4f"
+                       "\x96\x67\x57\x1f\x20\x86\x1b\x2d"
+                       "\x69\xe4\x29\x93\x66\x5f\xaf\x6b"
+                       "\x88\x26\x2c\x67\x02\x4b\x52\xd0"
+                       "\x83\x7a\x43\x1f\xc0\x71\x15\x25"
+                       "\x77\x65\x08\x60\x11\x76\x4c\x8d"
+                       "\xed\xa9\x27\xc6\xb1\x2a\x2c\x6a"
+                       "\x4a\x97\xf5\xc6\xb7\x70\x42\xd3"
+                       "\x03\xd1\x24\x95\xec\x6d\xab\x38"
+                       "\x72\xce\xe2\x8b\x33\xd7\x51\x09"
+                       "\xdc\x45\xe0\x09\x96\x32\xf3\xc4"
+                       "\x84\xdc\x73\x73\x2d\x1b\x11\x98"
+                       "\xc5\x0e\x69\x28\x94\xc7\xb5\x4d"
+                       "\xc8\x8a\xd0\xaa\x13\x2e\x18\x74"
+                       "\xdd\xd1\x1e\xf3\x90\xe8\xfc\x9a"
+                       "\x72\x4a\x0e\xd1\xe4\xfb\x0d\x96"
+                       "\xd1\x0c\x79\x85\x1b\x1c\xfe\xe1"
+                       "\x62\x8f\x7a\x73\x32\xab\xc8\x18"
+                       "\x69\xe3\x34\x30\xdf\x13\xa6\xe5"
+                       "\xe8\x0e\x67\x7f\x81\x11\xb4\x60"
+                       "\xc7\xbd\x79\x65\x50\xdc\xc4\x5b"
+                       "\xde\x39\xa4\x01\x72\x63\xf3\xd1"
+                       "\x64\x4e\xdf\xfc\x27\x92\x37\x0d"
+                       "\x57\xcd\x11\x4f\x11\x04\x8e\x1d"
+                       "\x16\xf7\xcd\x92\x9a\x99\x30\x14"
+                       "\xf1\x7c\x67\x1b\x1f\x41\x0b\xe8"
+                       "\x32\xe8\xb8\xc1\x4f\x54\x86\x4f"
+                       "\xe5\x79\x81\x73\xcd\x43\x59\x68"
+                       "\x73\x02\x3b\x78\x21\x72\x43\x00"
+                       "\x49\x17\xf7\x00\xaf\x68\x24\x53"
+                       "\x05\x0a\xc3\x33\xe0\x33\x3f\x69"
+                       "\xd2\x84\x2f\x0b\xed\xde\x04\xf4"
+                       "\x11\x94\x13\x69\x51\x09\x28\xde"
+                       "\x57\x5c\xef\xdc\x9a\x49\x1c\x17"
+                       "\x97\xf3\x96\xc1\x7f\x5d\x2e\x7d"
+                       "\x55\xb8\xb3\x02\x09\xb3\x1f\xe7"
+                       "\xc9\x8d\xa3\x36\x34\x8a\x77\x13"
+                       "\x30\x63\x4c\xa5\xcd\xc3\xe0\x7e"
+                       "\x05\xa1\x7b\x0c\xcb\x74\x47\x31"
+                       "\x62\x03\x43\xf1\x87\xb4\xb0\x85"
+                       "\x87\x8e\x4b\x25\xc7\xcf\xae\x4b"
+                       "\x36\x46\x3e\x62\xbc\x6f\xeb\x5f"
+                       "\x73\xac\xe6\x07\xee\xc1\xa1\xd6"
+                       "\xc4\xab\xc9\xd6\x89\x45\xe1\xf1"
+                       "\x04\x4e\x1a\x6f\xbb\x4f\x3a\xa3"
+                       "\xa0\xcb\xa3\x0a\xd8\x71\x35\x55"
+                       "\xe4\xbc\x2e\x04\x06\xe6\xff\x5b"
+                       "\x1c\xc0\x11\x7c\xc5\x17\xf3\x38"
+                       "\xcf\xe9\xba\x0f\x0e\xef\x02\xc2"
+                       "\x8d\xc6\xbc\x4b\x67\x20\x95\xd7"
+                       "\x2c\x45\x5b\x86\x44\x8c\x6f\x2e"
+                       "\x7e\x9f\x1c\x77\xba\x6b\x0e\xa3"
+                       "\x69\xdc\xab\x24\x57\x60\x47\xc1"
+                       "\xd1\xa5\x9d\x23\xe6\xb1\x37\xfe"
+                       "\x93\xd2\x4c\x46\xf9\x0c\xc6\xfb"
+                       "\xd6\x9d\x99\x69\xab\x7a\x07\x0c"
+                       "\x65\xe7\xc4\x08\x96\xe2\xa5\x01"
+                       "\x3f\x46\x07\x05\x7e\xe8\x9a\x90"
+                       "\x50\xdc\xe9\x7a\xea\xa1\x39\x6e"
+                       "\x66\xe4\x6f\xa5\x5f\xb2\xd9\x5b"
+                       "\xf5\xdb\x2a\x32\xf0\x11\x6f\x7c"
+                       "\x26\x10\x8f\x3d\x80\xe9\x58\xf7"
+                       "\xe0\xa8\x57\xf8\xdb\x0e\xce\x99"
+                       "\x63\x19\x3d\xd5\xec\x1b\x77\x69"
+                       "\x98\xf6\xe4\x5f\x67\x17\x4b\x09"
+                       "\x85\x62\x82\x70\x18\xe2\x9a\x78"
+                       "\xe2\x62\xbd\xb4\xf1\x42\xc6\xfb"
+                       "\x08\xd0\xbd\xeb\x4e\x09\xf2\xc8"
+                       "\x1e\xdc\x3d\x32\x21\x56\x9c\x4f"
+                       "\x35\xf3\x61\x06\x72\x84\xc4\x32"
+                       "\xf2\xf1\xfa\x0b\x2f\xc3\xdb\x02"
+                       "\x04\xc2\xde\x57\x64\x60\x8d\xcf"
+                       "\xcb\x86\x5d\x97\x3e\xb1\x9c\x01"
+                       "\xd6\x28\x8f\x99\xbc\x46\xeb\x05"
+                       "\xaf\x7e\xb8\x21\x2a\x56\x85\x1c"
+                       "\xb3\x71\xa0\xde\xca\x96\xf1\x78"
+                       "\x49\xa2\x99\x81\x80\x5c\x01\xf5"
+                       "\xa0\xa2\x56\x63\xe2\x70\x07\xa5"
+                       "\x95\xd6\x85\xeb\x36\x9e\xa9\x51"
+                       "\x66\x56\x5f\x1d\x02\x19\xe2\xf6"
+                       "\x4f\x73\x38\x09\x75\x64\x48\xe0"
+                       "\xf1\x7e\x0e\xe8\x9d\xf9\xed\x94"
+                       "\xfe\x16\x26\x62\x49\x74\xf4\xb0"
+                       "\xd4\xa9\x6c\xb0\xfd\x53\xe9\x81"
+                       "\xe0\x7a\xbf\xcf\xb5\xc4\x01\x81"
+                       "\x79\x99\x77\x01\x3b\xe9\xa2\xb6"
+                       "\xe6\x6a\x8a\x9e\x56\x1c\x8d\x1e"
+                       "\x8f\x06\x55\x2c\x6c\xdc\x92\x87"
+                       "\x64\x3b\x4b\x19\xa1\x13\x64\x1d"
+                       "\x4a\xe9\xc0\x00\xb8\x95\xef\x6b"
+                       "\x1a\x86\x6d\x37\x52\x02\xc2\xe0"
+                       "\xc8\xbb\x42\x0c\x02\x21\x4a\xc9"
+                       "\xef\xa0\x54\xe4\x5e\x16\x53\x81"
+                       "\x70\x62\x10\xaf\xde\xb8\xb5\xd3"
+                       "\xe8\x5e\x6c\xc3\x8a\x3e\x18\x07"
+                       "\xf2\x2f\x7d\xa7\xe1\x3d\x4e\xb4"
+                       "\x26\xa7\xa3\x93\x86\xb2\x04\x1e"
+                       "\x53\x5d\x86\xd6\xde\x65\xca\xe3"
+                       "\x4e\xc1\xcf\xef\xc8\x70\x1b\x83"
+                       "\x13\xdd\x18\x8b\x0d\x76\xd2\xf6"
+                       "\x37\x7a\x93\x7a\x50\x11\x9f\x96"
+                       "\x86\x25\xfd\xac\xdc\xbe\x18\x93"
+                       "\x19\x6b\xec\x58\x4f\xb9\x75\xa7"
+                       "\xdd\x3f\x2f\xec\xc8\x5a\x84\xab"
+                       "\xd5\xe4\x8a\x07\xf6\x4d\x23\xd6"
+                       "\x03\xfb\x03\x6a\xea\x66\xbf\xd4"
+                       "\xb1\x34\xfb\x78\xe9\x55\xdc\x7c"
+                       "\x3d\x9c\xe5\x9a\xac\xc3\x7a\x80"
+                       "\x24\x6d\xa0\xef\x25\x7c\xb7\xea"
+                       "\xce\x4d\x5f\x18\x60\xce\x87\x22"
+                       "\x66\x2f\xd5\xdd\xdd\x02\x21\x75"
+                       "\x82\xa0\x1f\x58\xc6\xd3\x62\xf7"
+                       "\x32\xd8\xaf\x1e\x07\x77\x51\x96"
+                       "\xd5\x6b\x1e\x7e\x80\x02\xe8\x67"
+                       "\xea\x17\x0b\x10\xd2\x3f\x28\x25"
+                       "\x4f\x05\x77\x02\x14\x69\xf0\x2c"
+                       "\xbe\x0c\xf1\x74\x30\xd1\xb9\x9b"
+                       "\xfc\x8c\xbb\x04\x16\xd9\xba\xc3"
+                       "\xbc\x91\x8a\xc4\x30\xa4\xb0\x12"
+                       "\x4c\x21\x87\xcb\xc9\x1d\x16\x96"
+                       "\x07\x6f\x23\x54\xb9\x6f\x79\xe5"
+                       "\x64\xc0\x64\xda\xb1\xae\xdd\x60"
+                       "\x6c\x1a\x9d\xd3\x04\x8e\x45\xb0"
+                       "\x92\x61\xd0\x48\x81\xed\x5e\x1d"
+                       "\xa0\xc9\xa4\x33\xc7\x13\x51\x5d"
+                       "\x7f\x83\x73\xb6\x70\x18\x65\x3e"
+                       "\x2f\x0e\x7a\x12\x39\x98\xab\xd8"
+                       "\x7e\x6f\xa3\xd1\xba\x56\xad\xbd"
+                       "\xf0\x03\x01\x1c\x85\x35\x9f\xeb"
+                       "\x19\x63\xa1\xaf\xfe\x2d\x35\x50"
+                       "\x39\xa0\x65\x7c\x95\x7e\x6b\xfe"
+                       "\xc1\xac\x07\x7c\x98\x4f\xbe\x57"
+                       "\xa7\x22\xec\xe2\x7e\x29\x09\x53"
+                       "\xe8\xbf\xb4\x7e\x3f\x8f\xfc\x14"
+                       "\xce\x54\xf9\x18\x58\xb5\xff\x44"
+                       "\x05\x9d\xce\x1b\xb6\x82\x23\xc8"
+                       "\x2e\xbc\x69\xbb\x4a\x29\x0f\x65"
+                       "\x94\xf0\x63\x06\x0e\xef\x8c\xbd"
+                       "\xff\xfd\xb0\x21\x6e\x57\x05\x75"
+                       "\xda\xd5\xc4\xeb\x8d\x32\xf7\x50"
+                       "\xd3\x6f\x22\xed\x5f\x8e\xa2\x5b"
+                       "\x80\x8c\xc8\x78\x40\x24\x4b\x89"
+                       "\x30\xce\x7a\x97\x0e\xc4\xaf\xef"
+                       "\x9b\xb4\xcd\x66\x74\x14\x04\x2b"
+                       "\xf7\xce\x0b\x1c\x6e\xc2\x78\x8c"
+                       "\xca\xc5\xd0\x1c\x95\x4a\x91\x2d"
+                       "\xa7\x20\xeb\x86\x52\xb7\x67\xd8"
+                       "\x0c\xd6\x04\x14\xde\x51\x74\x75"
+                       "\xe7\x11\xb4\x87\xa3\x3d\x2d\xad"
+                       "\x4f\xef\xa0\x0f\x70\x00\x6d\x13"
+                       "\x19\x1d\x41\x50\xe9\xd8\xf0\x32"
+                       "\x71\xbc\xd3\x11\xf2\xac\xbe\xaf"
+                       "\x75\x46\x65\x4e\x07\x34\x37\xa3"
+                       "\x89\xfe\x75\xd4\x70\x4c\xc6\x3f"
+                       "\x69\x24\x0e\x38\x67\x43\x8c\xde"
+                       "\x06\xb5\xb8\xe7\xc4\xf0\x41\x8f"
+                       "\xf0\xbd\x2f\x0b\xb9\x18\xf8\xde"
+                       "\x64\xb1\xdb\xee\x00\x50\x77\xe1"
+                       "\xc7\xff\xa6\xfa\xdd\x70\xf4\xe3"
+                       "\x93\xe9\x77\x35\x3d\x4b\x2f\x2b"
+                       "\x6d\x55\xf0\xfc\x88\x54\x4e\x89"
+                       "\xc1\x8a\x23\x31\x2d\x14\x2a\xb8"
+                       "\x1b\x15\xdd\x9e\x6e\x7b\xda\x05"
+                       "\x91\x7d\x62\x64\x96\x72\xde\xfc"
+                       "\xc1\xec\xf0\x23\x51\x6f\xdb\x5b"
+                       "\x1d\x08\x57\xce\x09\xb8\xf6\xcd"
+                       "\x8d\x95\xf2\x20\xbf\x0f\x20\x57"
+                       "\x98\x81\x84\x4f\x15\x5c\x76\xe7"
+                       "\x3e\x0a\x3a\x6c\xc4\x8a\xbe\x78"
+                       "\x74\x77\xc3\x09\x4b\x5d\x48\xe4"
+                       "\xc8\xcb\x0b\xea\x17\x28\xcf\xcf"
+                       "\x31\x32\x44\xa4\xe5\x0e\x1a\x98"
+                       "\x94\xc4\xf0\xff\xae\x3e\x44\xe8"
+                       "\xa5\xb3\xb5\x37\x2f\xe8\xaf\x6f"
+                       "\x28\xc1\x37\x5f\x31\xd2\xb9\x33"
+                       "\xb1\xb2\x52\x94\x75\x2c\x29\x59"
+                       "\x06\xc2\x25\xe8\x71\x65\x4e\xed"
+                       "\xc0\x9c\xb1\xbb\x25\xdc\x6c\xe7"
+                       "\x4b\xa5\x7a\x54\x7a\x60\xff\x7a"
+                       "\xe0\x50\x40\x96\x35\x63\xe4\x0b"
+                       "\x76\xbd\xa4\x65\x00\x1b\x57\x88"
+                       "\xae\xed\x39\x88\x42\x11\x3c\xed"
+                       "\x85\x67\x7d\xb9\x68\x82\xe9\x43"
+                       "\x3c\x47\x53\xfa\xe8\xf8\x9f\x1f"
+                       "\x9f\xef\x0f\xf7\x30\xd9\x30\x0e"
+                       "\xb9\x9f\x69\x18\x2f\x7e\xf8\xf8"
+                       "\xf8\x8c\x0f\xd4\x02\x4d\xea\xcd"
+                       "\x0a\x9c\x6f\x71\x6d\x5a\x4c\x60"
+                       "\xce\x20\x56\x32\xc6\xc5\x99\x1f"
+                       "\x09\xe6\x4e\x18\x1a\x15\x13\xa8"
+                       "\x7d\xb1\x6b\xc0\xb2\x6d\xf8\x26"
+                       "\x66\xf8\x3d\x18\x74\x70\x66\x7a"
+                       "\x34\x17\xde\xba\x47\xf1\x06\x18"
+                       "\xcb\xaf\xeb\x4a\x1e\x8f\xa7\x77"
+                       "\xe0\x3b\x78\x62\x66\xc9\x10\xea"
+                       "\x1f\xb7\x29\x0a\x45\xa1\x1d\x1e"
+                       "\x1d\xe2\x65\x61\x50\x9c\xd7\x05"
+                       "\xf2\x0b\x5b\x12\x61\x02\xc8\xe5"
+                       "\x63\x4f\x20\x0c\x07\x17\x33\x5e"
+                       "\x03\x9a\x53\x0f\x2e\x55\xfe\x50"
+                       "\x43\x7d\xd0\xb6\x7e\x5a\xda\xae"
+                       "\x58\xef\x15\xa9\x83\xd9\x46\xb1"
+                       "\x42\xaa\xf5\x02\x6c\xce\x92\x06"
+                       "\x1b\xdb\x66\x45\x91\x79\xc2\x2d"
+                       "\xe6\x53\xd3\x14\xfd\xbb\x44\x63"
+                       "\xc6\xd7\x3d\x7a\x0c\x75\x78\x9d"
+                       "\x5c\xa6\x39\xb3\xe5\x63\xca\x8b"
+                       "\xfe\xd3\xef\x60\x83\xf6\x8e\x70"
+                       "\xb6\x67\xc7\x77\xed\x23\xef\x4c"
+                       "\xf0\xed\x2d\x07\x59\x6f\xc1\x01"
+                       "\x34\x37\x08\xab\xd9\x1f\x09\xb1"
+                       "\xce\x5b\x17\xff\x74\xf8\x9c\xd5"
+                       "\x2c\x56\x39\x79\x0f\x69\x44\x75"
+                       "\x58\x27\x01\xc4\xbf\xa7\xa1\x1d"
+                       "\x90\x17\x77\x86\x5a\x3f\xd9\xd1"
+                       "\x0e\xa0\x10\xf8\xec\x1e\xa5\x7f"
+                       "\x5e\x36\xd1\xe3\x04\x2c\x70\xf7"
+                       "\x8e\xc0\x98\x2f\x6c\x94\x2b\x41"
+                       "\xb7\x60\x00\xb7\x2e\xb8\x02\x8d"
+                       "\xb8\xb0\xd3\x86\xba\x1d\xd7\x90"
+                       "\xd6\xb6\xe1\xfc\xd7\xd8\x28\x06"
+                       "\x63\x9b\xce\x61\x24\x79\xc0\x70"
+                       "\x52\xd0\xb6\xd4\x28\x95\x24\x87"
+                       "\x03\x1f\xb7\x9a\xda\xa3\xfb\x52"
+                       "\x5b\x68\xe7\x4c\x8c\x24\xe1\x42"
+                       "\xf7\xd5\xfd\xad\x06\x32\x9f\xba"
+                       "\xc1\xfc\xdd\xc6\xfc\xfc\xb3\x38"
+                       "\x74\x56\x58\x40\x02\x37\x52\x2c"
+                       "\x55\xcc\xb3\x9e\x7a\xe9\xd4\x38"
+                       "\x41\x5e\x0c\x35\xe2\x11\xd1\x13"
+                       "\xf8\xb7\x8d\x72\x6b\x22\x2a\xb0"
+                       "\xdb\x08\xba\x35\xb9\x3f\xc8\xd3"
+                       "\x24\x90\xec\x58\xd2\x09\xc7\x2d"
+                       "\xed\x38\x80\x36\x72\x43\x27\x49"
+                       "\x4a\x80\x8a\xa2\xe8\xd3\xda\x30"
+                       "\x7d\xb6\x82\x37\x86\x92\x86\x3e"
+                       "\x08\xb2\x28\x5a\x55\x44\x24\x7d"
+                       "\x40\x48\x8a\xb6\x89\x58\x08\xa0"
+                       "\xd6\x6d\x3a\x17\xbf\xf6\x54\xa2"
+                       "\xf5\xd3\x8c\x0f\x78\x12\x57\x8b"
+                       "\xd5\xc2\xfd\x58\x5b\x7f\x38\xe3"
+                       "\xcc\xb7\x7c\x48\xb3\x20\xe8\x81"
+                       "\x14\x32\x45\x05\xe0\xdb\x9f\x75"
+                       "\x85\xb4\x6a\xfc\x95\xe3\x54\x22"
+                       "\x12\xee\x30\xfe\xd8\x30\xef\x34"
+                       "\x50\xab\x46\x30\x98\x2f\xb7\xc0"
+                       "\x15\xa2\x83\xb6\xf2\x06\x21\xa2"
+                       "\xc3\x26\x37\x14\xd1\x4d\xb5\x10"
+                       "\x52\x76\x4d\x6a\xee\xb5\x2b\x15"
+                       "\xb7\xf9\x51\xe8\x2a\xaf\xc7\xfa"
+                       "\x77\xaf\xb0\x05\x4d\xd1\x68\x8e"
+                       "\x74\x05\x9f\x9d\x93\xa5\x3e\x7f"
+                       "\x4e\x5f\x9d\xcb\x09\xc7\x83\xe3"
+                       "\x02\x9d\x27\x1f\xef\x85\x05\x8d"
+                       "\xec\x55\x88\x0f\x0d\x7c\x4c\xe8"
+                       "\xa1\x75\xa0\xd8\x06\x47\x14\xef"
+                       "\xaa\x61\xcf\x26\x15\xad\xd8\xa3"
+                       "\xaa\x75\xf2\x78\x4a\x5a\x61\xdf"
+                       "\x8b\xc7\x04\xbc\xb2\x32\xd2\x7e"
+                       "\x42\xee\xb4\x2f\x51\xff\x7b\x2e"
+                       "\xd3\x02\xe8\xdc\x5d\x0d\x50\xdc"
+                       "\xae\xb7\x46\xf9\xa8\xe6\xd0\x16"
+                       "\xcc\xe6\x2c\x81\xc7\xad\xe9\xf0"
+                       "\x05\x72\x6d\x3d\x0a\x7a\xa9\x02"
+                       "\xac\x82\x93\x6e\xb6\x1c\x28\xfc"
+                       "\x44\x12\xfb\x73\x77\xd4\x13\x39"
+                       "\x29\x88\x8a\xf3\x5c\xa6\x36\xa0"
+                       "\x2a\xed\x7e\xb1\x1d\xd6\x4c\x6b"
+                       "\x41\x01\x18\x5d\x5d\x07\x97\xa6"
+                       "\x4b\xef\x31\x18\xea\xac\xb1\x84"
+                       "\x21\xed\xda\x86",
+               .rlen = 4100,
+               .np     = 2,
+               .tap    = { 4064, 36 },
+#endif
+       },
+};
+
+static struct cipher_testvec aes_ctr_rfc3686_dec_tv_template[] = {
+       { /* From RFC 3686 */
+               .key    = "\xae\x68\x52\xf8\x12\x10\x67\xcc"
+                         "\x4b\xf7\xa5\x76\x55\x77\xf3\x9e"
+                         "\x00\x00\x00\x30",
+               .klen   = 20,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\xe4\x09\x5d\x4f\xb7\xa7\xb3\x79"
+                         "\x2d\x61\x75\xa3\x26\x13\x11\xb8",
+               .ilen   = 16,
+               .result = "Single block msg",
+               .rlen   = 16,
+       }, {
+               .key    = "\x7e\x24\x06\x78\x17\xfa\xe0\xd7"
+                         "\x43\xd6\xce\x1f\x32\x53\x91\x63"
+                         "\x00\x6c\xb6\xdb",
+               .klen   = 20,
+               .iv     = "\xc0\x54\x3b\x59\xda\x48\xd9\x0b",
+               .input  = "\x51\x04\xa1\x06\x16\x8a\x72\xd9"
+                         "\x79\x0d\x41\xee\x8e\xda\xd3\x88"
+                         "\xeb\x2e\x1e\xfc\x46\xda\x57\xc8"
+                         "\xfc\xe6\x30\xdf\x91\x41\xbe\x28",
+               .ilen   = 32,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .rlen   = 32,
+       }, {
+               .key    = "\x16\xaf\x5b\x14\x5f\xc9\xf5\x79"
+                         "\xc1\x75\xf9\x3e\x3b\xfb\x0e\xed"
+                         "\x86\x3d\x06\xcc\xfd\xb7\x85\x15"
+                         "\x00\x00\x00\x48",
+               .klen   = 28,
+               .iv     = "\x36\x73\x3c\x14\x7d\x6d\x93\xcb",
+               .input  = "\x4b\x55\x38\x4f\xe2\x59\xc9\xc8"
+                         "\x4e\x79\x35\xa0\x03\xcb\xe9\x28",
+               .ilen   = 16,
+               .result = "Single block msg",
+               .rlen   = 16,
+       }, {
+               .key    = "\x7c\x5c\xb2\x40\x1b\x3d\xc3\x3c"
+                         "\x19\xe7\x34\x08\x19\xe0\xf6\x9c"
+                         "\x67\x8c\x3d\xb8\xe6\xf6\xa9\x1a"
+                         "\x00\x96\xb0\x3b",
+               .klen   = 28,
+               .iv     = "\x02\x0c\x6e\xad\xc2\xcb\x50\x0d",
+               .input  = "\x45\x32\x43\xfc\x60\x9b\x23\x32"
+                         "\x7e\xdf\xaa\xfa\x71\x31\xcd\x9f"
+                         "\x84\x90\x70\x1c\x5a\xd4\xa7\x9c"
+                         "\xfc\x1f\xe0\xff\x42\xf4\xfb\x00",
+               .ilen   = 32,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .rlen   = 32,
+       }, {
+               .key    = "\x77\x6b\xef\xf2\x85\x1d\xb0\x6f"
+                         "\x4c\x8a\x05\x42\xc8\x69\x6f\x6c"
+                         "\x6a\x81\xaf\x1e\xec\x96\xb4\xd3"
+                         "\x7f\xc1\xd6\x89\xe6\xc1\xc1\x04"
+                         "\x00\x00\x00\x60",
+               .klen   = 36,
+               .iv     = "\xdb\x56\x72\xc9\x7a\xa8\xf0\xb2",
+               .input  = "\x14\x5a\xd0\x1d\xbf\x82\x4e\xc7"
+                         "\x56\x08\x63\xdc\x71\xe3\xe0\xc0",
+               .ilen   = 16,
+               .result = "Single block msg",
+               .rlen   = 16,
+       }, {
+               .key    = "\xf6\xd6\x6d\x6b\xd5\x2d\x59\xbb"
+                         "\x07\x96\x36\x58\x79\xef\xf8\x86"
+                         "\xc6\x6d\xd5\x1a\x5b\x6a\x99\x74"
+                         "\x4b\x50\x59\x0c\x87\xa2\x38\x84"
+                         "\x00\xfa\xac\x24",
+               .klen   = 36,
+               .iv     = "\xc1\x58\x5e\xf1\x5a\x43\xd8\x75",
+               .input  = "\xf0\x5e\x23\x1b\x38\x94\x61\x2c"
+                         "\x49\xee\x00\x0b\x80\x4e\xb2\xa9"
+                         "\xb8\x30\x6b\x50\x8f\x83\x9d\x6a"
+                         "\x55\x30\x83\x1d\x93\x44\xaf\x1c",
+               .ilen   = 32,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .rlen   = 32,
+       },
+};
+
+static struct aead_testvec aes_gcm_enc_tv_template[] = {
+       { /* From McGrew & Viega - http://citeseer.ist.psu.edu/656989.html */
+               .key    = zeroed_string,
+               .klen   = 16,
+               .result = "\x58\xe2\xfc\xce\xfa\x7e\x30\x61"
+                         "\x36\x7f\x1d\x57\xa4\xe7\x45\x5a",
+               .rlen   = 16,
+       }, {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\x03\x88\xda\xce\x60\xb6\xa3\x92"
+                         "\xf3\x28\xc2\xb9\x71\xb2\xfe\x78"
+                         "\xab\x6e\x47\xd4\x2c\xec\x13\xbd"
+                         "\xf5\x3a\x67\xb2\x12\x57\xbd\xdf",
+               .rlen   = 32,
+       }, {
+               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+               .klen   = 16,
+               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+                         "\xde\xca\xf8\x88",
+               .input  = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+                         "\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
+               .ilen   = 64,
+               .result = "\x42\x83\x1e\xc2\x21\x77\x74\x24"
+                         "\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
+                         "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0"
+                         "\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
+                         "\x21\xd5\x14\xb2\x54\x66\x93\x1c"
+                         "\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
+                         "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97"
+                         "\x3d\x58\xe0\x91\x47\x3f\x59\x85"
+                         "\x4d\x5c\x2a\xf3\x27\xcd\x64\xa6"
+                         "\x2c\xf3\x5a\xbd\x2b\xa6\xfa\xb4",
+               .rlen   = 80,
+       }, {
+               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+               .klen   = 16,
+               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+                         "\xde\xca\xf8\x88",
+               .input  = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+                         "\xba\x63\x7b\x39",
+               .ilen   = 60,
+               .assoc  = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+                         "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+                         "\xab\xad\xda\xd2",
+               .alen   = 20,
+               .result = "\x42\x83\x1e\xc2\x21\x77\x74\x24"
+                         "\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
+                         "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0"
+                         "\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
+                         "\x21\xd5\x14\xb2\x54\x66\x93\x1c"
+                         "\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
+                         "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97"
+                         "\x3d\x58\xe0\x91"
+                         "\x5b\xc9\x4f\xbc\x32\x21\xa5\xdb"
+                         "\x94\xfa\xe9\x5a\xe7\x12\x1a\x47",
+               .rlen   = 76,
+       }, {
+               .key    = zeroed_string,
+               .klen   = 24,
+               .result = "\xcd\x33\xb2\x8a\xc7\x73\xf7\x4b"
+                         "\xa0\x0e\xd1\xf3\x12\x57\x24\x35",
+               .rlen   = 16,
+       }, {
+               .key    = zeroed_string,
+               .klen   = 24,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\x98\xe7\x24\x7c\x07\xf0\xfe\x41"
+                         "\x1c\x26\x7e\x43\x84\xb0\xf6\x00"
+                         "\x2f\xf5\x8d\x80\x03\x39\x27\xab"
+                         "\x8e\xf4\xd4\x58\x75\x14\xf0\xfb",
+               .rlen   = 32,
+       }, {
+               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+                         "\xfe\xff\xe9\x92\x86\x65\x73\x1c",
+               .klen   = 24,
+               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+                         "\xde\xca\xf8\x88",
+               .input  = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+                         "\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
+               .ilen   = 64,
+               .result = "\x39\x80\xca\x0b\x3c\x00\xe8\x41"
+                         "\xeb\x06\xfa\xc4\x87\x2a\x27\x57"
+                         "\x85\x9e\x1c\xea\xa6\xef\xd9\x84"
+                         "\x62\x85\x93\xb4\x0c\xa1\xe1\x9c"
+                         "\x7d\x77\x3d\x00\xc1\x44\xc5\x25"
+                         "\xac\x61\x9d\x18\xc8\x4a\x3f\x47"
+                         "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9"
+                         "\xcc\xda\x27\x10\xac\xad\xe2\x56"
+                         "\x99\x24\xa7\xc8\x58\x73\x36\xbf"
+                         "\xb1\x18\x02\x4d\xb8\x67\x4a\x14",
+               .rlen   = 80,
+       }, {
+               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+                         "\xfe\xff\xe9\x92\x86\x65\x73\x1c",
+               .klen   = 24,
+               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+                         "\xde\xca\xf8\x88",
+               .input  = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+                         "\xba\x63\x7b\x39",
+               .ilen   = 60,
+               .assoc  = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+                         "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+                         "\xab\xad\xda\xd2",
+               .alen   = 20,
+               .result = "\x39\x80\xca\x0b\x3c\x00\xe8\x41"
+                         "\xeb\x06\xfa\xc4\x87\x2a\x27\x57"
+                         "\x85\x9e\x1c\xea\xa6\xef\xd9\x84"
+                         "\x62\x85\x93\xb4\x0c\xa1\xe1\x9c"
+                         "\x7d\x77\x3d\x00\xc1\x44\xc5\x25"
+                         "\xac\x61\x9d\x18\xc8\x4a\x3f\x47"
+                         "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9"
+                         "\xcc\xda\x27\x10"
+                         "\x25\x19\x49\x8e\x80\xf1\x47\x8f"
+                         "\x37\xba\x55\xbd\x6d\x27\x61\x8c",
+               .rlen   = 76,
+               .np     = 2,
+               .tap    = { 32, 28 },
+               .anp    = 2,
+               .atap   = { 8, 12 }
+       }, {
+               .key    = zeroed_string,
+               .klen   = 32,
+               .result = "\x53\x0f\x8a\xfb\xc7\x45\x36\xb9"
+                         "\xa9\x63\xb4\xf1\xc4\xcb\x73\x8b",
+               .rlen   = 16,
+       }
+};
+
+static struct aead_testvec aes_gcm_dec_tv_template[] = {
+       { /* From McGrew & Viega - http://citeseer.ist.psu.edu/656989.html */
+               .key    = zeroed_string,
+               .klen   = 32,
+               .input  = "\xce\xa7\x40\x3d\x4d\x60\x6b\x6e"
+                         "\x07\x4e\xc5\xd3\xba\xf3\x9d\x18"
+                         "\xd0\xd1\xc8\xa7\x99\x99\x6b\xf0"
+                         "\x26\x5b\x98\xb5\xd4\x8a\xb9\x19",
+               .ilen   = 32,
+               .result  = zeroed_string,
+               .rlen   = 16,
+       }, {
+               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+                         "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+               .klen   = 32,
+               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+                         "\xde\xca\xf8\x88",
+               .input  = "\x52\x2d\xc1\xf0\x99\x56\x7d\x07"
+                         "\xf4\x7f\x37\xa3\x2a\x84\x42\x7d"
+                         "\x64\x3a\x8c\xdc\xbf\xe5\xc0\xc9"
+                         "\x75\x98\xa2\xbd\x25\x55\xd1\xaa"
+                         "\x8c\xb0\x8e\x48\x59\x0d\xbb\x3d"
+                         "\xa7\xb0\x8b\x10\x56\x82\x88\x38"
+                         "\xc5\xf6\x1e\x63\x93\xba\x7a\x0a"
+                         "\xbc\xc9\xf6\x62\x89\x80\x15\xad"
+                         "\xb0\x94\xda\xc5\xd9\x34\x71\xbd"
+                         "\xec\x1a\x50\x22\x70\xe3\xcc\x6c",
+               .ilen   = 80,
+               .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+                         "\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
+               .rlen   = 64,
+       }, {
+               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+                         "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+               .klen   = 32,
+               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+                         "\xde\xca\xf8\x88",
+               .input  = "\x52\x2d\xc1\xf0\x99\x56\x7d\x07"
+                         "\xf4\x7f\x37\xa3\x2a\x84\x42\x7d"
+                         "\x64\x3a\x8c\xdc\xbf\xe5\xc0\xc9"
+                         "\x75\x98\xa2\xbd\x25\x55\xd1\xaa"
+                         "\x8c\xb0\x8e\x48\x59\x0d\xbb\x3d"
+                         "\xa7\xb0\x8b\x10\x56\x82\x88\x38"
+                         "\xc5\xf6\x1e\x63\x93\xba\x7a\x0a"
+                         "\xbc\xc9\xf6\x62"
+                         "\x76\xfc\x6e\xce\x0f\x4e\x17\x68"
+                         "\xcd\xdf\x88\x53\xbb\x2d\x55\x1b",
+               .ilen   = 76,
+               .assoc  = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+                         "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+                         "\xab\xad\xda\xd2",
+               .alen   = 20,
+               .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+                         "\xba\x63\x7b\x39",
+               .rlen   = 60,
+               .np     = 2,
+               .tap    = { 48, 28 },
+               .anp    = 3,
+               .atap   = { 8, 8, 4 }
+       }, {
+               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+               .klen   = 16,
+               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+                         "\xde\xca\xf8\x88",
+               .input  = "\x42\x83\x1e\xc2\x21\x77\x74\x24"
+                         "\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
+                         "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0"
+                         "\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
+                         "\x21\xd5\x14\xb2\x54\x66\x93\x1c"
+                         "\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
+                         "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97"
+                         "\x3d\x58\xe0\x91\x47\x3f\x59\x85"
+                         "\x4d\x5c\x2a\xf3\x27\xcd\x64\xa6"
+                         "\x2c\xf3\x5a\xbd\x2b\xa6\xfa\xb4",
+               .ilen   = 80,
+               .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+                         "\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
+               .rlen   = 64,
+       }, {
+               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+               .klen   = 16,
+               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+                         "\xde\xca\xf8\x88",
+               .input  = "\x42\x83\x1e\xc2\x21\x77\x74\x24"
+                         "\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
+                         "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0"
+                         "\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
+                         "\x21\xd5\x14\xb2\x54\x66\x93\x1c"
+                         "\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
+                         "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97"
+                         "\x3d\x58\xe0\x91"
+                         "\x5b\xc9\x4f\xbc\x32\x21\xa5\xdb"
+                         "\x94\xfa\xe9\x5a\xe7\x12\x1a\x47",
+               .ilen   = 76,
+               .assoc  = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+                         "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+                         "\xab\xad\xda\xd2",
+               .alen   = 20,
+               .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+                         "\xba\x63\x7b\x39",
+               .rlen   = 60,
+       }, {
+               .key    = zeroed_string,
+               .klen   = 24,
+               .input  = "\x98\xe7\x24\x7c\x07\xf0\xfe\x41"
+                         "\x1c\x26\x7e\x43\x84\xb0\xf6\x00"
+                         "\x2f\xf5\x8d\x80\x03\x39\x27\xab"
+                         "\x8e\xf4\xd4\x58\x75\x14\xf0\xfb",
+               .ilen   = 32,
+               .result  = zeroed_string,
+               .rlen   = 16,
+       }, {
+               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+                         "\xfe\xff\xe9\x92\x86\x65\x73\x1c",
+               .klen   = 24,
+               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+                         "\xde\xca\xf8\x88",
+               .input  = "\x39\x80\xca\x0b\x3c\x00\xe8\x41"
+                         "\xeb\x06\xfa\xc4\x87\x2a\x27\x57"
+                         "\x85\x9e\x1c\xea\xa6\xef\xd9\x84"
+                         "\x62\x85\x93\xb4\x0c\xa1\xe1\x9c"
+                         "\x7d\x77\x3d\x00\xc1\x44\xc5\x25"
+                         "\xac\x61\x9d\x18\xc8\x4a\x3f\x47"
+                         "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9"
+                         "\xcc\xda\x27\x10\xac\xad\xe2\x56"
+                         "\x99\x24\xa7\xc8\x58\x73\x36\xbf"
+                         "\xb1\x18\x02\x4d\xb8\x67\x4a\x14",
+               .ilen   = 80,
+               .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+                         "\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
+               .rlen   = 64,
+       }, {
+               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+                         "\xfe\xff\xe9\x92\x86\x65\x73\x1c",
+               .klen   = 24,
+               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+                         "\xde\xca\xf8\x88",
+               .input  = "\x39\x80\xca\x0b\x3c\x00\xe8\x41"
+                         "\xeb\x06\xfa\xc4\x87\x2a\x27\x57"
+                         "\x85\x9e\x1c\xea\xa6\xef\xd9\x84"
+                         "\x62\x85\x93\xb4\x0c\xa1\xe1\x9c"
+                         "\x7d\x77\x3d\x00\xc1\x44\xc5\x25"
+                         "\xac\x61\x9d\x18\xc8\x4a\x3f\x47"
+                         "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9"
+                         "\xcc\xda\x27\x10"
+                         "\x25\x19\x49\x8e\x80\xf1\x47\x8f"
+                         "\x37\xba\x55\xbd\x6d\x27\x61\x8c",
+               .ilen   = 76,
+               .assoc  = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+                         "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+                         "\xab\xad\xda\xd2",
+               .alen   = 20,
+               .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+                         "\xba\x63\x7b\x39",
+               .rlen   = 60,
+       }
+};
+
+static struct aead_testvec aes_ccm_enc_tv_template[] = {
+       { /* From RFC 3610 */
+               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+               .klen   = 16,
+               .iv     = "\x01\x00\x00\x00\x03\x02\x01\x00"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07",
+               .alen   = 8,
+               .input  = "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e",
+               .ilen   = 23,
+               .result = "\x58\x8c\x97\x9a\x61\xc6\x63\xd2"
+                         "\xf0\x66\xd0\xc2\xc0\xf9\x89\x80"
+                         "\x6d\x5f\x6b\x61\xda\xc3\x84\x17"
+                         "\xe8\xd1\x2c\xfd\xf9\x26\xe0",
+               .rlen   = 31,
+       }, {
+               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+               .klen   = 16,
+               .iv     = "\x01\x00\x00\x00\x07\x06\x05\x04"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b",
+               .alen   = 12,
+               .input  = "\x0c\x0d\x0e\x0f\x10\x11\x12\x13"
+                         "\x14\x15\x16\x17\x18\x19\x1a\x1b"
+                         "\x1c\x1d\x1e\x1f",
+               .ilen   = 20,
+               .result = "\xdc\xf1\xfb\x7b\x5d\x9e\x23\xfb"
+                         "\x9d\x4e\x13\x12\x53\x65\x8a\xd8"
+                         "\x6e\xbd\xca\x3e\x51\xe8\x3f\x07"
+                         "\x7d\x9c\x2d\x93",
+               .rlen   = 28,
+       }, {
+               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+               .klen   = 16,
+               .iv     = "\x01\x00\x00\x00\x0b\x0a\x09\x08"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07",
+               .alen   = 8,
+               .input  = "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+                         "\x20",
+               .ilen   = 25,
+               .result = "\x82\x53\x1a\x60\xcc\x24\x94\x5a"
+                         "\x4b\x82\x79\x18\x1a\xb5\xc8\x4d"
+                         "\xf2\x1c\xe7\xf9\xb7\x3f\x42\xe1"
+                         "\x97\xea\x9c\x07\xe5\x6b\x5e\xb1"
+                         "\x7e\x5f\x4e",
+               .rlen   = 35,
+       }, {
+               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+               .klen   = 16,
+               .iv     = "\x01\x00\x00\x00\x0c\x0b\x0a\x09"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b",
+               .alen   = 12,
+               .input  = "\x0c\x0d\x0e\x0f\x10\x11\x12\x13"
+                         "\x14\x15\x16\x17\x18\x19\x1a\x1b"
+                         "\x1c\x1d\x1e",
+               .ilen   = 19,
+               .result = "\x07\x34\x25\x94\x15\x77\x85\x15"
+                         "\x2b\x07\x40\x98\x33\x0a\xbb\x14"
+                         "\x1b\x94\x7b\x56\x6a\xa9\x40\x6b"
+                         "\x4d\x99\x99\x88\xdd",
+               .rlen   = 29,
+       }, {
+               .key    = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
+                         "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
+               .klen   = 16,
+               .iv     = "\x01\x00\x33\x56\x8e\xf7\xb2\x63"
+                         "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
+               .assoc  = "\x63\x01\x8f\x76\xdc\x8a\x1b\xcb",
+               .alen   = 8,
+               .input  = "\x90\x20\xea\x6f\x91\xbd\xd8\x5a"
+                         "\xfa\x00\x39\xba\x4b\xaf\xf9\xbf"
+                         "\xb7\x9c\x70\x28\x94\x9c\xd0\xec",
+               .ilen   = 24,
+               .result = "\x4c\xcb\x1e\x7c\xa9\x81\xbe\xfa"
+                         "\xa0\x72\x6c\x55\xd3\x78\x06\x12"
+                         "\x98\xc8\x5c\x92\x81\x4a\xbc\x33"
+                         "\xc5\x2e\xe8\x1d\x7d\x77\xc0\x8a",
+               .rlen   = 32,
+       }, {
+               .key    = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
+                         "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
+               .klen   = 16,
+               .iv     = "\x01\x00\xd5\x60\x91\x2d\x3f\x70"
+                         "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
+               .assoc  = "\xcd\x90\x44\xd2\xb7\x1f\xdb\x81"
+                         "\x20\xea\x60\xc0",
+               .alen   = 12,
+               .input  = "\x64\x35\xac\xba\xfb\x11\xa8\x2e"
+                         "\x2f\x07\x1d\x7c\xa4\xa5\xeb\xd9"
+                         "\x3a\x80\x3b\xa8\x7f",
+               .ilen   = 21,
+               .result = "\x00\x97\x69\xec\xab\xdf\x48\x62"
+                         "\x55\x94\xc5\x92\x51\xe6\x03\x57"
+                         "\x22\x67\x5e\x04\xc8\x47\x09\x9e"
+                         "\x5a\xe0\x70\x45\x51",
+               .rlen   = 29,
+       }, {
+               .key    = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
+                         "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
+               .klen   = 16,
+               .iv     = "\x01\x00\x42\xff\xf8\xf1\x95\x1c"
+                         "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
+               .assoc  = "\xd8\x5b\xc7\xe6\x9f\x94\x4f\xb8",
+               .alen   = 8,
+               .input  = "\x8a\x19\xb9\x50\xbc\xf7\x1a\x01"
+                         "\x8e\x5e\x67\x01\xc9\x17\x87\x65"
+                         "\x98\x09\xd6\x7d\xbe\xdd\x18",
+               .ilen   = 23,
+               .result = "\xbc\x21\x8d\xaa\x94\x74\x27\xb6"
+                         "\xdb\x38\x6a\x99\xac\x1a\xef\x23"
+                         "\xad\xe0\xb5\x29\x39\xcb\x6a\x63"
+                         "\x7c\xf9\xbe\xc2\x40\x88\x97\xc6"
+                         "\xba",
+               .rlen   = 33,
+       },
+};
+
+static struct aead_testvec aes_ccm_dec_tv_template[] = {
+       { /* From RFC 3610 */
+               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+               .klen   = 16,
+               .iv     = "\x01\x00\x00\x00\x03\x02\x01\x00"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07",
+               .alen   = 8,
+               .input  = "\x58\x8c\x97\x9a\x61\xc6\x63\xd2"
+                         "\xf0\x66\xd0\xc2\xc0\xf9\x89\x80"
+                         "\x6d\x5f\x6b\x61\xda\xc3\x84\x17"
+                         "\xe8\xd1\x2c\xfd\xf9\x26\xe0",
+               .ilen   = 31,
+               .result = "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e",
+               .rlen   = 23,
+       }, {
+               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+               .klen   = 16,
+               .iv     = "\x01\x00\x00\x00\x07\x06\x05\x04"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b",
+               .alen   = 12,
+               .input  = "\xdc\xf1\xfb\x7b\x5d\x9e\x23\xfb"
+                         "\x9d\x4e\x13\x12\x53\x65\x8a\xd8"
+                         "\x6e\xbd\xca\x3e\x51\xe8\x3f\x07"
+                         "\x7d\x9c\x2d\x93",
+               .ilen   = 28,
+               .result = "\x0c\x0d\x0e\x0f\x10\x11\x12\x13"
+                         "\x14\x15\x16\x17\x18\x19\x1a\x1b"
+                         "\x1c\x1d\x1e\x1f",
+               .rlen   = 20,
+       }, {
+               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+               .klen   = 16,
+               .iv     = "\x01\x00\x00\x00\x0b\x0a\x09\x08"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07",
+               .alen   = 8,
+               .input  = "\x82\x53\x1a\x60\xcc\x24\x94\x5a"
+                         "\x4b\x82\x79\x18\x1a\xb5\xc8\x4d"
+                         "\xf2\x1c\xe7\xf9\xb7\x3f\x42\xe1"
+                         "\x97\xea\x9c\x07\xe5\x6b\x5e\xb1"
+                         "\x7e\x5f\x4e",
+               .ilen   = 35,
+               .result = "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+                         "\x20",
+               .rlen   = 25,
+       }, {
+               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+               .klen   = 16,
+               .iv     = "\x01\x00\x00\x00\x0c\x0b\x0a\x09"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b",
+               .alen   = 12,
+               .input  = "\x07\x34\x25\x94\x15\x77\x85\x15"
+                         "\x2b\x07\x40\x98\x33\x0a\xbb\x14"
+                         "\x1b\x94\x7b\x56\x6a\xa9\x40\x6b"
+                         "\x4d\x99\x99\x88\xdd",
+               .ilen   = 29,
+               .result = "\x0c\x0d\x0e\x0f\x10\x11\x12\x13"
+                         "\x14\x15\x16\x17\x18\x19\x1a\x1b"
+                         "\x1c\x1d\x1e",
+               .rlen   = 19,
+       }, {
+               .key    = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
+                         "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
+               .klen   = 16,
+               .iv     = "\x01\x00\x33\x56\x8e\xf7\xb2\x63"
+                         "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
+               .assoc  = "\x63\x01\x8f\x76\xdc\x8a\x1b\xcb",
+               .alen   = 8,
+               .input  = "\x4c\xcb\x1e\x7c\xa9\x81\xbe\xfa"
+                         "\xa0\x72\x6c\x55\xd3\x78\x06\x12"
+                         "\x98\xc8\x5c\x92\x81\x4a\xbc\x33"
+                         "\xc5\x2e\xe8\x1d\x7d\x77\xc0\x8a",
+               .ilen   = 32,
+               .result = "\x90\x20\xea\x6f\x91\xbd\xd8\x5a"
+                         "\xfa\x00\x39\xba\x4b\xaf\xf9\xbf"
+                         "\xb7\x9c\x70\x28\x94\x9c\xd0\xec",
+               .rlen   = 24,
+       }, {
+               .key    = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
+                         "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
+               .klen   = 16,
+               .iv     = "\x01\x00\xd5\x60\x91\x2d\x3f\x70"
+                         "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
+               .assoc  = "\xcd\x90\x44\xd2\xb7\x1f\xdb\x81"
+                         "\x20\xea\x60\xc0",
+               .alen   = 12,
+               .input  = "\x00\x97\x69\xec\xab\xdf\x48\x62"
+                         "\x55\x94\xc5\x92\x51\xe6\x03\x57"
+                         "\x22\x67\x5e\x04\xc8\x47\x09\x9e"
+                         "\x5a\xe0\x70\x45\x51",
+               .ilen   = 29,
+               .result = "\x64\x35\xac\xba\xfb\x11\xa8\x2e"
+                         "\x2f\x07\x1d\x7c\xa4\xa5\xeb\xd9"
+                         "\x3a\x80\x3b\xa8\x7f",
+               .rlen   = 21,
+       }, {
+               .key    = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
+                         "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
+               .klen   = 16,
+               .iv     = "\x01\x00\x42\xff\xf8\xf1\x95\x1c"
+                         "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
+               .assoc  = "\xd8\x5b\xc7\xe6\x9f\x94\x4f\xb8",
+               .alen   = 8,
+               .input  = "\xbc\x21\x8d\xaa\x94\x74\x27\xb6"
+                         "\xdb\x38\x6a\x99\xac\x1a\xef\x23"
+                         "\xad\xe0\xb5\x29\x39\xcb\x6a\x63"
+                         "\x7c\xf9\xbe\xc2\x40\x88\x97\xc6"
+                         "\xba",
+               .ilen   = 33,
+               .result = "\x8a\x19\xb9\x50\xbc\xf7\x1a\x01"
+                         "\x8e\x5e\x67\x01\xc9\x17\x87\x65"
+                         "\x98\x09\xd6\x7d\xbe\xdd\x18",
+               .rlen   = 23,
+       },
+};
+
+/*
+ * rfc4309 refers to section 8 of rfc3610 for test vectors, but they all
+ * use a 13-byte nonce, we only support an 11-byte nonce. Similarly, all of
+ * Special Publication 800-38C's test vectors also use nonce lengths our
+ * implementation doesn't support. The following are taken from fips cavs
+ * fax files on hand at Red Hat.
+ *
+ * nb: actual key lengths are (klen - 3), the last 3 bytes are actually
+ * part of the nonce which combine w/the iv, but need to be input this way.
+ */
+static struct aead_testvec aes_ccm_rfc4309_enc_tv_template[] = {
+       {
+               .key    = "\x83\xac\x54\x66\xc2\xeb\xe5\x05"
+                         "\x2e\x01\xd1\xfc\x5d\x82\x66\x2e"
+                         "\x96\xac\x59",
+               .klen   = 19,
+               .iv     = "\x30\x07\xa1\xe2\xa2\xc7\x55\x24",
+               .alen   = 0,
+               .input  = "\x19\xc8\x81\xf6\xe9\x86\xff\x93"
+                         "\x0b\x78\x67\xe5\xbb\xb7\xfc\x6e"
+                         "\x83\x77\xb3\xa6\x0c\x8c\x9f\x9c"
+                         "\x35\x2e\xad\xe0\x62\xf9\x91\xa1",
+               .ilen   = 32,
+               .result = "\xab\x6f\xe1\x69\x1d\x19\x99\xa8"
+                         "\x92\xa0\xc4\x6f\x7e\xe2\x8b\xb1"
+                         "\x70\xbb\x8c\xa6\x4c\x6e\x97\x8a"
+                         "\x57\x2b\xbe\x5d\x98\xa6\xb1\x32"
+                         "\xda\x24\xea\xd9\xa1\x39\x98\xfd"
+                         "\xa4\xbe\xd9\xf2\x1a\x6d\x22\xa8",
+               .rlen   = 48,
+       }, {
+               .key    = "\x1e\x2c\x7e\x01\x41\x9a\xef\xc0"
+                         "\x0d\x58\x96\x6e\x5c\xa2\x4b\xd3"
+                         "\x4f\xa3\x19",
+               .klen   = 19,
+               .iv     = "\xd3\x01\x5a\xd8\x30\x60\x15\x56",
+               .assoc  = "\xda\xe6\x28\x9c\x45\x2d\xfd\x63"
+                         "\x5e\xda\x4c\xb6\xe6\xfc\xf9\xb7"
+                         "\x0c\x56\xcb\xe4\xe0\x05\x7a\xe1"
+                         "\x0a\x63\x09\x78\xbc\x2c\x55\xde",
+               .alen   = 32,
+               .input  = "\x87\xa3\x36\xfd\x96\xb3\x93\x78"
+                         "\xa9\x28\x63\xba\x12\xa3\x14\x85"
+                         "\x57\x1e\x06\xc9\x7b\x21\xef\x76"
+                         "\x7f\x38\x7e\x8e\x29\xa4\x3e\x7e",
+               .ilen   = 32,
+               .result = "\x8a\x1e\x11\xf0\x02\x6b\xe2\x19"
+                         "\xfc\x70\xc4\x6d\x8e\xb7\x99\xab"
+                         "\xc5\x4b\xa2\xac\xd3\xf3\x48\xff"
+                         "\x3b\xb5\xce\x53\xef\xde\xbb\x02"
+                         "\xa9\x86\x15\x6c\x13\xfe\xda\x0a"
+                         "\x22\xb8\x29\x3d\xd8\x39\x9a\x23",
+               .rlen   = 48,
+       }, {
+               .key    = "\xf4\x6b\xc2\x75\x62\xfe\xb4\xe1"
+                         "\xa3\xf0\xff\xdd\x4e\x4b\x12\x75"
+                         "\x53\x14\x73\x66\x8d\x88\xf6\x80"
+                         "\xa0\x20\x35",
+               .klen   = 27,
+               .iv     = "\x26\xf2\x21\x8d\x50\x20\xda\xe2",
+               .assoc  = "\x5b\x9e\x13\x67\x02\x5e\xef\xc1"
+                         "\x6c\xf9\xd7\x1e\x52\x8f\x7a\x47"
+                         "\xe9\xd4\xcf\x20\x14\x6e\xf0\x2d"
+                         "\xd8\x9e\x2b\x56\x10\x23\x56\xe7",
+               .alen   = 32,
+               .ilen   = 0,
+               .result = "\x36\xea\x7a\x70\x08\xdc\x6a\xbc"
+                         "\xad\x0c\x7a\x63\xf6\x61\xfd\x9b",
+               .rlen   = 16,
+       }, {
+               .key    = "\x56\xdf\x5c\x8f\x26\x3f\x0e\x42"
+                         "\xef\x7a\xd3\xce\xfc\x84\x60\x62"
+                         "\xca\xb4\x40\xaf\x5f\xc9\xc9\x01"
+                         "\xd6\x3c\x8c",
+               .klen   = 27,
+               .iv     = "\x86\x84\xb6\xcd\xef\x09\x2e\x94",
+               .assoc  = "\x02\x65\x78\x3c\xe9\x21\x30\x91"
+                         "\xb1\xb9\xda\x76\x9a\x78\x6d\x95"
+                         "\xf2\x88\x32\xa3\xf2\x50\xcb\x4c"
+                         "\xe3\x00\x73\x69\x84\x69\x87\x79",
+               .alen   = 32,
+               .input  = "\x9f\xd2\x02\x4b\x52\x49\x31\x3c"
+                         "\x43\x69\x3a\x2d\x8e\x70\xad\x7e"
+                         "\xe0\xe5\x46\x09\x80\x89\x13\xb2"
+                         "\x8c\x8b\xd9\x3f\x86\xfb\xb5\x6b",
+               .ilen   = 32,
+               .result = "\x39\xdf\x7c\x3c\x5a\x29\xb9\x62"
+                         "\x5d\x51\xc2\x16\xd8\xbd\x06\x9f"
+                         "\x9b\x6a\x09\x70\xc1\x51\x83\xc2"
+                         "\x66\x88\x1d\x4f\x9a\xda\xe0\x1e"
+                         "\xc7\x79\x11\x58\xe5\x6b\x20\x40"
+                         "\x7a\xea\x46\x42\x8b\xe4\x6f\xe1",
+               .rlen   = 48,
+       }, {
+               .key    = "\xe0\x8d\x99\x71\x60\xd7\x97\x1a"
+                         "\xbd\x01\x99\xd5\x8a\xdf\x71\x3a"
+                         "\xd3\xdf\x24\x4b\x5e\x3d\x4b\x4e"
+                         "\x30\x7a\xb9\xd8\x53\x0a\x5e\x2b"
+                         "\x1e\x29\x91",
+               .klen   = 35,
+               .iv     = "\xad\x8e\xc1\x53\x0a\xcf\x2d\xbe",
+               .assoc  = "\x19\xb6\x1f\x57\xc4\xf3\xf0\x8b"
+                         "\x78\x2b\x94\x02\x29\x0f\x42\x27"
+                         "\x6b\x75\xcb\x98\x34\x08\x7e\x79"
+                         "\xe4\x3e\x49\x0d\x84\x8b\x22\x87",
+               .alen   = 32,
+               .input  = "\xe1\xd9\xd8\x13\xeb\x3a\x75\x3f"
+                         "\x9d\xbd\x5f\x66\xbe\xdc\xbb\x66"
+                         "\xbf\x17\x99\x62\x4a\x39\x27\x1f"
+                         "\x1d\xdc\x24\xae\x19\x2f\x98\x4c",
+               .ilen   = 32,
+               .result = "\x19\xb8\x61\x33\x45\x2b\x43\x96"
+                         "\x6f\x51\xd0\x20\x30\x7d\x9b\xc6"
+                         "\x26\x3d\xf8\xc9\x65\x16\xa8\x9f"
+                         "\xf0\x62\x17\x34\xf2\x1e\x8d\x75"
+                         "\x4e\x13\xcc\xc0\xc3\x2a\x54\x2d",
+               .rlen   = 40,
+       }, {
+               .key    = "\x7c\xc8\x18\x3b\x8d\x99\xe0\x7c"
+                         "\x45\x41\xb8\xbd\x5c\xa7\xc2\x32"
+                         "\x8a\xb8\x02\x59\xa4\xfe\xa9\x2c"
+                         "\x09\x75\x9a\x9b\x3c\x9b\x27\x39"
+                         "\xf9\xd9\x4e",
+               .klen   = 35,
+               .iv     = "\x63\xb5\x3d\x9d\x43\xf6\x1e\x50",
+               .assoc  = "\x57\xf5\x6b\x8b\x57\x5c\x3d\x3b"
+                         "\x13\x02\x01\x0c\x83\x4c\x96\x35"
+                         "\x8e\xd6\x39\xcf\x7d\x14\x9b\x94"
+                         "\xb0\x39\x36\xe6\x8f\x57\xe0\x13",
+               .alen   = 32,
+               .input  = "\x3b\x6c\x29\x36\xb6\xef\x07\xa6"
+                         "\x83\x72\x07\x4f\xcf\xfa\x66\x89"
+                         "\x5f\xca\xb1\xba\xd5\x8f\x2c\x27"
+                         "\x30\xdb\x75\x09\x93\xd4\x65\xe4",
+               .ilen   = 32,
+               .result = "\xb0\x88\x5a\x33\xaa\xe5\xc7\x1d"
+                         "\x85\x23\xc7\xc6\x2f\xf4\x1e\x3d"
+                         "\xcc\x63\x44\x25\x07\x78\x4f\x9e"
+                         "\x96\xb8\x88\xeb\xbc\x48\x1f\x06"
+                         "\x39\xaf\x39\xac\xd8\x4a\x80\x39"
+                         "\x7b\x72\x8a\xf7",
+               .rlen   = 44,
+       }, {
+               .key    = "\xab\xd0\xe9\x33\x07\x26\xe5\x83"
+                         "\x8c\x76\x95\xd4\xb6\xdc\xf3\x46"
+                         "\xf9\x8f\xad\xe3\x02\x13\x83\x77"
+                         "\x3f\xb0\xf1\xa1\xa1\x22\x0f\x2b"
+                         "\x24\xa7\x8b",
+               .klen   = 35,
+               .iv     = "\x07\xcb\xcc\x0e\xe6\x33\xbf\xf5",
+               .assoc  = "\xd4\xdb\x30\x1d\x03\xfe\xfd\x5f"
+                         "\x87\xd4\x8c\xb6\xb6\xf1\x7a\x5d"
+                         "\xab\x90\x65\x8d\x8e\xca\x4d\x4f"
+                         "\x16\x0c\x40\x90\x4b\xc7\x36\x73",
+               .alen   = 32,
+               .input  = "\xf5\xc6\x7d\x48\xc1\xb7\xe6\x92"
+                         "\x97\x5a\xca\xc4\xa9\x6d\xf9\x3d"
+                         "\x6c\xde\xbc\xf1\x90\xea\x6a\xb2"
+                         "\x35\x86\x36\xaf\x5c\xfe\x4b\x3a",
+               .ilen   = 32,
+               .result = "\x83\x6f\x40\x87\x72\xcf\xc1\x13"
+                         "\xef\xbb\x80\x21\x04\x6c\x58\x09"
+                         "\x07\x1b\xfc\xdf\xc0\x3f\x5b\xc7"
+                         "\xe0\x79\xa8\x6e\x71\x7c\x3f\xcf"
+                         "\x5c\xda\xb2\x33\xe5\x13\xe2\x0d"
+                         "\x74\xd1\xef\xb5\x0f\x3a\xb5\xf8",
+               .rlen   = 48,
+       },
+};
+
+static struct aead_testvec aes_ccm_rfc4309_dec_tv_template[] = {
+       {
+               .key    = "\xab\x2f\x8a\x74\xb7\x1c\xd2\xb1"
+                         "\xff\x80\x2e\x48\x7d\x82\xf8\xb9"
+                         "\xc6\xfb\x7d",
+               .klen   = 19,
+               .iv     = "\x80\x0d\x13\xab\xd8\xa6\xb2\xd8",
+               .alen   = 0,
+               .input  = "\xd5\xe8\x93\x9f\xc7\x89\x2e\x2b",
+               .ilen   = 8,
+               .result = "\x00",
+               .rlen   = 0,
+               .novrfy = 1,
+       }, {
+               .key    = "\xab\x2f\x8a\x74\xb7\x1c\xd2\xb1"
+                         "\xff\x80\x2e\x48\x7d\x82\xf8\xb9"
+                         "\xaf\x94\x87",
+               .klen   = 19,
+               .iv     = "\x78\x35\x82\x81\x7f\x88\x94\x68",
+               .alen   = 0,
+               .input  = "\x41\x3c\xb8\x87\x73\xcb\xf3\xf3",
+               .ilen   = 8,
+               .result = "\x00",
+               .rlen   = 0,
+       }, {
+               .key    = "\x61\x0e\x8c\xae\xe3\x23\xb6\x38"
+                         "\x76\x1c\xf6\x3a\x67\xa3\x9c\xd8"
+                         "\xc6\xfb\x7d",
+               .klen   = 19,
+               .iv     = "\x80\x0d\x13\xab\xd8\xa6\xb2\xd8",
+               .assoc  = "\xf3\x94\x87\x78\x35\x82\x81\x7f"
+                         "\x88\x94\x68\xb1\x78\x6b\x2b\xd6"
+                         "\x04\x1f\x4e\xed\x78\xd5\x33\x66"
+                         "\xd8\x94\x99\x91\x81\x54\x62\x57",
+               .alen   = 32,
+               .input  = "\xf0\x7c\x29\x02\xae\x1c\x2f\x55"
+                         "\xd0\xd1\x3d\x1a\xa3\x6d\xe4\x0a"
+                         "\x86\xb0\x87\x6b\x62\x33\x8c\x34"
+                         "\xce\xab\x57\xcc\x79\x0b\xe0\x6f"
+                         "\x5c\x3e\x48\x1f\x6c\x46\xf7\x51"
+                         "\x8b\x84\x83\x2a\xc1\x05\xb8\xc5",
+               .ilen   = 48,
+               .result = "\x50\x82\x3e\x07\xe2\x1e\xb6\xfb"
+                         "\x33\xe4\x73\xce\xd2\xfb\x95\x79"
+                         "\xe8\xb4\xb5\x77\x11\x10\x62\x6f"
+                         "\x6a\x82\xd1\x13\xec\xf5\xd0\x48",
+               .rlen   = 32,
+               .novrfy = 1,
+       }, {
+               .key    = "\x61\x0e\x8c\xae\xe3\x23\xb6\x38"
+                         "\x76\x1c\xf6\x3a\x67\xa3\x9c\xd8"
+                         "\x05\xe0\xc9",
+               .klen   = 19,
+               .iv     = "\x0f\xed\x34\xea\x97\xd4\x3b\xdf",
+               .assoc  = "\x49\x5c\x50\x1f\x1d\x94\xcc\x81"
+                         "\xba\xb7\xb6\x03\xaf\xa5\xc1\xa1"
+                         "\xd8\x5c\x42\x68\xe0\x6c\xda\x89"
+                         "\x05\xac\x56\xac\x1b\x2a\xd3\x86",
+               .alen   = 32,
+               .input  = "\x39\xbe\x7d\x15\x62\x77\xf3\x3c"
+                         "\xad\x83\x52\x6d\x71\x03\x25\x1c"
+                         "\xed\x81\x3a\x9a\x16\x7d\x19\x80"
+                         "\x72\x04\x72\xd0\xf6\xff\x05\x0f"
+                         "\xb7\x14\x30\x00\x32\x9e\xa0\xa6"
+                         "\x9e\x5a\x18\xa1\xb8\xfe\xdb\xd3",
+               .ilen   = 48,
+               .result = "\x75\x05\xbe\xc2\xd9\x1e\xde\x60"
+                         "\x47\x3d\x8c\x7d\xbd\xb5\xd9\xb7"
+                         "\xf2\xae\x61\x05\x8f\x82\x24\x3f"
+                         "\x9c\x67\x91\xe1\x38\x4f\xe4\x0c",
+               .rlen   = 32,
+       }, {
+               .key    = "\x39\xbb\xa7\xbe\x59\x97\x9e\x73"
+                         "\xa2\xbc\x6b\x98\xd7\x75\x7f\xe3"
+                         "\xa4\x48\x93\x39\x26\x71\x4a\xc6"
+                         "\xee\x49\x83",
+               .klen   = 27,
+               .iv     = "\xe9\xa9\xff\xe9\x57\xba\xfd\x9e",
+               .assoc  = "\x44\xa6\x2c\x05\xe9\xe1\x43\xb1"
+                         "\x58\x7c\xf2\x5c\x6d\x39\x0a\x64"
+                         "\xa4\xf0\x13\x05\xd1\x77\x99\x67"
+                         "\x11\xc4\xc6\xdb\x00\x56\x36\x61",
+               .alen   = 32,
+               .input  = "\x71\x99\xfa\xf4\x44\x12\x68\x9b",
+               .ilen   = 8,
+               .result = "\x00",
+               .rlen   = 0,
+       }, {
+               .key    = "\x58\x5d\xa0\x96\x65\x1a\x04\xd7"
+                         "\x96\xe5\xc5\x68\xaa\x95\x35\xe0"
+                         "\x29\xa0\xba\x9e\x48\x78\xd1\xba"
+                         "\xee\x49\x83",
+               .klen   = 27,
+               .iv     = "\xe9\xa9\xff\xe9\x57\xba\xfd\x9e",
+               .assoc  = "\x44\xa6\x2c\x05\xe9\xe1\x43\xb1"
+                         "\x58\x7c\xf2\x5c\x6d\x39\x0a\x64"
+                         "\xa4\xf0\x13\x05\xd1\x77\x99\x67"
+                         "\x11\xc4\xc6\xdb\x00\x56\x36\x61",
+               .alen   = 32,
+               .input  = "\xfb\xe5\x5d\x34\xbe\xe5\xe8\xe7"
+                         "\x5a\xef\x2f\xbf\x1f\x7f\xd4\xb2"
+                         "\x66\xca\x61\x1e\x96\x7a\x61\xb3"
+                         "\x1c\x16\x45\x52\xba\x04\x9c\x9f"
+                         "\xb1\xd2\x40\xbc\x52\x7c\x6f\xb1",
+               .ilen   = 40,
+               .result = "\x85\x34\x66\x42\xc8\x92\x0f\x36"
+                         "\x58\xe0\x6b\x91\x3c\x98\x5c\xbb"
+                         "\x0a\x85\xcc\x02\xad\x7a\x96\xe9"
+                         "\x65\x43\xa4\xc3\x0f\xdc\x55\x81",
+               .rlen   = 32,
+       }, {
+               .key    = "\x58\x5d\xa0\x96\x65\x1a\x04\xd7"
+                         "\x96\xe5\xc5\x68\xaa\x95\x35\xe0"
+                         "\x29\xa0\xba\x9e\x48\x78\xd1\xba"
+                         "\xd1\xfc\x57",
+               .klen   = 27,
+               .iv     = "\x9c\xfe\xb8\x9c\xad\x71\xaa\x1f",
+               .assoc  = "\x86\x67\xa5\xa9\x14\x5f\x0d\xc6"
+                         "\xff\x14\xc7\x44\xbf\x6c\x3a\xc3"
+                         "\xff\xb6\x81\xbd\xe2\xd5\x06\xc7"
+                         "\x3c\xa1\x52\x13\x03\x8a\x23\x3a",
+               .alen   = 32,
+               .input  = "\x3f\x66\xb0\x9d\xe5\x4b\x38\x00"
+                         "\xc6\x0e\x6e\xe5\xd6\x98\xa6\x37"
+                         "\x8c\x26\x33\xc6\xb2\xa2\x17\xfa"
+                         "\x64\x19\xc0\x30\xd7\xfc\x14\x6b"
+                         "\xe3\x33\xc2\x04\xb0\x37\xbe\x3f"
+                         "\xa9\xb4\x2d\x68\x03\xa3\x44\xef",
+               .ilen   = 48,
+               .result = "\x02\x87\x4d\x28\x80\x6e\xb2\xed"
+                         "\x99\x2a\xa8\xca\x04\x25\x45\x90"
+                         "\x1d\xdd\x5a\xd9\xe4\xdb\x9c\x9c"
+                         "\x49\xe9\x01\xfe\xa7\x80\x6d\x6b",
+               .rlen   = 32,
+               .novrfy = 1,
+       }, {
+               .key    = "\xa4\x4b\x54\x29\x0a\xb8\x6d\x01"
+                         "\x5b\x80\x2a\xcf\x25\xc4\xb7\x5c"
+                         "\x20\x2c\xad\x30\xc2\x2b\x41\xfb"
+                         "\x0e\x85\xbc\x33\xad\x0f\x2b\xff"
+                         "\xee\x49\x83",
+               .klen   = 35,
+               .iv     = "\xe9\xa9\xff\xe9\x57\xba\xfd\x9e",
+               .alen   = 0,
+               .input  = "\x1f\xb8\x8f\xa3\xdd\x54\x00\xf2",
+               .ilen   = 8,
+               .result = "\x00",
+               .rlen   = 0,
+       }, {
+               .key    = "\x39\xbb\xa7\xbe\x59\x97\x9e\x73"
+                         "\xa2\xbc\x6b\x98\xd7\x75\x7f\xe3"
+                         "\xa4\x48\x93\x39\x26\x71\x4a\xc6"
+                         "\xae\x8f\x11\x4c\xc2\x9c\x4a\xbb"
+                         "\x85\x34\x66",
+               .klen   = 35,
+               .iv     = "\x42\xc8\x92\x0f\x36\x58\xe0\x6b",
+               .alen   = 0,
+               .input  = "\x48\x01\x5e\x02\x24\x04\x66\x47"
+                         "\xa1\xea\x6f\xaf\xe8\xfc\xfb\xdd"
+                         "\xa5\xa9\x87\x8d\x84\xee\x2e\x77"
+                         "\xbb\x86\xb9\xf5\x5c\x6c\xff\xf6"
+                         "\x72\xc3\x8e\xf7\x70\xb1\xb2\x07"
+                         "\xbc\xa8\xa3\xbd\x83\x7c\x1d\x2a",
+               .ilen   = 48,
+               .result = "\xdc\x56\xf2\x71\xb0\xb1\xa0\x6c"
+                         "\xf0\x97\x3a\xfb\x6d\xe7\x32\x99"
+                         "\x3e\xaf\x70\x5e\xb2\x4d\xea\x39"
+                         "\x89\xd4\x75\x7a\x63\xb1\xda\x93",
+               .rlen   = 32,
+               .novrfy = 1,
+       }, {
+               .key    = "\x58\x5d\xa0\x96\x65\x1a\x04\xd7"
+                         "\x96\xe5\xc5\x68\xaa\x95\x35\xe0"
+                         "\x29\xa0\xba\x9e\x48\x78\xd1\xba"
+                         "\x0d\x1a\x53\x3b\xb5\xe3\xf8\x8b"
+                         "\xcf\x76\x3f",
+               .klen   = 35,
+               .iv     = "\xd9\x95\x75\x8f\x44\x89\x40\x7b",
+               .assoc  = "\x8f\x86\x6c\x4d\x1d\xc5\x39\x88"
+                         "\xc8\xf3\x5c\x52\x10\x63\x6f\x2b"
+                         "\x8a\x2a\xc5\x6f\x30\x23\x58\x7b"
+                         "\xfb\x36\x03\x11\xb4\xd9\xf2\xfe",
+               .alen   = 32,
+               .input  = "\x48\x58\xd6\xf3\xad\x63\x58\xbf"
+                         "\xae\xc7\x5e\xae\x83\x8f\x7b\xe4"
+                         "\x78\x5c\x4c\x67\x71\x89\x94\xbf"
+                         "\x47\xf1\x63\x7e\x1c\x59\xbd\xc5"
+                         "\x7f\x44\x0a\x0c\x01\x18\x07\x92"
+                         "\xe1\xd3\x51\xce\x32\x6d\x0c\x5b",
+               .ilen   = 48,
+               .result = "\xc2\x54\xc8\xde\x78\x87\x77\x40"
+                         "\x49\x71\xe4\xb7\xe7\xcb\x76\x61"
+                         "\x0a\x41\xb9\xe9\xc0\x76\x54\xab"
+                         "\x04\x49\x3b\x19\x93\x57\x25\x5d",
+               .rlen   = 32,
+       },
+};
+
+/*
+ * ANSI X9.31 Continuous Pseudo-Random Number Generator (
+ * test vectors, taken from Appendix B.2.9 and B.2.10:
+ *     http://csrc.nist.gov/groups/STM/cavp/documents/rng/RNGVS.pdf
+ * Only AES-128 is supported at this time.
+ */
+#define ANSI_CPRNG_AES_TEST_VECTORS    6
+
+static struct cprng_testvec ansi_cprng_aes_tv_template[] = {
+       {
+               .key    = "\xf3\xb1\x66\x6d\x13\x60\x72\x42"
+                         "\xed\x06\x1c\xab\xb8\xd4\x62\x02",
+               .klen   = 16,
+               .dt     = "\xe6\xb3\xbe\x78\x2a\x23\xfa\x62"
+                         "\xd7\x1d\x4a\xfb\xb0\xe9\x22\xf9",
+               .dtlen  = 16,
+               .v      = "\x80\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .vlen   = 16,
+               .result = "\x59\x53\x1e\xd1\x3b\xb0\xc0\x55"
+                         "\x84\x79\x66\x85\xc1\x2f\x76\x41",
+               .rlen   = 16,
+               .loops  = 1,
+       }, {
+               .key    = "\xf3\xb1\x66\x6d\x13\x60\x72\x42"
+                         "\xed\x06\x1c\xab\xb8\xd4\x62\x02",
+               .klen   = 16,
+               .dt     = "\xe6\xb3\xbe\x78\x2a\x23\xfa\x62"
+                         "\xd7\x1d\x4a\xfb\xb0\xe9\x22\xfa",
+               .dtlen  = 16,
+               .v      = "\xc0\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .vlen   = 16,
+               .result = "\x7c\x22\x2c\xf4\xca\x8f\xa2\x4c"
+                         "\x1c\x9c\xb6\x41\xa9\xf3\x22\x0d",
+               .rlen   = 16,
+               .loops  = 1,
+       }, {
+               .key    = "\xf3\xb1\x66\x6d\x13\x60\x72\x42"
+                         "\xed\x06\x1c\xab\xb8\xd4\x62\x02",
+               .klen   = 16,
+               .dt     = "\xe6\xb3\xbe\x78\x2a\x23\xfa\x62"
+                         "\xd7\x1d\x4a\xfb\xb0\xe9\x22\xfb",
+               .dtlen  = 16,
+               .v      = "\xe0\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .vlen   = 16,
+               .result = "\x8a\xaa\x00\x39\x66\x67\x5b\xe5"
+                         "\x29\x14\x28\x81\xa9\x4d\x4e\xc7",
+               .rlen   = 16,
+               .loops  = 1,
+       }, {
+               .key    = "\xf3\xb1\x66\x6d\x13\x60\x72\x42"
+                         "\xed\x06\x1c\xab\xb8\xd4\x62\x02",
+               .klen   = 16,
+               .dt     = "\xe6\xb3\xbe\x78\x2a\x23\xfa\x62"
+                         "\xd7\x1d\x4a\xfb\xb0\xe9\x22\xfc",
+               .dtlen  = 16,
+               .v      = "\xf0\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .vlen   = 16,
+               .result = "\x88\xdd\xa4\x56\x30\x24\x23\xe5"
+                         "\xf6\x9d\xa5\x7e\x7b\x95\xc7\x3a",
+               .rlen   = 16,
+               .loops  = 1,
+       }, {
+               .key    = "\xf3\xb1\x66\x6d\x13\x60\x72\x42"
+                         "\xed\x06\x1c\xab\xb8\xd4\x62\x02",
+               .klen   = 16,
+               .dt     = "\xe6\xb3\xbe\x78\x2a\x23\xfa\x62"
+                         "\xd7\x1d\x4a\xfb\xb0\xe9\x22\xfd",
+               .dtlen  = 16,
+               .v      = "\xf8\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .vlen   = 16,
+               .result = "\x05\x25\x92\x46\x61\x79\xd2\xcb"
+                         "\x78\xc4\x0b\x14\x0a\x5a\x9a\xc8",
+               .rlen   = 16,
+               .loops  = 1,
+       }, {    /* Monte Carlo Test */
+               .key    = "\x9f\x5b\x51\x20\x0b\xf3\x34\xb5"
+                         "\xd8\x2b\xe8\xc3\x72\x55\xc8\x48",
+               .klen   = 16,
+               .dt     = "\x63\x76\xbb\xe5\x29\x02\xba\x3b"
+                         "\x67\xc9\x25\xfa\x70\x1f\x11\xac",
+               .dtlen  = 16,
+               .v      = "\x57\x2c\x8e\x76\x87\x26\x47\x97"
+                         "\x7e\x74\xfb\xdd\xc4\x95\x01\xd1",
+               .vlen   = 16,
+               .result = "\x48\xe9\xbd\x0d\x06\xee\x18\xfb"
+                         "\xe4\x57\x90\xd5\xc3\xfc\x9b\x73",
+               .rlen   = 16,
+               .loops  = 10000,
+       },
+};
+
+/* Cast5 test vectors from RFC 2144 */
+#define CAST5_ENC_TEST_VECTORS 3
+#define CAST5_DEC_TEST_VECTORS 3
+
+static struct cipher_testvec cast5_enc_tv_template[] = {
+       {
+               .key    = "\x01\x23\x45\x67\x12\x34\x56\x78"
+                         "\x23\x45\x67\x89\x34\x56\x78\x9a",
+               .klen   = 16,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .ilen   = 8,
+               .result = "\x23\x8b\x4f\xe5\x84\x7e\x44\xb2",
+               .rlen   = 8,
+       }, {
+               .key    = "\x01\x23\x45\x67\x12\x34\x56\x78"
+                         "\x23\x45",
+               .klen   = 10,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .ilen   = 8,
+               .result = "\xeb\x6a\x71\x1a\x2c\x02\x27\x1b",
+               .rlen   = 8,
+       }, {
+               .key    = "\x01\x23\x45\x67\x12",
+               .klen   = 5,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .ilen   = 8,
+               .result = "\x7a\xc8\x16\xd1\x6e\x9b\x30\x2e",
+               .rlen   = 8,
+       },
+};
+
+static struct cipher_testvec cast5_dec_tv_template[] = {
+       {
+               .key    = "\x01\x23\x45\x67\x12\x34\x56\x78"
+                         "\x23\x45\x67\x89\x34\x56\x78\x9a",
+               .klen   = 16,
+               .input  = "\x23\x8b\x4f\xe5\x84\x7e\x44\xb2",
+               .ilen   = 8,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .rlen   = 8,
+       }, {
+               .key    = "\x01\x23\x45\x67\x12\x34\x56\x78"
+                         "\x23\x45",
+               .klen   = 10,
+               .input  = "\xeb\x6a\x71\x1a\x2c\x02\x27\x1b",
+               .ilen   = 8,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .rlen   = 8,
+       }, {
+               .key    = "\x01\x23\x45\x67\x12",
+               .klen   = 5,
+               .input  = "\x7a\xc8\x16\xd1\x6e\x9b\x30\x2e",
+               .ilen   = 8,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .rlen   = 8,
+       },
+};
+
+/*
+ * ARC4 test vectors from OpenSSL
+ */
+#define ARC4_ENC_TEST_VECTORS  7
+#define ARC4_DEC_TEST_VECTORS  7
+
+static struct cipher_testvec arc4_enc_tv_template[] = {
+       {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .ilen   = 8,
+               .result = "\x75\xb7\x87\x80\x99\xe0\xc5\x96",
+               .rlen   = 8,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 8,
+               .result = "\x74\x94\xc2\xe7\x10\x4b\x08\x79",
+               .rlen   = 8,
+       }, {
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 8,
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 8,
+               .result = "\xde\x18\x89\x41\xa3\x37\x5d\x3a",
+               .rlen   = 8,
+       }, {
+               .key    = "\xef\x01\x23\x45",
+               .klen   = 4,
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00",
+               .ilen   = 20,
+               .result = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf"
+                         "\xbd\x61\x5a\x11\x62\xe1\xc7\xba"
+                         "\x36\xb6\x78\x58",
+               .rlen   = 20,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
+                         "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
+                         "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
+                         "\x12\x34\x56\x78",
+               .ilen   = 28,
+               .result = "\x66\xa0\x94\x9f\x8a\xf7\xd6\x89"
+                         "\x1f\x7f\x83\x2b\xa8\x33\xc0\x0c"
+                         "\x89\x2e\xbe\x30\x14\x3c\xe2\x87"
+                         "\x40\x01\x1e\xcf",
+               .rlen   = 28,
+       }, {
+               .key    = "\xef\x01\x23\x45",
+               .klen   = 4,
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00",
+               .ilen   = 10,
+               .result = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf"
+                         "\xbd\x61",
+               .rlen   = 10,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xAB\xCD\xEF"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 16,
+               .input  = "\x01\x23\x45\x67\x89\xAB\xCD\xEF",
+               .ilen   = 8,
+               .result = "\x69\x72\x36\x59\x1B\x52\x42\xB1",
+               .rlen   = 8,
+       },
+};
+
+static struct cipher_testvec arc4_dec_tv_template[] = {
+       {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x75\xb7\x87\x80\x99\xe0\xc5\x96",
+               .ilen   = 8,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .rlen   = 8,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x74\x94\xc2\xe7\x10\x4b\x08\x79",
+               .ilen   = 8,
+               .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .rlen   = 8,
+       }, {
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 8,
+               .input  = "\xde\x18\x89\x41\xa3\x37\x5d\x3a",
+               .ilen   = 8,
+               .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .rlen   = 8,
+       }, {
+               .key    = "\xef\x01\x23\x45",
+               .klen   = 4,
+               .input  = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf"
+                         "\xbd\x61\x5a\x11\x62\xe1\xc7\xba"
+                         "\x36\xb6\x78\x58",
+               .ilen   = 20,
+               .result = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00",
+               .rlen   = 20,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x66\xa0\x94\x9f\x8a\xf7\xd6\x89"
+                         "\x1f\x7f\x83\x2b\xa8\x33\xc0\x0c"
+                         "\x89\x2e\xbe\x30\x14\x3c\xe2\x87"
+                         "\x40\x01\x1e\xcf",
+               .ilen   = 28,
+               .result = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
+                         "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
+                         "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
+                         "\x12\x34\x56\x78",
+               .rlen   = 28,
+       }, {
+               .key    = "\xef\x01\x23\x45",
+               .klen   = 4,
+               .input  = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf"
+                         "\xbd\x61",
+               .ilen   = 10,
+               .result = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00",
+               .rlen   = 10,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xAB\xCD\xEF"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 16,
+               .input  = "\x69\x72\x36\x59\x1B\x52\x42\xB1",
+               .ilen   = 8,
+               .result = "\x01\x23\x45\x67\x89\xAB\xCD\xEF",
+               .rlen   = 8,
+       },
+};
+
+/*
+ * TEA test vectors
+ */
+#define TEA_ENC_TEST_VECTORS   4
+#define TEA_DEC_TEST_VECTORS   4
+
+static struct cipher_testvec tea_enc_tv_template[] = {
+       {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = zeroed_string,
+               .ilen   = 8,
+               .result = "\x0a\x3a\xea\x41\x40\xa9\xba\x94",
+               .rlen   = 8,
+       }, {
+               .key    = "\x2b\x02\x05\x68\x06\x14\x49\x76"
+                         "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
+               .klen   = 16,
+               .input  = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
+               .ilen   = 8,
+               .result = "\x77\x5d\x2a\x6a\xf6\xce\x92\x09",
+               .rlen   = 8,
+       }, {
+               .key    = "\x09\x65\x43\x11\x66\x44\x39\x25"
+                         "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
+               .klen   = 16,
+               .input  = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
+                         "\x65\x73\x74\x5f\x76\x65\x63\x74",
+               .ilen   = 16,
+               .result = "\xbe\x7a\xbb\x81\x95\x2d\x1f\x1e"
+                         "\xdd\x89\xa1\x25\x04\x21\xdf\x95",
+               .rlen   = 16,
+       }, {
+               .key    = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
+                         "\x5d\x04\x16\x36\x15\x72\x63\x2f",
+               .klen   = 16,
+               .input  = "\x54\x65\x61\x20\x69\x73\x20\x67"
+                         "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
+                         "\x79\x6f\x75\x21\x21\x21\x20\x72"
+                         "\x65\x61\x6c\x6c\x79\x21\x21\x21",
+               .ilen   = 32,
+               .result = "\xe0\x4d\x5d\x3c\xb7\x8c\x36\x47"
+                         "\x94\x18\x95\x91\xa9\xfc\x49\xf8"
+                         "\x44\xd1\x2d\xc2\x99\xb8\x08\x2a"
+                         "\x07\x89\x73\xc2\x45\x92\xc6\x90",
+               .rlen   = 32,
+       }
+};
+
+static struct cipher_testvec tea_dec_tv_template[] = {
+       {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = "\x0a\x3a\xea\x41\x40\xa9\xba\x94",
+               .ilen   = 8,
+               .result = zeroed_string,
+               .rlen   = 8,
+       }, {
+               .key    = "\x2b\x02\x05\x68\x06\x14\x49\x76"
+                         "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
+               .klen   = 16,
+               .input  = "\x77\x5d\x2a\x6a\xf6\xce\x92\x09",
+               .ilen   = 8,
+               .result = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
+               .rlen   = 8,
+       }, {
+               .key    = "\x09\x65\x43\x11\x66\x44\x39\x25"
+                         "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
+               .klen   = 16,
+               .input  = "\xbe\x7a\xbb\x81\x95\x2d\x1f\x1e"
+                         "\xdd\x89\xa1\x25\x04\x21\xdf\x95",
+               .ilen   = 16,
+               .result = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
+                         "\x65\x73\x74\x5f\x76\x65\x63\x74",
+               .rlen   = 16,
+       }, {
+               .key    = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
+                         "\x5d\x04\x16\x36\x15\x72\x63\x2f",
+               .klen   = 16,
+               .input  = "\xe0\x4d\x5d\x3c\xb7\x8c\x36\x47"
+                         "\x94\x18\x95\x91\xa9\xfc\x49\xf8"
+                         "\x44\xd1\x2d\xc2\x99\xb8\x08\x2a"
+                         "\x07\x89\x73\xc2\x45\x92\xc6\x90",
+               .ilen   = 32,
+               .result = "\x54\x65\x61\x20\x69\x73\x20\x67"
+                         "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
+                         "\x79\x6f\x75\x21\x21\x21\x20\x72"
+                         "\x65\x61\x6c\x6c\x79\x21\x21\x21",
+               .rlen   = 32,
+       }
+};
+
+/*
+ * XTEA test vectors
+ */
+#define XTEA_ENC_TEST_VECTORS  4
+#define XTEA_DEC_TEST_VECTORS  4
+
+static struct cipher_testvec xtea_enc_tv_template[] = {
+       {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = zeroed_string,
+               .ilen   = 8,
+               .result = "\xd8\xd4\xe9\xde\xd9\x1e\x13\xf7",
+               .rlen   = 8,
+       }, {
+               .key    = "\x2b\x02\x05\x68\x06\x14\x49\x76"
+                         "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
+               .klen   = 16,
+               .input  = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
+               .ilen   = 8,
+               .result = "\x94\xeb\xc8\x96\x84\x6a\x49\xa8",
+               .rlen   = 8,
+       }, {
+               .key    = "\x09\x65\x43\x11\x66\x44\x39\x25"
+                         "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
+               .klen   = 16,
+               .input  = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
+                         "\x65\x73\x74\x5f\x76\x65\x63\x74",
+               .ilen   = 16,
+               .result = "\x3e\xce\xae\x22\x60\x56\xa8\x9d"
+                         "\x77\x4d\xd4\xb4\x87\x24\xe3\x9a",
+               .rlen   = 16,
+       }, {
+               .key    = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
+                         "\x5d\x04\x16\x36\x15\x72\x63\x2f",
+               .klen   = 16,
+               .input  = "\x54\x65\x61\x20\x69\x73\x20\x67"
+                         "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
+                         "\x79\x6f\x75\x21\x21\x21\x20\x72"
+                         "\x65\x61\x6c\x6c\x79\x21\x21\x21",
+               .ilen   = 32,
+               .result = "\x99\x81\x9f\x5d\x6f\x4b\x31\x3a"
+                         "\x86\xff\x6f\xd0\xe3\x87\x70\x07"
+                         "\x4d\xb8\xcf\xf3\x99\x50\xb3\xd4"
+                         "\x73\xa2\xfa\xc9\x16\x59\x5d\x81",
+               .rlen   = 32,
+       }
+};
+
+static struct cipher_testvec xtea_dec_tv_template[] = {
+       {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = "\xd8\xd4\xe9\xde\xd9\x1e\x13\xf7",
+               .ilen   = 8,
+               .result = zeroed_string,
+               .rlen   = 8,
+       }, {
+               .key    = "\x2b\x02\x05\x68\x06\x14\x49\x76"
+                         "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
+               .klen   = 16,
+               .input  = "\x94\xeb\xc8\x96\x84\x6a\x49\xa8",
+               .ilen   = 8,
+               .result = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
+               .rlen   = 8,
+       }, {
+               .key    = "\x09\x65\x43\x11\x66\x44\x39\x25"
+                         "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
+               .klen   = 16,
+               .input  = "\x3e\xce\xae\x22\x60\x56\xa8\x9d"
+                         "\x77\x4d\xd4\xb4\x87\x24\xe3\x9a",
+               .ilen   = 16,
+               .result = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
+                         "\x65\x73\x74\x5f\x76\x65\x63\x74",
+               .rlen   = 16,
+       }, {
+               .key    = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
+                         "\x5d\x04\x16\x36\x15\x72\x63\x2f",
+               .klen   = 16,
+               .input  = "\x99\x81\x9f\x5d\x6f\x4b\x31\x3a"
+                         "\x86\xff\x6f\xd0\xe3\x87\x70\x07"
+                         "\x4d\xb8\xcf\xf3\x99\x50\xb3\xd4"
+                         "\x73\xa2\xfa\xc9\x16\x59\x5d\x81",
+               .ilen   = 32,
+               .result = "\x54\x65\x61\x20\x69\x73\x20\x67"
+                         "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
+                         "\x79\x6f\x75\x21\x21\x21\x20\x72"
+                         "\x65\x61\x6c\x6c\x79\x21\x21\x21",
+               .rlen   = 32,
+       }
+};
+
+/*
+ * KHAZAD test vectors.
+ */
+#define KHAZAD_ENC_TEST_VECTORS 5
+#define KHAZAD_DEC_TEST_VECTORS 5
+
+static struct cipher_testvec khazad_enc_tv_template[] = {
+       {
+               .key    = "\x80\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 16,
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 8,
+               .result = "\x49\xa4\xce\x32\xac\x19\x0e\x3f",
+               .rlen   = 8,
+       }, {
+               .key    = "\x38\x38\x38\x38\x38\x38\x38\x38"
+                         "\x38\x38\x38\x38\x38\x38\x38\x38",
+               .klen   = 16,
+               .input  = "\x38\x38\x38\x38\x38\x38\x38\x38",
+               .ilen   = 8,
+               .result = "\x7e\x82\x12\xa1\xd9\x5b\xe4\xf9",
+               .rlen   = 8,
+       }, {
+               .key    = "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2"
+                       "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2",
+               .klen   = 16,
+               .input  = "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2",
+               .ilen   = 8,
+               .result = "\xaa\xbe\xc1\x95\xc5\x94\x1a\x9c",
+               .rlen   = 8,
+       }, {
+               .key    = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
+                       "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+               .klen   = 16,
+               .input  = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+               .ilen   = 8,
+               .result = "\x04\x74\xf5\x70\x50\x16\xd3\xb8",
+               .rlen   = 8,
+       }, {
+               .key    = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
+                       "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+               .klen   = 16,
+               .input  = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
+                       "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+               .ilen   = 16,
+               .result = "\x04\x74\xf5\x70\x50\x16\xd3\xb8"
+                       "\x04\x74\xf5\x70\x50\x16\xd3\xb8",
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec khazad_dec_tv_template[] = {
+       {
+               .key    = "\x80\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 16,
+               .input  = "\x49\xa4\xce\x32\xac\x19\x0e\x3f",
+               .ilen   = 8,
+               .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .rlen   = 8,
+       }, {
+               .key    = "\x38\x38\x38\x38\x38\x38\x38\x38"
+                         "\x38\x38\x38\x38\x38\x38\x38\x38",
+               .klen   = 16,
+               .input  = "\x7e\x82\x12\xa1\xd9\x5b\xe4\xf9",
+               .ilen   = 8,
+               .result = "\x38\x38\x38\x38\x38\x38\x38\x38",
+               .rlen   = 8,
+       }, {
+               .key    = "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2"
+                       "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2",
+               .klen   = 16,
+               .input  = "\xaa\xbe\xc1\x95\xc5\x94\x1a\x9c",
+               .ilen   = 8,
+               .result = "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2",
+               .rlen   = 8,
+       }, {
+               .key    = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
+                       "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+               .klen   = 16,
+               .input  = "\x04\x74\xf5\x70\x50\x16\xd3\xb8",
+               .ilen   = 8,
+               .result = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+               .rlen   = 8,
+       }, {
+               .key    = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
+                       "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+               .klen   = 16,
+               .input  = "\x04\x74\xf5\x70\x50\x16\xd3\xb8"
+                       "\x04\x74\xf5\x70\x50\x16\xd3\xb8",
+               .ilen   = 16,
+               .result = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
+                       "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+               .rlen   = 16,
+       },
+};
+
+/*
+ * Anubis test vectors.
+ */
+
+#define ANUBIS_ENC_TEST_VECTORS                        5
+#define ANUBIS_DEC_TEST_VECTORS                        5
+#define ANUBIS_CBC_ENC_TEST_VECTORS            2
+#define ANUBIS_CBC_DEC_TEST_VECTORS            2
+
+static struct cipher_testvec anubis_enc_tv_template[] = {
+       {
+               .key    = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+               .klen   = 16,
+               .input  = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+               .ilen   = 16,
+               .result = "\x6d\xc5\xda\xa2\x26\x7d\x62\x6f"
+                         "\x08\xb7\x52\x8e\x6e\x6e\x86\x90",
+               .rlen   = 16,
+       }, {
+
+               .key    = "\x03\x03\x03\x03\x03\x03\x03\x03"
+                         "\x03\x03\x03\x03\x03\x03\x03\x03"
+                         "\x03\x03\x03\x03",
+               .klen   = 20,
+               .input  = "\x03\x03\x03\x03\x03\x03\x03\x03"
+                         "\x03\x03\x03\x03\x03\x03\x03\x03",
+               .ilen   = 16,
+               .result = "\xdb\xf1\x42\xf4\xd1\x8a\xc7\x49"
+                         "\x87\x41\x6f\x82\x0a\x98\x64\xae",
+               .rlen   = 16,
+       }, {
+               .key    = "\x24\x24\x24\x24\x24\x24\x24\x24"
+                         "\x24\x24\x24\x24\x24\x24\x24\x24"
+                         "\x24\x24\x24\x24\x24\x24\x24\x24"
+                         "\x24\x24\x24\x24",
+               .klen   = 28,
+               .input  = "\x24\x24\x24\x24\x24\x24\x24\x24"
+                         "\x24\x24\x24\x24\x24\x24\x24\x24",
+               .ilen   = 16,
+               .result = "\xfd\x1b\x4a\xe3\xbf\xf0\xad\x3d"
+                         "\x06\xd3\x61\x27\xfd\x13\x9e\xde",
+               .rlen   = 16,
+       }, {
+               .key    = "\x25\x25\x25\x25\x25\x25\x25\x25"
+                         "\x25\x25\x25\x25\x25\x25\x25\x25"
+                         "\x25\x25\x25\x25\x25\x25\x25\x25"
+                         "\x25\x25\x25\x25\x25\x25\x25\x25",
+               .klen   = 32,
+               .input  = "\x25\x25\x25\x25\x25\x25\x25\x25"
+                         "\x25\x25\x25\x25\x25\x25\x25\x25",
+               .ilen   = 16,
+               .result = "\x1a\x91\xfb\x2b\xb7\x78\x6b\xc4"
+                       "\x17\xd9\xff\x40\x3b\x0e\xe5\xfe",
+               .rlen   = 16,
+       }, {
+               .key    = "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35",
+               .klen   = 40,
+               .input  = "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35",
+               .ilen   = 16,
+               .result = "\xa5\x2c\x85\x6f\x9c\xba\xa0\x97"
+                         "\x9e\xc6\x84\x0f\x17\x21\x07\xee",
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec anubis_dec_tv_template[] = {
+       {
+               .key    = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+               .klen   = 16,
+               .input  = "\x6d\xc5\xda\xa2\x26\x7d\x62\x6f"
+                         "\x08\xb7\x52\x8e\x6e\x6e\x86\x90",
+               .ilen   = 16,
+               .result = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+               .rlen   = 16,
+       }, {
+
+               .key    = "\x03\x03\x03\x03\x03\x03\x03\x03"
+                         "\x03\x03\x03\x03\x03\x03\x03\x03"
+                         "\x03\x03\x03\x03",
+               .klen   = 20,
+               .input  = "\xdb\xf1\x42\xf4\xd1\x8a\xc7\x49"
+                         "\x87\x41\x6f\x82\x0a\x98\x64\xae",
+               .ilen   = 16,
+               .result = "\x03\x03\x03\x03\x03\x03\x03\x03"
+                         "\x03\x03\x03\x03\x03\x03\x03\x03",
+               .rlen   = 16,
+       }, {
+               .key    = "\x24\x24\x24\x24\x24\x24\x24\x24"
+                         "\x24\x24\x24\x24\x24\x24\x24\x24"
+                         "\x24\x24\x24\x24\x24\x24\x24\x24"
+                         "\x24\x24\x24\x24",
+               .klen   = 28,
+               .input  = "\xfd\x1b\x4a\xe3\xbf\xf0\xad\x3d"
+                         "\x06\xd3\x61\x27\xfd\x13\x9e\xde",
+               .ilen   = 16,
+               .result = "\x24\x24\x24\x24\x24\x24\x24\x24"
+                         "\x24\x24\x24\x24\x24\x24\x24\x24",
+               .rlen   = 16,
+       }, {
+               .key    = "\x25\x25\x25\x25\x25\x25\x25\x25"
+                         "\x25\x25\x25\x25\x25\x25\x25\x25"
+                         "\x25\x25\x25\x25\x25\x25\x25\x25"
+                         "\x25\x25\x25\x25\x25\x25\x25\x25",
+               .klen   = 32,
+               .input  = "\x1a\x91\xfb\x2b\xb7\x78\x6b\xc4"
+                       "\x17\xd9\xff\x40\x3b\x0e\xe5\xfe",
+               .ilen   = 16,
+               .result = "\x25\x25\x25\x25\x25\x25\x25\x25"
+                         "\x25\x25\x25\x25\x25\x25\x25\x25",
+               .rlen   = 16,
+       }, {
+               .key    = "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35",
+               .input = "\xa5\x2c\x85\x6f\x9c\xba\xa0\x97"
+                        "\x9e\xc6\x84\x0f\x17\x21\x07\xee",
+               .klen   = 40,
+               .ilen   = 16,
+               .result = "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35",
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec anubis_cbc_enc_tv_template[] = {
+       {
+               .key    = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+               .klen   = 16,
+               .input  = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+               .ilen   = 32,
+               .result = "\x6d\xc5\xda\xa2\x26\x7d\x62\x6f"
+                         "\x08\xb7\x52\x8e\x6e\x6e\x86\x90"
+                         "\x86\xd8\xb5\x6f\x98\x5e\x8a\x66"
+                         "\x4f\x1f\x78\xa1\xbb\x37\xf1\xbe",
+               .rlen   = 32,
+       }, {
+               .key    = "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35",
+               .klen   = 40,
+               .input  = "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35",
+               .ilen   = 32,
+               .result = "\xa5\x2c\x85\x6f\x9c\xba\xa0\x97"
+                         "\x9e\xc6\x84\x0f\x17\x21\x07\xee"
+                         "\xa2\xbc\x06\x98\xc6\x4b\xda\x75"
+                         "\x2e\xaa\xbe\x58\xce\x01\x5b\xc7",
+               .rlen   = 32,
+       },
+};
+
+static struct cipher_testvec anubis_cbc_dec_tv_template[] = {
+       {
+               .key    = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+               .klen   = 16,
+               .input  = "\x6d\xc5\xda\xa2\x26\x7d\x62\x6f"
+                         "\x08\xb7\x52\x8e\x6e\x6e\x86\x90"
+                         "\x86\xd8\xb5\x6f\x98\x5e\x8a\x66"
+                         "\x4f\x1f\x78\xa1\xbb\x37\xf1\xbe",
+               .ilen   = 32,
+               .result = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+               .rlen   = 32,
+       }, {
+               .key    = "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35",
+               .klen   = 40,
+               .input = "\xa5\x2c\x85\x6f\x9c\xba\xa0\x97"
+                         "\x9e\xc6\x84\x0f\x17\x21\x07\xee"
+                         "\xa2\xbc\x06\x98\xc6\x4b\xda\x75"
+                         "\x2e\xaa\xbe\x58\xce\x01\x5b\xc7",
+               .ilen   = 32,
+               .result = "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35",
+               .rlen   = 32,
+       },
+};
+
+/*
+ * XETA test vectors
+ */
+#define XETA_ENC_TEST_VECTORS  4
+#define XETA_DEC_TEST_VECTORS  4
+
+static struct cipher_testvec xeta_enc_tv_template[] = {
+       {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = zeroed_string,
+               .ilen   = 8,
+               .result = "\xaa\x22\x96\xe5\x6c\x61\xf3\x45",
+               .rlen   = 8,
+       }, {
+               .key    = "\x2b\x02\x05\x68\x06\x14\x49\x76"
+                         "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
+               .klen   = 16,
+               .input  = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
+               .ilen   = 8,
+               .result = "\x82\x3e\xeb\x35\xdc\xdd\xd9\xc3",
+               .rlen   = 8,
+       }, {
+               .key    = "\x09\x65\x43\x11\x66\x44\x39\x25"
+                         "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
+               .klen   = 16,
+               .input  = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
+                         "\x65\x73\x74\x5f\x76\x65\x63\x74",
+               .ilen   = 16,
+               .result = "\xe2\x04\xdb\xf2\x89\x85\x9e\xea"
+                         "\x61\x35\xaa\xed\xb5\xcb\x71\x2c",
+               .rlen   = 16,
+       }, {
+               .key    = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
+                         "\x5d\x04\x16\x36\x15\x72\x63\x2f",
+               .klen   = 16,
+               .input  = "\x54\x65\x61\x20\x69\x73\x20\x67"
+                         "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
+                         "\x79\x6f\x75\x21\x21\x21\x20\x72"
+                         "\x65\x61\x6c\x6c\x79\x21\x21\x21",
+               .ilen   = 32,
+               .result = "\x0b\x03\xcd\x8a\xbe\x95\xfd\xb1"
+                         "\xc1\x44\x91\x0b\xa5\xc9\x1b\xb4"
+                         "\xa9\xda\x1e\x9e\xb1\x3e\x2a\x8f"
+                         "\xea\xa5\x6a\x85\xd1\xf4\xa8\xa5",
+               .rlen   = 32,
+       }
+};
+
+static struct cipher_testvec xeta_dec_tv_template[] = {
+       {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = "\xaa\x22\x96\xe5\x6c\x61\xf3\x45",
+               .ilen   = 8,
+               .result = zeroed_string,
+               .rlen   = 8,
+       }, {
+               .key    = "\x2b\x02\x05\x68\x06\x14\x49\x76"
+                         "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
+               .klen   = 16,
+               .input  = "\x82\x3e\xeb\x35\xdc\xdd\xd9\xc3",
+               .ilen   = 8,
+               .result = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
+               .rlen   = 8,
+       }, {
+               .key    = "\x09\x65\x43\x11\x66\x44\x39\x25"
+                         "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
+               .klen   = 16,
+               .input  = "\xe2\x04\xdb\xf2\x89\x85\x9e\xea"
+                         "\x61\x35\xaa\xed\xb5\xcb\x71\x2c",
+               .ilen   = 16,
+               .result = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
+                         "\x65\x73\x74\x5f\x76\x65\x63\x74",
+               .rlen   = 16,
+       }, {
+               .key    = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
+                         "\x5d\x04\x16\x36\x15\x72\x63\x2f",
+               .klen   = 16,
+               .input  = "\x0b\x03\xcd\x8a\xbe\x95\xfd\xb1"
+                         "\xc1\x44\x91\x0b\xa5\xc9\x1b\xb4"
+                         "\xa9\xda\x1e\x9e\xb1\x3e\x2a\x8f"
+                         "\xea\xa5\x6a\x85\xd1\xf4\xa8\xa5",
+               .ilen   = 32,
+               .result = "\x54\x65\x61\x20\x69\x73\x20\x67"
+                         "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
+                         "\x79\x6f\x75\x21\x21\x21\x20\x72"
+                         "\x65\x61\x6c\x6c\x79\x21\x21\x21",
+               .rlen   = 32,
+       }
+};
+
+/*
+ * FCrypt test vectors
+ */
+#define FCRYPT_ENC_TEST_VECTORS        ARRAY_SIZE(fcrypt_pcbc_enc_tv_template)
+#define FCRYPT_DEC_TEST_VECTORS        ARRAY_SIZE(fcrypt_pcbc_dec_tv_template)
+
+static struct cipher_testvec fcrypt_pcbc_enc_tv_template[] = {
+       { /* http://www.openafs.org/pipermail/openafs-devel/2000-December/005320.html */
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 8,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 8,
+               .result = "\x0E\x09\x00\xC7\x3E\xF7\xED\x41",
+               .rlen   = 8,
+       }, {
+               .key    = "\x11\x44\x77\xAA\xDD\x00\x33\x66",
+               .klen   = 8,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0",
+               .ilen   = 8,
+               .result = "\xD8\xED\x78\x74\x77\xEC\x06\x80",
+               .rlen   = 8,
+       }, { /* From Arla */
+               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+               .klen   = 8,
+               .iv     = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .input  = "The quick brown fox jumps over the lazy dogs.\0\0",
+               .ilen   = 48,
+               .result = "\x00\xf0\x0e\x11\x75\xe6\x23\x82"
+                         "\xee\xac\x98\x62\x44\x51\xe4\x84"
+                         "\xc3\x59\xd8\xaa\x64\x60\xae\xf7"
+                         "\xd2\xd9\x13\x79\x72\xa3\x45\x03"
+                         "\x23\xb5\x62\xd7\x0c\xf5\x27\xd1"
+                         "\xf8\x91\x3c\xac\x44\x22\x92\xef",
+               .rlen   = 48,
+       }, {
+               .key    = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .klen   = 8,
+               .iv     = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+               .input  = "The quick brown fox jumps over the lazy dogs.\0\0",
+               .ilen   = 48,
+               .result = "\xca\x90\xf5\x9d\xcb\xd4\xd2\x3c"
+                         "\x01\x88\x7f\x3e\x31\x6e\x62\x9d"
+                         "\xd8\xe0\x57\xa3\x06\x3a\x42\x58"
+                         "\x2a\x28\xfe\x72\x52\x2f\xdd\xe0"
+                         "\x19\x89\x09\x1c\x2a\x8e\x8c\x94"
+                         "\xfc\xc7\x68\xe4\x88\xaa\xde\x0f",
+               .rlen   = 48,
+       }, { /* split-page version */
+               .key    = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .klen   = 8,
+               .iv     = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+               .input  = "The quick brown fox jumps over the lazy dogs.\0\0",
+               .ilen   = 48,
+               .result = "\xca\x90\xf5\x9d\xcb\xd4\xd2\x3c"
+                         "\x01\x88\x7f\x3e\x31\x6e\x62\x9d"
+                         "\xd8\xe0\x57\xa3\x06\x3a\x42\x58"
+                         "\x2a\x28\xfe\x72\x52\x2f\xdd\xe0"
+                         "\x19\x89\x09\x1c\x2a\x8e\x8c\x94"
+                         "\xfc\xc7\x68\xe4\x88\xaa\xde\x0f",
+               .rlen   = 48,
+               .np     = 2,
+               .tap    = { 20, 28 },
+       }
+};
+
+static struct cipher_testvec fcrypt_pcbc_dec_tv_template[] = {
+       { /* http://www.openafs.org/pipermail/openafs-devel/2000-December/005320.html */
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 8,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x0E\x09\x00\xC7\x3E\xF7\xED\x41",
+               .ilen   = 8,
+               .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .rlen   = 8,
+       }, {
+               .key    = "\x11\x44\x77\xAA\xDD\x00\x33\x66",
+               .klen   = 8,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\xD8\xED\x78\x74\x77\xEC\x06\x80",
+               .ilen   = 8,
+               .result = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0",
+               .rlen   = 8,
+       }, { /* From Arla */
+               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+               .klen   = 8,
+               .iv     = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .input  = "\x00\xf0\x0e\x11\x75\xe6\x23\x82"
+                         "\xee\xac\x98\x62\x44\x51\xe4\x84"
+                         "\xc3\x59\xd8\xaa\x64\x60\xae\xf7"
+                         "\xd2\xd9\x13\x79\x72\xa3\x45\x03"
+                         "\x23\xb5\x62\xd7\x0c\xf5\x27\xd1"
+                         "\xf8\x91\x3c\xac\x44\x22\x92\xef",
+               .ilen   = 48,
+               .result = "The quick brown fox jumps over the lazy dogs.\0\0",
+               .rlen   = 48,
+       }, {
+               .key    = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .klen   = 8,
+               .iv     = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+               .input  = "\xca\x90\xf5\x9d\xcb\xd4\xd2\x3c"
+                         "\x01\x88\x7f\x3e\x31\x6e\x62\x9d"
+                         "\xd8\xe0\x57\xa3\x06\x3a\x42\x58"
+                         "\x2a\x28\xfe\x72\x52\x2f\xdd\xe0"
+                         "\x19\x89\x09\x1c\x2a\x8e\x8c\x94"
+                         "\xfc\xc7\x68\xe4\x88\xaa\xde\x0f",
+               .ilen   = 48,
+               .result = "The quick brown fox jumps over the lazy dogs.\0\0",
+               .rlen   = 48,
+       }, { /* split-page version */
+               .key    = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .klen   = 8,
+               .iv     = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+               .input  = "\xca\x90\xf5\x9d\xcb\xd4\xd2\x3c"
+                         "\x01\x88\x7f\x3e\x31\x6e\x62\x9d"
+                         "\xd8\xe0\x57\xa3\x06\x3a\x42\x58"
+                         "\x2a\x28\xfe\x72\x52\x2f\xdd\xe0"
+                         "\x19\x89\x09\x1c\x2a\x8e\x8c\x94"
+                         "\xfc\xc7\x68\xe4\x88\xaa\xde\x0f",
+               .ilen   = 48,
+               .result = "The quick brown fox jumps over the lazy dogs.\0\0",
+               .rlen   = 48,
+               .np     = 2,
+               .tap    = { 20, 28 },
+       }
+};
+
+/*
+ * CAMELLIA test vectors.
+ */
+#define CAMELLIA_ENC_TEST_VECTORS 3
+#define CAMELLIA_DEC_TEST_VECTORS 3
+#define CAMELLIA_CBC_ENC_TEST_VECTORS 2
+#define CAMELLIA_CBC_DEC_TEST_VECTORS 2
+
+static struct cipher_testvec camellia_enc_tv_template[] = {
+       {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .klen   = 16,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .ilen   = 16,
+               .result = "\x67\x67\x31\x38\x54\x96\x69\x73"
+                         "\x08\x57\x06\x56\x48\xea\xbe\x43",
+               .rlen   = 16,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+                         "\x00\x11\x22\x33\x44\x55\x66\x77",
+               .klen   = 24,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .ilen   = 16,
+               .result = "\xb4\x99\x34\x01\xb3\xe9\x96\xf8"
+                         "\x4e\xe5\xce\xe7\xd7\x9b\x09\xb9",
+               .rlen   = 16,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+                         "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               .klen   = 32,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .ilen   = 16,
+               .result = "\x9a\xcc\x23\x7d\xff\x16\xd7\x6c"
+                         "\x20\xef\x7c\x91\x9e\x3a\x75\x09",
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec camellia_dec_tv_template[] = {
+       {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .klen   = 16,
+               .input  = "\x67\x67\x31\x38\x54\x96\x69\x73"
+                         "\x08\x57\x06\x56\x48\xea\xbe\x43",
+               .ilen   = 16,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .rlen   = 16,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+                         "\x00\x11\x22\x33\x44\x55\x66\x77",
+               .klen   = 24,
+               .input  = "\xb4\x99\x34\x01\xb3\xe9\x96\xf8"
+                         "\x4e\xe5\xce\xe7\xd7\x9b\x09\xb9",
+               .ilen   = 16,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .rlen   = 16,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+                         "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               .klen   = 32,
+               .input  = "\x9a\xcc\x23\x7d\xff\x16\xd7\x6c"
+                         "\x20\xef\x7c\x91\x9e\x3a\x75\x09",
+               .ilen   = 16,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec camellia_cbc_enc_tv_template[] = {
+       {
+               .key    = "\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
+                         "\x51\x2e\x03\xd5\x34\x12\x00\x06",
+               .klen   = 16,
+               .iv     = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
+                         "\xb4\x22\xda\x80\x2c\x9f\xac\x41",
+               .input  = "Single block msg",
+               .ilen   = 16,
+               .result = "\xea\x32\x12\x76\x3b\x50\x10\xe7"
+                         "\x18\xf6\xfd\x5d\xf6\x8f\x13\x51",
+               .rlen   = 16,
+       }, {
+               .key    = "\xc2\x86\x69\x6d\x88\x7c\x9a\xa0"
+                         "\x61\x1b\xbb\x3e\x20\x25\xa4\x5a",
+               .klen   = 16,
+               .iv     = "\x56\x2e\x17\x99\x6d\x09\x3d\x28"
+                         "\xdd\xb3\xba\x69\x5a\x2e\x6f\x58",
+               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .ilen   = 32,
+               .result = "\xa5\xdf\x6e\x50\xda\x70\x6c\x01"
+                         "\x4a\xab\xf3\xf2\xd6\xfc\x6c\xfd"
+                         "\x19\xb4\x3e\x57\x1c\x02\x5e\xa0"
+                         "\x15\x78\xe0\x5e\xf2\xcb\x87\x16",
+               .rlen   = 32,
+       },
+};
+
+static struct cipher_testvec camellia_cbc_dec_tv_template[] = {
+       {
+               .key    = "\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
+                         "\x51\x2e\x03\xd5\x34\x12\x00\x06",
+               .klen   = 16,
+               .iv     = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
+                         "\xb4\x22\xda\x80\x2c\x9f\xac\x41",
+               .input  = "\xea\x32\x12\x76\x3b\x50\x10\xe7"
+                         "\x18\xf6\xfd\x5d\xf6\x8f\x13\x51",
+               .ilen   = 16,
+               .result = "Single block msg",
+               .rlen   = 16,
+       }, {
+               .key    = "\xc2\x86\x69\x6d\x88\x7c\x9a\xa0"
+                         "\x61\x1b\xbb\x3e\x20\x25\xa4\x5a",
+               .klen   = 16,
+               .iv     = "\x56\x2e\x17\x99\x6d\x09\x3d\x28"
+                         "\xdd\xb3\xba\x69\x5a\x2e\x6f\x58",
+               .input = "\xa5\xdf\x6e\x50\xda\x70\x6c\x01"
+                         "\x4a\xab\xf3\xf2\xd6\xfc\x6c\xfd"
+                         "\x19\xb4\x3e\x57\x1c\x02\x5e\xa0"
+                         "\x15\x78\xe0\x5e\xf2\xcb\x87\x16",
+               .ilen   = 32,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .rlen   = 32,
+       },
+};
+
+/*
+ * SEED test vectors
+ */
+#define SEED_ENC_TEST_VECTORS  4
+#define SEED_DEC_TEST_VECTORS  4
+
+static struct cipher_testvec seed_enc_tv_template[] = {
+       {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .ilen   = 16,
+               .result = "\x5e\xba\xc6\xe0\x05\x4e\x16\x68"
+                         "\x19\xaf\xf1\xcc\x6d\x34\x6c\xdb",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .klen   = 16,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\xc1\x1f\x22\xf2\x01\x40\x50\x50"
+                         "\x84\x48\x35\x97\xe4\x37\x0f\x43",
+               .rlen   = 16,
+       }, {
+               .key    = "\x47\x06\x48\x08\x51\xe6\x1b\xe8"
+                         "\x5d\x74\xbf\xb3\xfd\x95\x61\x85",
+               .klen   = 16,
+               .input  = "\x83\xa2\xf8\xa2\x88\x64\x1f\xb9"
+                         "\xa4\xe9\xa5\xcc\x2f\x13\x1c\x7d",
+               .ilen   = 16,
+               .result = "\xee\x54\xd1\x3e\xbc\xae\x70\x6d"
+                         "\x22\x6b\xc3\x14\x2c\xd4\x0d\x4a",
+               .rlen   = 16,
+       }, {
+               .key    = "\x28\xdb\xc3\xbc\x49\xff\xd8\x7d"
+                         "\xcf\xa5\x09\xb1\x1d\x42\x2b\xe7",
+               .klen   = 16,
+               .input  = "\xb4\x1e\x6b\xe2\xeb\xa8\x4a\x14"
+                         "\x8e\x2e\xed\x84\x59\x3c\x5e\xc7",
+               .ilen   = 16,
+               .result = "\x9b\x9b\x7b\xfc\xd1\x81\x3c\xb9"
+                         "\x5d\x0b\x36\x18\xf4\x0f\x51\x22",
+               .rlen   = 16,
+       }
+};
+
+static struct cipher_testvec seed_dec_tv_template[] = {
+       {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = "\x5e\xba\xc6\xe0\x05\x4e\x16\x68"
+                         "\x19\xaf\xf1\xcc\x6d\x34\x6c\xdb",
+               .ilen   = 16,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .klen   = 16,
+               .input  = "\xc1\x1f\x22\xf2\x01\x40\x50\x50"
+                         "\x84\x48\x35\x97\xe4\x37\x0f\x43",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       }, {
+               .key    = "\x47\x06\x48\x08\x51\xe6\x1b\xe8"
+                         "\x5d\x74\xbf\xb3\xfd\x95\x61\x85",
+               .klen   = 16,
+               .input  = "\xee\x54\xd1\x3e\xbc\xae\x70\x6d"
+                         "\x22\x6b\xc3\x14\x2c\xd4\x0d\x4a",
+               .ilen   = 16,
+               .result = "\x83\xa2\xf8\xa2\x88\x64\x1f\xb9"
+                         "\xa4\xe9\xa5\xcc\x2f\x13\x1c\x7d",
+               .rlen   = 16,
+       }, {
+               .key    = "\x28\xdb\xc3\xbc\x49\xff\xd8\x7d"
+                         "\xcf\xa5\x09\xb1\x1d\x42\x2b\xe7",
+               .klen   = 16,
+               .input  = "\x9b\x9b\x7b\xfc\xd1\x81\x3c\xb9"
+                         "\x5d\x0b\x36\x18\xf4\x0f\x51\x22",
+               .ilen   = 16,
+               .result = "\xb4\x1e\x6b\xe2\xeb\xa8\x4a\x14"
+                         "\x8e\x2e\xed\x84\x59\x3c\x5e\xc7",
+               .rlen   = 16,
+       }
+};
+
+#define SALSA20_STREAM_ENC_TEST_VECTORS 5
+static struct cipher_testvec salsa20_stream_enc_tv_template[] = {
+       /*
+       * Testvectors from verified.test-vectors submitted to ECRYPT.
+       * They are truncated to size 39, 64, 111, 129 to test a variety
+       * of input length.
+       */
+       { /* Set 3, vector 0 */
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                       "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
+               .klen   = 16,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 39,
+               .result = "\x2D\xD5\xC3\xF7\xBA\x2B\x20\xF7"
+                        "\x68\x02\x41\x0C\x68\x86\x88\x89"
+                        "\x5A\xD8\xC1\xBD\x4E\xA6\xC9\xB1"
+                        "\x40\xFB\x9B\x90\xE2\x10\x49\xBF"
+                        "\x58\x3F\x52\x79\x70\xEB\xC1",
+               .rlen   = 39,
+       }, { /* Set 5, vector 0 */
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 16,
+               .iv     = "\x80\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 64,
+               .result = "\xB6\x6C\x1E\x44\x46\xDD\x95\x57"
+                        "\xE5\x78\xE2\x23\xB0\xB7\x68\x01"
+                        "\x7B\x23\xB2\x67\xBB\x02\x34\xAE"
+                        "\x46\x26\xBF\x44\x3F\x21\x97\x76"
+                        "\x43\x6F\xB1\x9F\xD0\xE8\x86\x6F"
+                        "\xCD\x0D\xE9\xA9\x53\x8F\x4A\x09"
+                        "\xCA\x9A\xC0\x73\x2E\x30\xBC\xF9"
+                        "\x8E\x4F\x13\xE4\xB9\xE2\x01\xD9",
+               .rlen   = 64,
+       }, { /* Set 3, vector 27 */
+               .key    = "\x1B\x1C\x1D\x1E\x1F\x20\x21\x22"
+                       "\x23\x24\x25\x26\x27\x28\x29\x2A"
+                       "\x2B\x2C\x2D\x2E\x2F\x30\x31\x32"
+                       "\x33\x34\x35\x36\x37\x38\x39\x3A",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 111,
+               .result = "\xAE\x39\x50\x8E\xAC\x9A\xEC\xE7"
+                        "\xBF\x97\xBB\x20\xB9\xDE\xE4\x1F"
+                        "\x87\xD9\x47\xF8\x28\x91\x35\x98"
+                        "\xDB\x72\xCC\x23\x29\x48\x56\x5E"
+                        "\x83\x7E\x0B\xF3\x7D\x5D\x38\x7B"
+                        "\x2D\x71\x02\xB4\x3B\xB5\xD8\x23"
+                        "\xB0\x4A\xDF\x3C\xEC\xB6\xD9\x3B"
+                        "\x9B\xA7\x52\xBE\xC5\xD4\x50\x59"
+                        "\x15\x14\xB4\x0E\x40\xE6\x53\xD1"
+                        "\x83\x9C\x5B\xA0\x92\x29\x6B\x5E"
+                        "\x96\x5B\x1E\x2F\xD3\xAC\xC1\x92"
+                        "\xB1\x41\x3F\x19\x2F\xC4\x3B\xC6"
+                        "\x95\x46\x45\x54\xE9\x75\x03\x08"
+                        "\x44\xAF\xE5\x8A\x81\x12\x09",
+               .rlen   = 111,
+       }, { /* Set 5, vector 27 */
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x10\x00\x00\x00\x00",
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00",
+               .ilen   = 129,
+               .result = "\xD2\xDB\x1A\x5C\xF1\xC1\xAC\xDB"
+                        "\xE8\x1A\x7A\x43\x40\xEF\x53\x43"
+                        "\x5E\x7F\x4B\x1A\x50\x52\x3F\x8D"
+                        "\x28\x3D\xCF\x85\x1D\x69\x6E\x60"
+                        "\xF2\xDE\x74\x56\x18\x1B\x84\x10"
+                        "\xD4\x62\xBA\x60\x50\xF0\x61\xF2"
+                        "\x1C\x78\x7F\xC1\x24\x34\xAF\x58"
+                        "\xBF\x2C\x59\xCA\x90\x77\xF3\xB0"
+                        "\x5B\x4A\xDF\x89\xCE\x2C\x2F\xFC"
+                        "\x67\xF0\xE3\x45\xE8\xB3\xB3\x75"
+                        "\xA0\x95\x71\xA1\x29\x39\x94\xCA"
+                        "\x45\x2F\xBD\xCB\x10\xB6\xBE\x9F"
+                        "\x8E\xF9\xB2\x01\x0A\x5A\x0A\xB7"
+                        "\x6B\x9D\x70\x8E\x4B\xD6\x2F\xCD"
+                        "\x2E\x40\x48\x75\xE9\xE2\x21\x45"
+                        "\x0B\xC9\xB6\xB5\x66\xBC\x9A\x59"
+                        "\x5A",
+               .rlen   = 129,
+       }, { /* large test vector generated using Crypto++ */
+               .key =  "\x00\x01\x02\x03\x04\x05\x06\x07"
+                       "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                       "\x10\x11\x12\x13\x14\x15\x16\x17"
+                       "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .klen = 32,
+               .iv =   "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input =
+                       "\x00\x01\x02\x03\x04\x05\x06\x07"
+                       "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                       "\x10\x11\x12\x13\x14\x15\x16\x17"
+                       "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+                       "\x20\x21\x22\x23\x24\x25\x26\x27"
+                       "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+                       "\x30\x31\x32\x33\x34\x35\x36\x37"
+                       "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+                       "\x40\x41\x42\x43\x44\x45\x46\x47"
+                       "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+                       "\x50\x51\x52\x53\x54\x55\x56\x57"
+                       "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+                       "\x60\x61\x62\x63\x64\x65\x66\x67"
+                       "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+                       "\x70\x71\x72\x73\x74\x75\x76\x77"
+                       "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+                       "\x80\x81\x82\x83\x84\x85\x86\x87"
+                       "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+                       "\x90\x91\x92\x93\x94\x95\x96\x97"
+                       "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+                       "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+                       "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+                       "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+                       "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+                       "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                       "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+                       "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+                       "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+                       "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+                       "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+                       "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+                       "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+                       "\x00\x03\x06\x09\x0c\x0f\x12\x15"
+                       "\x18\x1b\x1e\x21\x24\x27\x2a\x2d"
+                       "\x30\x33\x36\x39\x3c\x3f\x42\x45"
+                       "\x48\x4b\x4e\x51\x54\x57\x5a\x5d"
+                       "\x60\x63\x66\x69\x6c\x6f\x72\x75"
+                       "\x78\x7b\x7e\x81\x84\x87\x8a\x8d"
+                       "\x90\x93\x96\x99\x9c\x9f\xa2\xa5"
+                       "\xa8\xab\xae\xb1\xb4\xb7\xba\xbd"
+                       "\xc0\xc3\xc6\xc9\xcc\xcf\xd2\xd5"
+                       "\xd8\xdb\xde\xe1\xe4\xe7\xea\xed"
+                       "\xf0\xf3\xf6\xf9\xfc\xff\x02\x05"
+                       "\x08\x0b\x0e\x11\x14\x17\x1a\x1d"
+                       "\x20\x23\x26\x29\x2c\x2f\x32\x35"
+                       "\x38\x3b\x3e\x41\x44\x47\x4a\x4d"
+                       "\x50\x53\x56\x59\x5c\x5f\x62\x65"
+                       "\x68\x6b\x6e\x71\x74\x77\x7a\x7d"
+                       "\x80\x83\x86\x89\x8c\x8f\x92\x95"
+                       "\x98\x9b\x9e\xa1\xa4\xa7\xaa\xad"
+                       "\xb0\xb3\xb6\xb9\xbc\xbf\xc2\xc5"
+                       "\xc8\xcb\xce\xd1\xd4\xd7\xda\xdd"
+                       "\xe0\xe3\xe6\xe9\xec\xef\xf2\xf5"
+                       "\xf8\xfb\xfe\x01\x04\x07\x0a\x0d"
+                       "\x10\x13\x16\x19\x1c\x1f\x22\x25"
+                       "\x28\x2b\x2e\x31\x34\x37\x3a\x3d"
+                       "\x40\x43\x46\x49\x4c\x4f\x52\x55"
+                       "\x58\x5b\x5e\x61\x64\x67\x6a\x6d"
+                       "\x70\x73\x76\x79\x7c\x7f\x82\x85"
+                       "\x88\x8b\x8e\x91\x94\x97\x9a\x9d"
+                       "\xa0\xa3\xa6\xa9\xac\xaf\xb2\xb5"
+                       "\xb8\xbb\xbe\xc1\xc4\xc7\xca\xcd"
+                       "\xd0\xd3\xd6\xd9\xdc\xdf\xe2\xe5"
+                       "\xe8\xeb\xee\xf1\xf4\xf7\xfa\xfd"
+                       "\x00\x05\x0a\x0f\x14\x19\x1e\x23"
+                       "\x28\x2d\x32\x37\x3c\x41\x46\x4b"
+                       "\x50\x55\x5a\x5f\x64\x69\x6e\x73"
+                       "\x78\x7d\x82\x87\x8c\x91\x96\x9b"
+                       "\xa0\xa5\xaa\xaf\xb4\xb9\xbe\xc3"
+                       "\xc8\xcd\xd2\xd7\xdc\xe1\xe6\xeb"
+                       "\xf0\xf5\xfa\xff\x04\x09\x0e\x13"
+                       "\x18\x1d\x22\x27\x2c\x31\x36\x3b"
+                       "\x40\x45\x4a\x4f\x54\x59\x5e\x63"
+                       "\x68\x6d\x72\x77\x7c\x81\x86\x8b"
+                       "\x90\x95\x9a\x9f\xa4\xa9\xae\xb3"
+                       "\xb8\xbd\xc2\xc7\xcc\xd1\xd6\xdb"
+                       "\xe0\xe5\xea\xef\xf4\xf9\xfe\x03"
+                       "\x08\x0d\x12\x17\x1c\x21\x26\x2b"
+                       "\x30\x35\x3a\x3f\x44\x49\x4e\x53"
+                       "\x58\x5d\x62\x67\x6c\x71\x76\x7b"
+                       "\x80\x85\x8a\x8f\x94\x99\x9e\xa3"
+                       "\xa8\xad\xb2\xb7\xbc\xc1\xc6\xcb"
+                       "\xd0\xd5\xda\xdf\xe4\xe9\xee\xf3"
+                       "\xf8\xfd\x02\x07\x0c\x11\x16\x1b"
+                       "\x20\x25\x2a\x2f\x34\x39\x3e\x43"
+                       "\x48\x4d\x52\x57\x5c\x61\x66\x6b"
+                       "\x70\x75\x7a\x7f\x84\x89\x8e\x93"
+                       "\x98\x9d\xa2\xa7\xac\xb1\xb6\xbb"
+                       "\xc0\xc5\xca\xcf\xd4\xd9\xde\xe3"
+                       "\xe8\xed\xf2\xf7\xfc\x01\x06\x0b"
+                       "\x10\x15\x1a\x1f\x24\x29\x2e\x33"
+                       "\x38\x3d\x42\x47\x4c\x51\x56\x5b"
+                       "\x60\x65\x6a\x6f\x74\x79\x7e\x83"
+                       "\x88\x8d\x92\x97\x9c\xa1\xa6\xab"
+                       "\xb0\xb5\xba\xbf\xc4\xc9\xce\xd3"
+                       "\xd8\xdd\xe2\xe7\xec\xf1\xf6\xfb"
+                       "\x00\x07\x0e\x15\x1c\x23\x2a\x31"
+                       "\x38\x3f\x46\x4d\x54\x5b\x62\x69"
+                       "\x70\x77\x7e\x85\x8c\x93\x9a\xa1"
+                       "\xa8\xaf\xb6\xbd\xc4\xcb\xd2\xd9"
+                       "\xe0\xe7\xee\xf5\xfc\x03\x0a\x11"
+                       "\x18\x1f\x26\x2d\x34\x3b\x42\x49"
+                       "\x50\x57\x5e\x65\x6c\x73\x7a\x81"
+                       "\x88\x8f\x96\x9d\xa4\xab\xb2\xb9"
+                       "\xc0\xc7\xce\xd5\xdc\xe3\xea\xf1"
+                       "\xf8\xff\x06\x0d\x14\x1b\x22\x29"
+                       "\x30\x37\x3e\x45\x4c\x53\x5a\x61"
+                       "\x68\x6f\x76\x7d\x84\x8b\x92\x99"
+                       "\xa0\xa7\xae\xb5\xbc\xc3\xca\xd1"
+                       "\xd8\xdf\xe6\xed\xf4\xfb\x02\x09"
+                       "\x10\x17\x1e\x25\x2c\x33\x3a\x41"
+                       "\x48\x4f\x56\x5d\x64\x6b\x72\x79"
+                       "\x80\x87\x8e\x95\x9c\xa3\xaa\xb1"
+                       "\xb8\xbf\xc6\xcd\xd4\xdb\xe2\xe9"
+                       "\xf0\xf7\xfe\x05\x0c\x13\x1a\x21"
+                       "\x28\x2f\x36\x3d\x44\x4b\x52\x59"
+                       "\x60\x67\x6e\x75\x7c\x83\x8a\x91"
+                       "\x98\x9f\xa6\xad\xb4\xbb\xc2\xc9"
+                       "\xd0\xd7\xde\xe5\xec\xf3\xfa\x01"
+                       "\x08\x0f\x16\x1d\x24\x2b\x32\x39"
+                       "\x40\x47\x4e\x55\x5c\x63\x6a\x71"
+                       "\x78\x7f\x86\x8d\x94\x9b\xa2\xa9"
+                       "\xb0\xb7\xbe\xc5\xcc\xd3\xda\xe1"
+                       "\xe8\xef\xf6\xfd\x04\x0b\x12\x19"
+                       "\x20\x27\x2e\x35\x3c\x43\x4a\x51"
+                       "\x58\x5f\x66\x6d\x74\x7b\x82\x89"
+                       "\x90\x97\x9e\xa5\xac\xb3\xba\xc1"
+                       "\xc8\xcf\xd6\xdd\xe4\xeb\xf2\xf9"
+                       "\x00\x09\x12\x1b\x24\x2d\x36\x3f"
+                       "\x48\x51\x5a\x63\x6c\x75\x7e\x87"
+                       "\x90\x99\xa2\xab\xb4\xbd\xc6\xcf"
+                       "\xd8\xe1\xea\xf3\xfc\x05\x0e\x17"
+                       "\x20\x29\x32\x3b\x44\x4d\x56\x5f"
+                       "\x68\x71\x7a\x83\x8c\x95\x9e\xa7"
+                       "\xb0\xb9\xc2\xcb\xd4\xdd\xe6\xef"
+                       "\xf8\x01\x0a\x13\x1c\x25\x2e\x37"
+                       "\x40\x49\x52\x5b\x64\x6d\x76\x7f"
+                       "\x88\x91\x9a\xa3\xac\xb5\xbe\xc7"
+                       "\xd0\xd9\xe2\xeb\xf4\xfd\x06\x0f"
+                       "\x18\x21\x2a\x33\x3c\x45\x4e\x57"
+                       "\x60\x69\x72\x7b\x84\x8d\x96\x9f"
+                       "\xa8\xb1\xba\xc3\xcc\xd5\xde\xe7"
+                       "\xf0\xf9\x02\x0b\x14\x1d\x26\x2f"
+                       "\x38\x41\x4a\x53\x5c\x65\x6e\x77"
+                       "\x80\x89\x92\x9b\xa4\xad\xb6\xbf"
+                       "\xc8\xd1\xda\xe3\xec\xf5\xfe\x07"
+                       "\x10\x19\x22\x2b\x34\x3d\x46\x4f"
+                       "\x58\x61\x6a\x73\x7c\x85\x8e\x97"
+                       "\xa0\xa9\xb2\xbb\xc4\xcd\xd6\xdf"
+                       "\xe8\xf1\xfa\x03\x0c\x15\x1e\x27"
+                       "\x30\x39\x42\x4b\x54\x5d\x66\x6f"
+                       "\x78\x81\x8a\x93\x9c\xa5\xae\xb7"
+                       "\xc0\xc9\xd2\xdb\xe4\xed\xf6\xff"
+                       "\x08\x11\x1a\x23\x2c\x35\x3e\x47"
+                       "\x50\x59\x62\x6b\x74\x7d\x86\x8f"
+                       "\x98\xa1\xaa\xb3\xbc\xc5\xce\xd7"
+                       "\xe0\xe9\xf2\xfb\x04\x0d\x16\x1f"
+                       "\x28\x31\x3a\x43\x4c\x55\x5e\x67"
+                       "\x70\x79\x82\x8b\x94\x9d\xa6\xaf"
+                       "\xb8\xc1\xca\xd3\xdc\xe5\xee\xf7"
+                       "\x00\x0b\x16\x21\x2c\x37\x42\x4d"
+                       "\x58\x63\x6e\x79\x84\x8f\x9a\xa5"
+                       "\xb0\xbb\xc6\xd1\xdc\xe7\xf2\xfd"
+                       "\x08\x13\x1e\x29\x34\x3f\x4a\x55"
+                       "\x60\x6b\x76\x81\x8c\x97\xa2\xad"
+                       "\xb8\xc3\xce\xd9\xe4\xef\xfa\x05"
+                       "\x10\x1b\x26\x31\x3c\x47\x52\x5d"
+                       "\x68\x73\x7e\x89\x94\x9f\xaa\xb5"
+                       "\xc0\xcb\xd6\xe1\xec\xf7\x02\x0d"
+                       "\x18\x23\x2e\x39\x44\x4f\x5a\x65"
+                       "\x70\x7b\x86\x91\x9c\xa7\xb2\xbd"
+                       "\xc8\xd3\xde\xe9\xf4\xff\x0a\x15"
+                       "\x20\x2b\x36\x41\x4c\x57\x62\x6d"
+                       "\x78\x83\x8e\x99\xa4\xaf\xba\xc5"
+                       "\xd0\xdb\xe6\xf1\xfc\x07\x12\x1d"
+                       "\x28\x33\x3e\x49\x54\x5f\x6a\x75"
+                       "\x80\x8b\x96\xa1\xac\xb7\xc2\xcd"
+                       "\xd8\xe3\xee\xf9\x04\x0f\x1a\x25"
+                       "\x30\x3b\x46\x51\x5c\x67\x72\x7d"
+                       "\x88\x93\x9e\xa9\xb4\xbf\xca\xd5"
+                       "\xe0\xeb\xf6\x01\x0c\x17\x22\x2d"
+                       "\x38\x43\x4e\x59\x64\x6f\x7a\x85"
+                       "\x90\x9b\xa6\xb1\xbc\xc7\xd2\xdd"
+                       "\xe8\xf3\xfe\x09\x14\x1f\x2a\x35"
+                       "\x40\x4b\x56\x61\x6c\x77\x82\x8d"
+                       "\x98\xa3\xae\xb9\xc4\xcf\xda\xe5"
+                       "\xf0\xfb\x06\x11\x1c\x27\x32\x3d"
+                       "\x48\x53\x5e\x69\x74\x7f\x8a\x95"
+                       "\xa0\xab\xb6\xc1\xcc\xd7\xe2\xed"
+                       "\xf8\x03\x0e\x19\x24\x2f\x3a\x45"
+                       "\x50\x5b\x66\x71\x7c\x87\x92\x9d"
+                       "\xa8\xb3\xbe\xc9\xd4\xdf\xea\xf5"
+                       "\x00\x0d\x1a\x27\x34\x41\x4e\x5b"
+                       "\x68\x75\x82\x8f\x9c\xa9\xb6\xc3"
+                       "\xd0\xdd\xea\xf7\x04\x11\x1e\x2b"
+                       "\x38\x45\x52\x5f\x6c\x79\x86\x93"
+                       "\xa0\xad\xba\xc7\xd4\xe1\xee\xfb"
+                       "\x08\x15\x22\x2f\x3c\x49\x56\x63"
+                       "\x70\x7d\x8a\x97\xa4\xb1\xbe\xcb"
+                       "\xd8\xe5\xf2\xff\x0c\x19\x26\x33"
+                       "\x40\x4d\x5a\x67\x74\x81\x8e\x9b"
+                       "\xa8\xb5\xc2\xcf\xdc\xe9\xf6\x03"
+                       "\x10\x1d\x2a\x37\x44\x51\x5e\x6b"
+                       "\x78\x85\x92\x9f\xac\xb9\xc6\xd3"
+                       "\xe0\xed\xfa\x07\x14\x21\x2e\x3b"
+                       "\x48\x55\x62\x6f\x7c\x89\x96\xa3"
+                       "\xb0\xbd\xca\xd7\xe4\xf1\xfe\x0b"
+                       "\x18\x25\x32\x3f\x4c\x59\x66\x73"
+                       "\x80\x8d\x9a\xa7\xb4\xc1\xce\xdb"
+                       "\xe8\xf5\x02\x0f\x1c\x29\x36\x43"
+                       "\x50\x5d\x6a\x77\x84\x91\x9e\xab"
+                       "\xb8\xc5\xd2\xdf\xec\xf9\x06\x13"
+                       "\x20\x2d\x3a\x47\x54\x61\x6e\x7b"
+                       "\x88\x95\xa2\xaf\xbc\xc9\xd6\xe3"
+                       "\xf0\xfd\x0a\x17\x24\x31\x3e\x4b"
+                       "\x58\x65\x72\x7f\x8c\x99\xa6\xb3"
+                       "\xc0\xcd\xda\xe7\xf4\x01\x0e\x1b"
+                       "\x28\x35\x42\x4f\x5c\x69\x76\x83"
+                       "\x90\x9d\xaa\xb7\xc4\xd1\xde\xeb"
+                       "\xf8\x05\x12\x1f\x2c\x39\x46\x53"
+                       "\x60\x6d\x7a\x87\x94\xa1\xae\xbb"
+                       "\xc8\xd5\xe2\xef\xfc\x09\x16\x23"
+                       "\x30\x3d\x4a\x57\x64\x71\x7e\x8b"
+                       "\x98\xa5\xb2\xbf\xcc\xd9\xe6\xf3"
+                       "\x00\x0f\x1e\x2d\x3c\x4b\x5a\x69"
+                       "\x78\x87\x96\xa5\xb4\xc3\xd2\xe1"
+                       "\xf0\xff\x0e\x1d\x2c\x3b\x4a\x59"
+                       "\x68\x77\x86\x95\xa4\xb3\xc2\xd1"
+                       "\xe0\xef\xfe\x0d\x1c\x2b\x3a\x49"
+                       "\x58\x67\x76\x85\x94\xa3\xb2\xc1"
+                       "\xd0\xdf\xee\xfd\x0c\x1b\x2a\x39"
+                       "\x48\x57\x66\x75\x84\x93\xa2\xb1"
+                       "\xc0\xcf\xde\xed\xfc\x0b\x1a\x29"
+                       "\x38\x47\x56\x65\x74\x83\x92\xa1"
+                       "\xb0\xbf\xce\xdd\xec\xfb\x0a\x19"
+                       "\x28\x37\x46\x55\x64\x73\x82\x91"
+                       "\xa0\xaf\xbe\xcd\xdc\xeb\xfa\x09"
+                       "\x18\x27\x36\x45\x54\x63\x72\x81"
+                       "\x90\x9f\xae\xbd\xcc\xdb\xea\xf9"
+                       "\x08\x17\x26\x35\x44\x53\x62\x71"
+                       "\x80\x8f\x9e\xad\xbc\xcb\xda\xe9"
+                       "\xf8\x07\x16\x25\x34\x43\x52\x61"
+                       "\x70\x7f\x8e\x9d\xac\xbb\xca\xd9"
+                       "\xe8\xf7\x06\x15\x24\x33\x42\x51"
+                       "\x60\x6f\x7e\x8d\x9c\xab\xba\xc9"
+                       "\xd8\xe7\xf6\x05\x14\x23\x32\x41"
+                       "\x50\x5f\x6e\x7d\x8c\x9b\xaa\xb9"
+                       "\xc8\xd7\xe6\xf5\x04\x13\x22\x31"
+                       "\x40\x4f\x5e\x6d\x7c\x8b\x9a\xa9"
+                       "\xb8\xc7\xd6\xe5\xf4\x03\x12\x21"
+                       "\x30\x3f\x4e\x5d\x6c\x7b\x8a\x99"
+                       "\xa8\xb7\xc6\xd5\xe4\xf3\x02\x11"
+                       "\x20\x2f\x3e\x4d\x5c\x6b\x7a\x89"
+                       "\x98\xa7\xb6\xc5\xd4\xe3\xf2\x01"
+                       "\x10\x1f\x2e\x3d\x4c\x5b\x6a\x79"
+                       "\x88\x97\xa6\xb5\xc4\xd3\xe2\xf1"
+                       "\x00\x11\x22\x33\x44\x55\x66\x77"
+                       "\x88\x99\xaa\xbb\xcc\xdd\xee\xff"
+                       "\x10\x21\x32\x43\x54\x65\x76\x87"
+                       "\x98\xa9\xba\xcb\xdc\xed\xfe\x0f"
+                       "\x20\x31\x42\x53\x64\x75\x86\x97"
+                       "\xa8\xb9\xca\xdb\xec\xfd\x0e\x1f"
+                       "\x30\x41\x52\x63\x74\x85\x96\xa7"
+                       "\xb8\xc9\xda\xeb\xfc\x0d\x1e\x2f"
+                       "\x40\x51\x62\x73\x84\x95\xa6\xb7"
+                       "\xc8\xd9\xea\xfb\x0c\x1d\x2e\x3f"
+                       "\x50\x61\x72\x83\x94\xa5\xb6\xc7"
+                       "\xd8\xe9\xfa\x0b\x1c\x2d\x3e\x4f"
+                       "\x60\x71\x82\x93\xa4\xb5\xc6\xd7"
+                       "\xe8\xf9\x0a\x1b\x2c\x3d\x4e\x5f"
+                       "\x70\x81\x92\xa3\xb4\xc5\xd6\xe7"
+                       "\xf8\x09\x1a\x2b\x3c\x4d\x5e\x6f"
+                       "\x80\x91\xa2\xb3\xc4\xd5\xe6\xf7"
+                       "\x08\x19\x2a\x3b\x4c\x5d\x6e\x7f"
+                       "\x90\xa1\xb2\xc3\xd4\xe5\xf6\x07"
+                       "\x18\x29\x3a\x4b\x5c\x6d\x7e\x8f"
+                       "\xa0\xb1\xc2\xd3\xe4\xf5\x06\x17"
+                       "\x28\x39\x4a\x5b\x6c\x7d\x8e\x9f"
+                       "\xb0\xc1\xd2\xe3\xf4\x05\x16\x27"
+                       "\x38\x49\x5a\x6b\x7c\x8d\x9e\xaf"
+                       "\xc0\xd1\xe2\xf3\x04\x15\x26\x37"
+                       "\x48\x59\x6a\x7b\x8c\x9d\xae\xbf"
+                       "\xd0\xe1\xf2\x03\x14\x25\x36\x47"
+                       "\x58\x69\x7a\x8b\x9c\xad\xbe\xcf"
+                       "\xe0\xf1\x02\x13\x24\x35\x46\x57"
+                       "\x68\x79\x8a\x9b\xac\xbd\xce\xdf"
+                       "\xf0\x01\x12\x23\x34\x45\x56\x67"
+                       "\x78\x89\x9a\xab\xbc\xcd\xde\xef"
+                       "\x00\x13\x26\x39\x4c\x5f\x72\x85"
+                       "\x98\xab\xbe\xd1\xe4\xf7\x0a\x1d"
+                       "\x30\x43\x56\x69\x7c\x8f\xa2\xb5"
+                       "\xc8\xdb\xee\x01\x14\x27\x3a\x4d"
+                       "\x60\x73\x86\x99\xac\xbf\xd2\xe5"
+                       "\xf8\x0b\x1e\x31\x44\x57\x6a\x7d"
+                       "\x90\xa3\xb6\xc9\xdc\xef\x02\x15"
+                       "\x28\x3b\x4e\x61\x74\x87\x9a\xad"
+                       "\xc0\xd3\xe6\xf9\x0c\x1f\x32\x45"
+                       "\x58\x6b\x7e\x91\xa4\xb7\xca\xdd"
+                       "\xf0\x03\x16\x29\x3c\x4f\x62\x75"
+                       "\x88\x9b\xae\xc1\xd4\xe7\xfa\x0d"
+                       "\x20\x33\x46\x59\x6c\x7f\x92\xa5"
+                       "\xb8\xcb\xde\xf1\x04\x17\x2a\x3d"
+                       "\x50\x63\x76\x89\x9c\xaf\xc2\xd5"
+                       "\xe8\xfb\x0e\x21\x34\x47\x5a\x6d"
+                       "\x80\x93\xa6\xb9\xcc\xdf\xf2\x05"
+                       "\x18\x2b\x3e\x51\x64\x77\x8a\x9d"
+                       "\xb0\xc3\xd6\xe9\xfc\x0f\x22\x35"
+                       "\x48\x5b\x6e\x81\x94\xa7\xba\xcd"
+                       "\xe0\xf3\x06\x19\x2c\x3f\x52\x65"
+                       "\x78\x8b\x9e\xb1\xc4\xd7\xea\xfd"
+                       "\x10\x23\x36\x49\x5c\x6f\x82\x95"
+                       "\xa8\xbb\xce\xe1\xf4\x07\x1a\x2d"
+                       "\x40\x53\x66\x79\x8c\x9f\xb2\xc5"
+                       "\xd8\xeb\xfe\x11\x24\x37\x4a\x5d"
+                       "\x70\x83\x96\xa9\xbc\xcf\xe2\xf5"
+                       "\x08\x1b\x2e\x41\x54\x67\x7a\x8d"
+                       "\xa0\xb3\xc6\xd9\xec\xff\x12\x25"
+                       "\x38\x4b\x5e\x71\x84\x97\xaa\xbd"
+                       "\xd0\xe3\xf6\x09\x1c\x2f\x42\x55"
+                       "\x68\x7b\x8e\xa1\xb4\xc7\xda\xed"
+                       "\x00\x15\x2a\x3f\x54\x69\x7e\x93"
+                       "\xa8\xbd\xd2\xe7\xfc\x11\x26\x3b"
+                       "\x50\x65\x7a\x8f\xa4\xb9\xce\xe3"
+                       "\xf8\x0d\x22\x37\x4c\x61\x76\x8b"
+                       "\xa0\xb5\xca\xdf\xf4\x09\x1e\x33"
+                       "\x48\x5d\x72\x87\x9c\xb1\xc6\xdb"
+                       "\xf0\x05\x1a\x2f\x44\x59\x6e\x83"
+                       "\x98\xad\xc2\xd7\xec\x01\x16\x2b"
+                       "\x40\x55\x6a\x7f\x94\xa9\xbe\xd3"
+                       "\xe8\xfd\x12\x27\x3c\x51\x66\x7b"
+                       "\x90\xa5\xba\xcf\xe4\xf9\x0e\x23"
+                       "\x38\x4d\x62\x77\x8c\xa1\xb6\xcb"
+                       "\xe0\xf5\x0a\x1f\x34\x49\x5e\x73"
+                       "\x88\x9d\xb2\xc7\xdc\xf1\x06\x1b"
+                       "\x30\x45\x5a\x6f\x84\x99\xae\xc3"
+                       "\xd8\xed\x02\x17\x2c\x41\x56\x6b"
+                       "\x80\x95\xaa\xbf\xd4\xe9\xfe\x13"
+                       "\x28\x3d\x52\x67\x7c\x91\xa6\xbb"
+                       "\xd0\xe5\xfa\x0f\x24\x39\x4e\x63"
+                       "\x78\x8d\xa2\xb7\xcc\xe1\xf6\x0b"
+                       "\x20\x35\x4a\x5f\x74\x89\x9e\xb3"
+                       "\xc8\xdd\xf2\x07\x1c\x31\x46\x5b"
+                       "\x70\x85\x9a\xaf\xc4\xd9\xee\x03"
+                       "\x18\x2d\x42\x57\x6c\x81\x96\xab"
+                       "\xc0\xd5\xea\xff\x14\x29\x3e\x53"
+                       "\x68\x7d\x92\xa7\xbc\xd1\xe6\xfb"
+                       "\x10\x25\x3a\x4f\x64\x79\x8e\xa3"
+                       "\xb8\xcd\xe2\xf7\x0c\x21\x36\x4b"
+                       "\x60\x75\x8a\x9f\xb4\xc9\xde\xf3"
+                       "\x08\x1d\x32\x47\x5c\x71\x86\x9b"
+                       "\xb0\xc5\xda\xef\x04\x19\x2e\x43"
+                       "\x58\x6d\x82\x97\xac\xc1\xd6\xeb"
+                       "\x00\x17\x2e\x45\x5c\x73\x8a\xa1"
+                       "\xb8\xcf\xe6\xfd\x14\x2b\x42\x59"
+                       "\x70\x87\x9e\xb5\xcc\xe3\xfa\x11"
+                       "\x28\x3f\x56\x6d\x84\x9b\xb2\xc9"
+                       "\xe0\xf7\x0e\x25\x3c\x53\x6a\x81"
+                       "\x98\xaf\xc6\xdd\xf4\x0b\x22\x39"
+                       "\x50\x67\x7e\x95\xac\xc3\xda\xf1"
+                       "\x08\x1f\x36\x4d\x64\x7b\x92\xa9"
+                       "\xc0\xd7\xee\x05\x1c\x33\x4a\x61"
+                       "\x78\x8f\xa6\xbd\xd4\xeb\x02\x19"
+                       "\x30\x47\x5e\x75\x8c\xa3\xba\xd1"
+                       "\xe8\xff\x16\x2d\x44\x5b\x72\x89"
+                       "\xa0\xb7\xce\xe5\xfc\x13\x2a\x41"
+                       "\x58\x6f\x86\x9d\xb4\xcb\xe2\xf9"
+                       "\x10\x27\x3e\x55\x6c\x83\x9a\xb1"
+                       "\xc8\xdf\xf6\x0d\x24\x3b\x52\x69"
+                       "\x80\x97\xae\xc5\xdc\xf3\x0a\x21"
+                       "\x38\x4f\x66\x7d\x94\xab\xc2\xd9"
+                       "\xf0\x07\x1e\x35\x4c\x63\x7a\x91"
+                       "\xa8\xbf\xd6\xed\x04\x1b\x32\x49"
+                       "\x60\x77\x8e\xa5\xbc\xd3\xea\x01"
+                       "\x18\x2f\x46\x5d\x74\x8b\xa2\xb9"
+                       "\xd0\xe7\xfe\x15\x2c\x43\x5a\x71"
+                       "\x88\x9f\xb6\xcd\xe4\xfb\x12\x29"
+                       "\x40\x57\x6e\x85\x9c\xb3\xca\xe1"
+                       "\xf8\x0f\x26\x3d\x54\x6b\x82\x99"
+                       "\xb0\xc7\xde\xf5\x0c\x23\x3a\x51"
+                       "\x68\x7f\x96\xad\xc4\xdb\xf2\x09"
+                       "\x20\x37\x4e\x65\x7c\x93\xaa\xc1"
+                       "\xd8\xef\x06\x1d\x34\x4b\x62\x79"
+                       "\x90\xa7\xbe\xd5\xec\x03\x1a\x31"
+                       "\x48\x5f\x76\x8d\xa4\xbb\xd2\xe9"
+                       "\x00\x19\x32\x4b\x64\x7d\x96\xaf"
+                       "\xc8\xe1\xfa\x13\x2c\x45\x5e\x77"
+                       "\x90\xa9\xc2\xdb\xf4\x0d\x26\x3f"
+                       "\x58\x71\x8a\xa3\xbc\xd5\xee\x07"
+                       "\x20\x39\x52\x6b\x84\x9d\xb6\xcf"
+                       "\xe8\x01\x1a\x33\x4c\x65\x7e\x97"
+                       "\xb0\xc9\xe2\xfb\x14\x2d\x46\x5f"
+                       "\x78\x91\xaa\xc3\xdc\xf5\x0e\x27"
+                       "\x40\x59\x72\x8b\xa4\xbd\xd6\xef"
+                       "\x08\x21\x3a\x53\x6c\x85\x9e\xb7"
+                       "\xd0\xe9\x02\x1b\x34\x4d\x66\x7f"
+                       "\x98\xb1\xca\xe3\xfc\x15\x2e\x47"
+                       "\x60\x79\x92\xab\xc4\xdd\xf6\x0f"
+                       "\x28\x41\x5a\x73\x8c\xa5\xbe\xd7"
+                       "\xf0\x09\x22\x3b\x54\x6d\x86\x9f"
+                       "\xb8\xd1\xea\x03\x1c\x35\x4e\x67"
+                       "\x80\x99\xb2\xcb\xe4\xfd\x16\x2f"
+                       "\x48\x61\x7a\x93\xac\xc5\xde\xf7"
+                       "\x10\x29\x42\x5b\x74\x8d\xa6\xbf"
+                       "\xd8\xf1\x0a\x23\x3c\x55\x6e\x87"
+                       "\xa0\xb9\xd2\xeb\x04\x1d\x36\x4f"
+                       "\x68\x81\x9a\xb3\xcc\xe5\xfe\x17"
+                       "\x30\x49\x62\x7b\x94\xad\xc6\xdf"
+                       "\xf8\x11\x2a\x43\x5c\x75\x8e\xa7"
+                       "\xc0\xd9\xf2\x0b\x24\x3d\x56\x6f"
+                       "\x88\xa1\xba\xd3\xec\x05\x1e\x37"
+                       "\x50\x69\x82\x9b\xb4\xcd\xe6\xff"
+                       "\x18\x31\x4a\x63\x7c\x95\xae\xc7"
+                       "\xe0\xf9\x12\x2b\x44\x5d\x76\x8f"
+                       "\xa8\xc1\xda\xf3\x0c\x25\x3e\x57"
+                       "\x70\x89\xa2\xbb\xd4\xed\x06\x1f"
+                       "\x38\x51\x6a\x83\x9c\xb5\xce\xe7"
+                       "\x00\x1b\x36\x51\x6c\x87\xa2\xbd"
+                       "\xd8\xf3\x0e\x29\x44\x5f\x7a\x95"
+                       "\xb0\xcb\xe6\x01\x1c\x37\x52\x6d"
+                       "\x88\xa3\xbe\xd9\xf4\x0f\x2a\x45"
+                       "\x60\x7b\x96\xb1\xcc\xe7\x02\x1d"
+                       "\x38\x53\x6e\x89\xa4\xbf\xda\xf5"
+                       "\x10\x2b\x46\x61\x7c\x97\xb2\xcd"
+                       "\xe8\x03\x1e\x39\x54\x6f\x8a\xa5"
+                       "\xc0\xdb\xf6\x11\x2c\x47\x62\x7d"
+                       "\x98\xb3\xce\xe9\x04\x1f\x3a\x55"
+                       "\x70\x8b\xa6\xc1\xdc\xf7\x12\x2d"
+                       "\x48\x63\x7e\x99\xb4\xcf\xea\x05"
+                       "\x20\x3b\x56\x71\x8c\xa7\xc2\xdd"
+                       "\xf8\x13\x2e\x49\x64\x7f\x9a\xb5"
+                       "\xd0\xeb\x06\x21\x3c\x57\x72\x8d"
+                       "\xa8\xc3\xde\xf9\x14\x2f\x4a\x65"
+                       "\x80\x9b\xb6\xd1\xec\x07\x22\x3d"
+                       "\x58\x73\x8e\xa9\xc4\xdf\xfa\x15"
+                       "\x30\x4b\x66\x81\x9c\xb7\xd2\xed"
+                       "\x08\x23\x3e\x59\x74\x8f\xaa\xc5"
+                       "\xe0\xfb\x16\x31\x4c\x67\x82\x9d"
+                       "\xb8\xd3\xee\x09\x24\x3f\x5a\x75"
+                       "\x90\xab\xc6\xe1\xfc\x17\x32\x4d"
+                       "\x68\x83\x9e\xb9\xd4\xef\x0a\x25"
+                       "\x40\x5b\x76\x91\xac\xc7\xe2\xfd"
+                       "\x18\x33\x4e\x69\x84\x9f\xba\xd5"
+                       "\xf0\x0b\x26\x41\x5c\x77\x92\xad"
+                       "\xc8\xe3\xfe\x19\x34\x4f\x6a\x85"
+                       "\xa0\xbb\xd6\xf1\x0c\x27\x42\x5d"
+                       "\x78\x93\xae\xc9\xe4\xff\x1a\x35"
+                       "\x50\x6b\x86\xa1\xbc\xd7\xf2\x0d"
+                       "\x28\x43\x5e\x79\x94\xaf\xca\xe5"
+                       "\x00\x1d\x3a\x57\x74\x91\xae\xcb"
+                       "\xe8\x05\x22\x3f\x5c\x79\x96\xb3"
+                       "\xd0\xed\x0a\x27\x44\x61\x7e\x9b"
+                       "\xb8\xd5\xf2\x0f\x2c\x49\x66\x83"
+                       "\xa0\xbd\xda\xf7\x14\x31\x4e\x6b"
+                       "\x88\xa5\xc2\xdf\xfc\x19\x36\x53"
+                       "\x70\x8d\xaa\xc7\xe4\x01\x1e\x3b"
+                       "\x58\x75\x92\xaf\xcc\xe9\x06\x23"
+                       "\x40\x5d\x7a\x97\xb4\xd1\xee\x0b"
+                       "\x28\x45\x62\x7f\x9c\xb9\xd6\xf3"
+                       "\x10\x2d\x4a\x67\x84\xa1\xbe\xdb"
+                       "\xf8\x15\x32\x4f\x6c\x89\xa6\xc3"
+                       "\xe0\xfd\x1a\x37\x54\x71\x8e\xab"
+                       "\xc8\xe5\x02\x1f\x3c\x59\x76\x93"
+                       "\xb0\xcd\xea\x07\x24\x41\x5e\x7b"
+                       "\x98\xb5\xd2\xef\x0c\x29\x46\x63"
+                       "\x80\x9d\xba\xd7\xf4\x11\x2e\x4b"
+                       "\x68\x85\xa2\xbf\xdc\xf9\x16\x33"
+                       "\x50\x6d\x8a\xa7\xc4\xe1\xfe\x1b"
+                       "\x38\x55\x72\x8f\xac\xc9\xe6\x03"
+                       "\x20\x3d\x5a\x77\x94\xb1\xce\xeb"
+                       "\x08\x25\x42\x5f\x7c\x99\xb6\xd3"
+                       "\xf0\x0d\x2a\x47\x64\x81\x9e\xbb"
+                       "\xd8\xf5\x12\x2f\x4c\x69\x86\xa3"
+                       "\xc0\xdd\xfa\x17\x34\x51\x6e\x8b"
+                       "\xa8\xc5\xe2\xff\x1c\x39\x56\x73"
+                       "\x90\xad\xca\xe7\x04\x21\x3e\x5b"
+                       "\x78\x95\xb2\xcf\xec\x09\x26\x43"
+                       "\x60\x7d\x9a\xb7\xd4\xf1\x0e\x2b"
+                       "\x48\x65\x82\x9f\xbc\xd9\xf6\x13"
+                       "\x30\x4d\x6a\x87\xa4\xc1\xde\xfb"
+                       "\x18\x35\x52\x6f\x8c\xa9\xc6\xe3"
+                       "\x00\x1f\x3e\x5d\x7c\x9b\xba\xd9"
+                       "\xf8\x17\x36\x55\x74\x93\xb2\xd1"
+                       "\xf0\x0f\x2e\x4d\x6c\x8b\xaa\xc9"
+                       "\xe8\x07\x26\x45\x64\x83\xa2\xc1"
+                       "\xe0\xff\x1e\x3d\x5c\x7b\x9a\xb9"
+                       "\xd8\xf7\x16\x35\x54\x73\x92\xb1"
+                       "\xd0\xef\x0e\x2d\x4c\x6b\x8a\xa9"
+                       "\xc8\xe7\x06\x25\x44\x63\x82\xa1"
+                       "\xc0\xdf\xfe\x1d\x3c\x5b\x7a\x99"
+                       "\xb8\xd7\xf6\x15\x34\x53\x72\x91"
+                       "\xb0\xcf\xee\x0d\x2c\x4b\x6a\x89"
+                       "\xa8\xc7\xe6\x05\x24\x43\x62\x81"
+                       "\xa0\xbf\xde\xfd\x1c\x3b\x5a\x79"
+                       "\x98\xb7\xd6\xf5\x14\x33\x52\x71"
+                       "\x90\xaf\xce\xed\x0c\x2b\x4a\x69"
+                       "\x88\xa7\xc6\xe5\x04\x23\x42\x61"
+                       "\x80\x9f\xbe\xdd\xfc\x1b\x3a\x59"
+                       "\x78\x97\xb6\xd5\xf4\x13\x32\x51"
+                       "\x70\x8f\xae\xcd\xec\x0b\x2a\x49"
+                       "\x68\x87\xa6\xc5\xe4\x03\x22\x41"
+                       "\x60\x7f\x9e\xbd\xdc\xfb\x1a\x39"
+                       "\x58\x77\x96\xb5\xd4\xf3\x12\x31"
+                       "\x50\x6f\x8e\xad\xcc\xeb\x0a\x29"
+                       "\x48\x67\x86\xa5\xc4\xe3\x02\x21"
+                       "\x40\x5f\x7e\x9d\xbc\xdb\xfa\x19"
+                       "\x38\x57\x76\x95\xb4\xd3\xf2\x11"
+                       "\x30\x4f\x6e\x8d\xac\xcb\xea\x09"
+                       "\x28\x47\x66\x85\xa4\xc3\xe2\x01"
+                       "\x20\x3f\x5e\x7d\x9c\xbb\xda\xf9"
+                       "\x18\x37\x56\x75\x94\xb3\xd2\xf1"
+                       "\x10\x2f\x4e\x6d\x8c\xab\xca\xe9"
+                       "\x08\x27\x46\x65\x84\xa3\xc2\xe1"
+                       "\x00\x21\x42\x63",
+               .ilen = 4100,
+               .result =
+                       "\xb5\x81\xf5\x64\x18\x73\xe3\xf0"
+                       "\x4c\x13\xf2\x77\x18\x60\x65\x5e"
+                       "\x29\x01\xce\x98\x55\x53\xf9\x0c"
+                       "\x2a\x08\xd5\x09\xb3\x57\x55\x56"
+                       "\xc5\xe9\x56\x90\xcb\x6a\xa3\xc0"
+                       "\xff\xc4\x79\xb4\xd2\x97\x5d\xc4"
+                       "\x43\xd1\xfe\x94\x7b\x88\x06\x5a"
+                       "\xb2\x9e\x2c\xfc\x44\x03\xb7\x90"
+                       "\xa0\xc1\xba\x6a\x33\xb8\xc7\xb2"
+                       "\x9d\xe1\x12\x4f\xc0\x64\xd4\x01"
+                       "\xfe\x8c\x7a\x66\xf7\xe6\x5a\x91"
+                       "\xbb\xde\x56\x86\xab\x65\x21\x30"
+                       "\x00\x84\x65\x24\xa5\x7d\x85\xb4"
+                       "\xe3\x17\xed\x3a\xb7\x6f\xb4\x0b"
+                       "\x0b\xaf\x15\xae\x5a\x8f\xf2\x0c"
+                       "\x2f\x27\xf4\x09\xd8\xd2\x96\xb7"
+                       "\x71\xf2\xc5\x99\x4d\x7e\x7f\x75"
+                       "\x77\x89\x30\x8b\x59\xdb\xa2\xb2"
+                       "\xa0\xf3\x19\x39\x2b\xc5\x7e\x3f"
+                       "\x4f\xd9\xd3\x56\x28\x97\x44\xdc"
+                       "\xc0\x8b\x77\x24\xd9\x52\xe7\xc5"
+                       "\xaf\xf6\x7d\x59\xb2\x44\x05\x1d"
+                       "\xb1\xb0\x11\xa5\x0f\xec\x33\xe1"
+                       "\x6d\x1b\x4e\x1f\xff\x57\x91\xb4"
+                       "\x5b\x9a\x96\xc5\x53\xbc\xae\x20"
+                       "\x3c\xbb\x14\xe2\xe8\x22\x33\xc1"
+                       "\x5e\x76\x9e\x46\x99\xf6\x2a\x15"
+                       "\xc6\x97\x02\xa0\x66\x43\xd1\xa6"
+                       "\x31\xa6\x9f\xfb\xf4\xd3\x69\xe5"
+                       "\xcd\x76\x95\xb8\x7a\x82\x7f\x21"
+                       "\x45\xff\x3f\xce\x55\xf6\x95\x10"
+                       "\x08\x77\x10\x43\xc6\xf3\x09\xe5"
+                       "\x68\xe7\x3c\xad\x00\x52\x45\x0d"
+                       "\xfe\x2d\xc6\xc2\x94\x8c\x12\x1d"
+                       "\xe6\x25\xae\x98\x12\x8e\x19\x9c"
+                       "\x81\x68\xb1\x11\xf6\x69\xda\xe3"
+                       "\x62\x08\x18\x7a\x25\x49\x28\xac"
+                       "\xba\x71\x12\x0b\xe4\xa2\xe5\xc7"
+                       "\x5d\x8e\xec\x49\x40\x21\xbf\x5a"
+                       "\x98\xf3\x02\x68\x55\x03\x7f\x8a"
+                       "\xe5\x94\x0c\x32\x5c\x07\x82\x63"
+                       "\xaf\x6f\x91\x40\x84\x8e\x52\x25"
+                       "\xd0\xb0\x29\x53\x05\xe2\x50\x7a"
+                       "\x34\xeb\xc9\x46\x20\xa8\x3d\xde"
+                       "\x7f\x16\x5f\x36\xc5\x2e\xdc\xd1"
+                       "\x15\x47\xc7\x50\x40\x6d\x91\xc5"
+                       "\xe7\x93\x95\x1a\xd3\x57\xbc\x52"
+                       "\x33\xee\x14\x19\x22\x52\x89\xa7"
+                       "\x4a\x25\x56\x77\x4b\xca\xcf\x0a"
+                       "\xe1\xf5\x35\x85\x30\x7e\x59\x4a"
+                       "\xbd\x14\x5b\xdf\xe3\x46\xcb\xac"
+                       "\x1f\x6c\x96\x0e\xf4\x81\xd1\x99"
+                       "\xca\x88\x63\x3d\x02\x58\x6b\xa9"
+                       "\xe5\x9f\xb3\x00\xb2\x54\xc6\x74"
+                       "\x1c\xbf\x46\xab\x97\xcc\xf8\x54"
+                       "\x04\x07\x08\x52\xe6\xc0\xda\x93"
+                       "\x74\x7d\x93\x99\x5d\x78\x68\xa6"
+                       "\x2e\x6b\xd3\x6a\x69\xcc\x12\x6b"
+                       "\xd4\xc7\xa5\xc6\xe7\xf6\x03\x04"
+                       "\x5d\xcd\x61\x5e\x17\x40\xdc\xd1"
+                       "\x5c\xf5\x08\xdf\x5c\x90\x85\xa4"
+                       "\xaf\xf6\x78\xbb\x0d\xf1\xf4\xa4"
+                       "\x54\x26\x72\x9e\x61\xfa\x86\xcf"
+                       "\xe8\x9e\xa1\xe0\xc7\x48\x23\xae"
+                       "\x5a\x90\xae\x75\x0a\x74\x18\x89"
+                       "\x05\xb1\x92\xb2\x7f\xd0\x1b\xa6"
+                       "\x62\x07\x25\x01\xc7\xc2\x4f\xf9"
+                       "\xe8\xfe\x63\x95\x80\x07\xb4\x26"
+                       "\xcc\xd1\x26\xb6\xc4\x3f\x9e\xcb"
+                       "\x8e\x3b\x2e\x44\x16\xd3\x10\x9a"
+                       "\x95\x08\xeb\xc8\xcb\xeb\xbf\x6f"
+                       "\x0b\xcd\x1f\xc8\xca\x86\xaa\xec"
+                       "\x33\xe6\x69\xf4\x45\x25\x86\x3a"
+                       "\x22\x94\x4f\x00\x23\x6a\x44\xc2"
+                       "\x49\x97\x33\xab\x36\x14\x0a\x70"
+                       "\x24\xc3\xbe\x04\x3b\x79\xa0\xf9"
+                       "\xb8\xe7\x76\x29\x22\x83\xd7\xf2"
+                       "\x94\xf4\x41\x49\xba\x5f\x7b\x07"
+                       "\xb5\xfb\xdb\x03\x1a\x9f\xb6\x4c"
+                       "\xc2\x2e\x37\x40\x49\xc3\x38\x16"
+                       "\xe2\x4f\x77\x82\xb0\x68\x4c\x71"
+                       "\x1d\x57\x61\x9c\xd9\x4e\x54\x99"
+                       "\x47\x13\x28\x73\x3c\xbb\x00\x90"
+                       "\xf3\x4d\xc9\x0e\xfd\xe7\xb1\x71"
+                       "\xd3\x15\x79\xbf\xcc\x26\x2f\xbd"
+                       "\xad\x6c\x50\x69\x6c\x3e\x6d\x80"
+                       "\x9a\xea\x78\xaf\x19\xb2\x0d\x4d"
+                       "\xad\x04\x07\xae\x22\x90\x4a\x93"
+                       "\x32\x0e\x36\x9b\x1b\x46\xba\x3b"
+                       "\xb4\xac\xc6\xd1\xa2\x31\x53\x3b"
+                       "\x2a\x3d\x45\xfe\x03\x61\x10\x85"
+                       "\x17\x69\xa6\x78\xcc\x6c\x87\x49"
+                       "\x53\xf9\x80\x10\xde\x80\xa2\x41"
+                       "\x6a\xc3\x32\x02\xad\x6d\x3c\x56"
+                       "\x00\x71\x51\x06\xa7\xbd\xfb\xef"
+                       "\x3c\xb5\x9f\xfc\x48\x7d\x53\x7c"
+                       "\x66\xb0\x49\x23\xc4\x47\x10\x0e"
+                       "\xe5\x6c\x74\x13\xe6\xc5\x3f\xaa"
+                       "\xde\xff\x07\x44\xdd\x56\x1b\xad"
+                       "\x09\x77\xfb\x5b\x12\xb8\x0d\x38"
+                       "\x17\x37\x35\x7b\x9b\xbc\xfe\xd4"
+                       "\x7e\x8b\xda\x7e\x5b\x04\xa7\x22"
+                       "\xa7\x31\xa1\x20\x86\xc7\x1b\x99"
+                       "\xdb\xd1\x89\xf4\x94\xa3\x53\x69"
+                       "\x8d\xe7\xe8\x74\x11\x8d\x74\xd6"
+                       "\x07\x37\x91\x9f\xfd\x67\x50\x3a"
+                       "\xc9\xe1\xf4\x36\xd5\xa0\x47\xd1"
+                       "\xf9\xe5\x39\xa3\x31\xac\x07\x36"
+                       "\x23\xf8\x66\x18\x14\x28\x34\x0f"
+                       "\xb8\xd0\xe7\x29\xb3\x04\x4b\x55"
+                       "\x01\x41\xb2\x75\x8d\xcb\x96\x85"
+                       "\x3a\xfb\xab\x2b\x9e\xfa\x58\x20"
+                       "\x44\x1f\xc0\x14\x22\x75\x61\xe8"
+                       "\xaa\x19\xcf\xf1\x82\x56\xf4\xd7"
+                       "\x78\x7b\x3d\x5f\xb3\x9e\x0b\x8a"
+                       "\x57\x50\xdb\x17\x41\x65\x4d\xa3"
+                       "\x02\xc9\x9c\x9c\x53\xfb\x39\x39"
+                       "\x9b\x1d\x72\x24\xda\xb7\x39\xbe"
+                       "\x13\x3b\xfa\x29\xda\x9e\x54\x64"
+                       "\x6e\xba\xd8\xa1\xcb\xb3\x36\xfa"
+                       "\xcb\x47\x85\xe9\x61\x38\xbc\xbe"
+                       "\xc5\x00\x38\x2a\x54\xf7\xc4\xb9"
+                       "\xb3\xd3\x7b\xa0\xa0\xf8\x72\x7f"
+                       "\x8c\x8e\x82\x0e\xc6\x1c\x75\x9d"
+                       "\xca\x8e\x61\x87\xde\xad\x80\xd2"
+                       "\xf5\xf9\x80\xef\x15\x75\xaf\xf5"
+                       "\x80\xfb\xff\x6d\x1e\x25\xb7\x40"
+                       "\x61\x6a\x39\x5a\x6a\xb5\x31\xab"
+                       "\x97\x8a\x19\x89\x44\x40\xc0\xa6"
+                       "\xb4\x4e\x30\x32\x7b\x13\xe7\x67"
+                       "\xa9\x8b\x57\x04\xc2\x01\xa6\xf4"
+                       "\x28\x99\xad\x2c\x76\xa3\x78\xc2"
+                       "\x4a\xe6\xca\x5c\x50\x6a\xc1\xb0"
+                       "\x62\x4b\x10\x8e\x7c\x17\x43\xb3"
+                       "\x17\x66\x1c\x3e\x8d\x69\xf0\x5a"
+                       "\x71\xf5\x97\xdc\xd1\x45\xdd\x28"
+                       "\xf3\x5d\xdf\x53\x7b\x11\xe5\xbc"
+                       "\x4c\xdb\x1b\x51\x6b\xe9\xfb\x3d"
+                       "\xc1\xc3\x2c\xb9\x71\xf5\xb6\xb2"
+                       "\x13\x36\x79\x80\x53\xe8\xd3\xa6"
+                       "\x0a\xaf\xfd\x56\x97\xf7\x40\x8e"
+                       "\x45\xce\xf8\xb0\x9e\x5c\x33\x82"
+                       "\xb0\x44\x56\xfc\x05\x09\xe9\x2a"
+                       "\xac\x26\x80\x14\x1d\xc8\x3a\x35"
+                       "\x4c\x82\x97\xfd\x76\xb7\xa9\x0a"
+                       "\x35\x58\x79\x8e\x0f\x66\xea\xaf"
+                       "\x51\x6c\x09\xa9\x6e\x9b\xcb\x9a"
+                       "\x31\x47\xa0\x2f\x7c\x71\xb4\x4a"
+                       "\x11\xaa\x8c\x66\xc5\x64\xe6\x3a"
+                       "\x54\xda\x24\x6a\xc4\x41\x65\x46"
+                       "\x82\xa0\x0a\x0f\x5f\xfb\x25\xd0"
+                       "\x2c\x91\xa7\xee\xc4\x81\x07\x86"
+                       "\x75\x5e\x33\x69\x97\xe4\x2c\xa8"
+                       "\x9d\x9f\x0b\x6a\xbe\xad\x98\xda"
+                       "\x6d\x94\x41\xda\x2c\x1e\x89\xc4"
+                       "\xc2\xaf\x1e\x00\x05\x0b\x83\x60"
+                       "\xbd\x43\xea\x15\x23\x7f\xb9\xac"
+                       "\xee\x4f\x2c\xaf\x2a\xf3\xdf\xd0"
+                       "\xf3\x19\x31\xbb\x4a\x74\x84\x17"
+                       "\x52\x32\x2c\x7d\x61\xe4\xcb\xeb"
+                       "\x80\x38\x15\x52\xcb\x6f\xea\xe5"
+                       "\x73\x9c\xd9\x24\x69\xc6\x95\x32"
+                       "\x21\xc8\x11\xe4\xdc\x36\xd7\x93"
+                       "\x38\x66\xfb\xb2\x7f\x3a\xb9\xaf"
+                       "\x31\xdd\x93\x75\x78\x8a\x2c\x94"
+                       "\x87\x1a\x58\xec\x9e\x7d\x4d\xba"
+                       "\xe1\xe5\x4d\xfc\xbc\xa4\x2a\x14"
+                       "\xef\xcc\xa7\xec\xab\x43\x09\x18"
+                       "\xd3\xab\x68\xd1\x07\x99\x44\x47"
+                       "\xd6\x83\x85\x3b\x30\xea\xa9\x6b"
+                       "\x63\xea\xc4\x07\xfb\x43\x2f\xa4"
+                       "\xaa\xb0\xab\x03\x89\xce\x3f\x8c"
+                       "\x02\x7c\x86\x54\xbc\x88\xaf\x75"
+                       "\xd2\xdc\x63\x17\xd3\x26\xf6\x96"
+                       "\xa9\x3c\xf1\x61\x8c\x11\x18\xcc"
+                       "\xd6\xea\x5b\xe2\xcd\xf0\xf1\xb2"
+                       "\xe5\x35\x90\x1f\x85\x4c\x76\x5b"
+                       "\x66\xce\x44\xa4\x32\x9f\xe6\x7b"
+                       "\x71\x6e\x9f\x58\x15\x67\x72\x87"
+                       "\x64\x8e\x3a\x44\x45\xd4\x76\xfa"
+                       "\xc2\xf6\xef\x85\x05\x18\x7a\x9b"
+                       "\xba\x41\x54\xac\xf0\xfc\x59\x12"
+                       "\x3f\xdf\xa0\xe5\x8a\x65\xfd\x3a"
+                       "\x62\x8d\x83\x2c\x03\xbe\x05\x76"
+                       "\x2e\x53\x49\x97\x94\x33\xae\x40"
+                       "\x81\x15\xdb\x6e\xad\xaa\xf5\x4b"
+                       "\xe3\x98\x70\xdf\xe0\x7c\xcd\xdb"
+                       "\x02\xd4\x7d\x2f\xc1\xe6\xb4\xf3"
+                       "\xd7\x0d\x7a\xd9\x23\x9e\x87\x2d"
+                       "\xce\x87\xad\xcc\x72\x05\x00\x29"
+                       "\xdc\x73\x7f\x64\xc1\x15\x0e\xc2"
+                       "\xdf\xa7\x5f\xeb\x41\xa1\xcd\xef"
+                       "\x5c\x50\x79\x2a\x56\x56\x71\x8c"
+                       "\xac\xc0\x79\x50\x69\xca\x59\x32"
+                       "\x65\xf2\x54\xe4\x52\x38\x76\xd1"
+                       "\x5e\xde\x26\x9e\xfb\x75\x2e\x11"
+                       "\xb5\x10\xf4\x17\x73\xf5\x89\xc7"
+                       "\x4f\x43\x5c\x8e\x7c\xb9\x05\x52"
+                       "\x24\x40\x99\xfe\x9b\x85\x0b\x6c"
+                       "\x22\x3e\x8b\xae\x86\xa1\xd2\x79"
+                       "\x05\x68\x6b\xab\xe3\x41\x49\xed"
+                       "\x15\xa1\x8d\x40\x2d\x61\xdf\x1a"
+                       "\x59\xc9\x26\x8b\xef\x30\x4c\x88"
+                       "\x4b\x10\xf8\x8d\xa6\x92\x9f\x4b"
+                       "\xf3\xc4\x53\x0b\x89\x5d\x28\x92"
+                       "\xcf\x78\xb2\xc0\x5d\xed\x7e\xfc"
+                       "\xc0\x12\x23\x5f\x5a\x78\x86\x43"
+                       "\x6e\x27\xf7\x5a\xa7\x6a\xed\x19"
+                       "\x04\xf0\xb3\x12\xd1\xbd\x0e\x89"
+                       "\x6e\xbc\x96\xa8\xd8\x49\x39\x9f"
+                       "\x7e\x67\xf0\x2e\x3e\x01\xa9\xba"
+                       "\xec\x8b\x62\x8e\xcb\x4a\x70\x43"
+                       "\xc7\xc2\xc4\xca\x82\x03\x73\xe9"
+                       "\x11\xdf\xcf\x54\xea\xc9\xb0\x95"
+                       "\x51\xc0\x13\x3d\x92\x05\xfa\xf4"
+                       "\xa9\x34\xc8\xce\x6c\x3d\x54\xcc"
+                       "\xc4\xaf\xf1\xdc\x11\x44\x26\xa2"
+                       "\xaf\xf1\x85\x75\x7d\x03\x61\x68"
+                       "\x4e\x78\xc6\x92\x7d\x86\x7d\x77"
+                       "\xdc\x71\x72\xdb\xc6\xae\xa1\xcb"
+                       "\x70\x9a\x0b\x19\xbe\x4a\x6c\x2a"
+                       "\xe2\xba\x6c\x64\x9a\x13\x28\xdf"
+                       "\x85\x75\xe6\x43\xf6\x87\x08\x68"
+                       "\x6e\xba\x6e\x79\x9f\x04\xbc\x23"
+                       "\x50\xf6\x33\x5c\x1f\x24\x25\xbe"
+                       "\x33\x47\x80\x45\x56\xa3\xa7\xd7"
+                       "\x7a\xb1\x34\x0b\x90\x3c\x9c\xad"
+                       "\x44\x5f\x9e\x0e\x9d\xd4\xbd\x93"
+                       "\x5e\xfa\x3c\xe0\xb0\xd9\xed\xf3"
+                       "\xd6\x2e\xff\x24\xd8\x71\x6c\xed"
+                       "\xaf\x55\xeb\x22\xac\x93\x68\x32"
+                       "\x05\x5b\x47\xdd\xc6\x4a\xcb\xc7"
+                       "\x10\xe1\x3c\x92\x1a\xf3\x23\x78"
+                       "\x2b\xa1\xd2\x80\xf4\x12\xb1\x20"
+                       "\x8f\xff\x26\x35\xdd\xfb\xc7\x4e"
+                       "\x78\xf1\x2d\x50\x12\x77\xa8\x60"
+                       "\x7c\x0f\xf5\x16\x2f\x63\x70\x2a"
+                       "\xc0\x96\x80\x4e\x0a\xb4\x93\x35"
+                       "\x5d\x1d\x3f\x56\xf7\x2f\xbb\x90"
+                       "\x11\x16\x8f\xa2\xec\x47\xbe\xac"
+                       "\x56\x01\x26\x56\xb1\x8c\xb2\x10"
+                       "\xf9\x1a\xca\xf5\xd1\xb7\x39\x20"
+                       "\x63\xf1\x69\x20\x4f\x13\x12\x1f"
+                       "\x5b\x65\xfc\x98\xf7\xc4\x7a\xbe"
+                       "\xf7\x26\x4d\x2b\x84\x7b\x42\xad"
+                       "\xd8\x7a\x0a\xb4\xd8\x74\xbf\xc1"
+                       "\xf0\x6e\xb4\x29\xa3\xbb\xca\x46"
+                       "\x67\x70\x6a\x2d\xce\x0e\xa2\x8a"
+                       "\xa9\x87\xbf\x05\xc4\xc1\x04\xa3"
+                       "\xab\xd4\x45\x43\x8c\xb6\x02\xb0"
+                       "\x41\xc8\xfc\x44\x3d\x59\xaa\x2e"
+                       "\x44\x21\x2a\x8d\x88\x9d\x57\xf4"
+                       "\xa0\x02\x77\xb8\xa6\xa0\xe6\x75"
+                       "\x5c\x82\x65\x3e\x03\x5c\x29\x8f"
+                       "\x38\x55\xab\x33\x26\xef\x9f\x43"
+                       "\x52\xfd\x68\xaf\x36\xb4\xbb\x9a"
+                       "\x58\x09\x09\x1b\xc3\x65\x46\x46"
+                       "\x1d\xa7\x94\x18\x23\x50\x2c\xca"
+                       "\x2c\x55\x19\x97\x01\x9d\x93\x3b"
+                       "\x63\x86\xf2\x03\x67\x45\xd2\x72"
+                       "\x28\x52\x6c\xf4\xe3\x1c\xb5\x11"
+                       "\x13\xf1\xeb\x21\xc7\xd9\x56\x82"
+                       "\x2b\x82\x39\xbd\x69\x54\xed\x62"
+                       "\xc3\xe2\xde\x73\xd4\x6a\x12\xae"
+                       "\x13\x21\x7f\x4b\x5b\xfc\xbf\xe8"
+                       "\x2b\xbe\x56\xba\x68\x8b\x9a\xb1"
+                       "\x6e\xfa\xbf\x7e\x5a\x4b\xf1\xac"
+                       "\x98\x65\x85\xd1\x93\x53\xd3\x7b"
+                       "\x09\xdd\x4b\x10\x6d\x84\xb0\x13"
+                       "\x65\xbd\xcf\x52\x09\xc4\x85\xe2"
+                       "\x84\x74\x15\x65\xb7\xf7\x51\xaf"
+                       "\x55\xad\xa4\xd1\x22\x54\x70\x94"
+                       "\xa0\x1c\x90\x41\xfd\x99\xd7\x5a"
+                       "\x31\xef\xaa\x25\xd0\x7f\x4f\xea"
+                       "\x1d\x55\x42\xe5\x49\xb0\xd0\x46"
+                       "\x62\x36\x43\xb2\x82\x15\x75\x50"
+                       "\xa4\x72\xeb\x54\x27\x1f\x8a\xe4"
+                       "\x7d\xe9\x66\xc5\xf1\x53\xa4\xd1"
+                       "\x0c\xeb\xb8\xf8\xbc\xd4\xe2\xe7"
+                       "\xe1\xf8\x4b\xcb\xa9\xa1\xaf\x15"
+                       "\x83\xcb\x72\xd0\x33\x79\x00\x2d"
+                       "\x9f\xd7\xf1\x2e\x1e\x10\xe4\x45"
+                       "\xc0\x75\x3a\x39\xea\x68\xf7\x5d"
+                       "\x1b\x73\x8f\xe9\x8e\x0f\x72\x47"
+                       "\xae\x35\x0a\x31\x7a\x14\x4d\x4a"
+                       "\x6f\x47\xf7\x7e\x91\x6e\x74\x8b"
+                       "\x26\x47\xf9\xc3\xf9\xde\x70\xf5"
+                       "\x61\xab\xa9\x27\x9f\x82\xe4\x9c"
+                       "\x89\x91\x3f\x2e\x6a\xfd\xb5\x49"
+                       "\xe9\xfd\x59\x14\x36\x49\x40\x6d"
+                       "\x32\xd8\x85\x42\xf3\xa5\xdf\x0c"
+                       "\xa8\x27\xd7\x54\xe2\x63\x2f\xf2"
+                       "\x7e\x8b\x8b\xe7\xf1\x9a\x95\x35"
+                       "\x43\xdc\x3a\xe4\xb6\xf4\xd0\xdf"
+                       "\x9c\xcb\x94\xf3\x21\xa0\x77\x50"
+                       "\xe2\xc6\xc4\xc6\x5f\x09\x64\x5b"
+                       "\x92\x90\xd8\xe1\xd1\xed\x4b\x42"
+                       "\xd7\x37\xaf\x65\x3d\x11\x39\xb6"
+                       "\x24\x8a\x60\xae\xd6\x1e\xbf\x0e"
+                       "\x0d\xd7\xdc\x96\x0e\x65\x75\x4e"
+                       "\x29\x06\x9d\xa4\x51\x3a\x10\x63"
+                       "\x8f\x17\x07\xd5\x8e\x3c\xf4\x28"
+                       "\x00\x5a\x5b\x05\x19\xd8\xc0\x6c"
+                       "\xe5\x15\xe4\x9c\x9d\x71\x9d\x5e"
+                       "\x94\x29\x1a\xa7\x80\xfa\x0e\x33"
+                       "\x03\xdd\xb7\x3e\x9a\xa9\x26\x18"
+                       "\x37\xa9\x64\x08\x4d\x94\x5a\x88"
+                       "\xca\x35\xce\x81\x02\xe3\x1f\x1b"
+                       "\x89\x1a\x77\x85\xe3\x41\x6d\x32"
+                       "\x42\x19\x23\x7d\xc8\x73\xee\x25"
+                       "\x85\x0d\xf8\x31\x25\x79\x1b\x6f"
+                       "\x79\x25\xd2\xd8\xd4\x23\xfd\xf7"
+                       "\x82\x36\x6a\x0c\x46\x22\x15\xe9"
+                       "\xff\x72\x41\x91\x91\x7d\x3a\xb7"
+                       "\xdd\x65\x99\x70\xf6\x8d\x84\xf8"
+                       "\x67\x15\x20\x11\xd6\xb2\x55\x7b"
+                       "\xdb\x87\xee\xef\x55\x89\x2a\x59"
+                       "\x2b\x07\x8f\x43\x8a\x59\x3c\x01"
+                       "\x8b\x65\x54\xa1\x66\xd5\x38\xbd"
+                       "\xc6\x30\xa9\xcc\x49\xb6\xa8\x1b"
+                       "\xb8\xc0\x0e\xe3\x45\x28\xe2\xff"
+                       "\x41\x9f\x7e\x7c\xd1\xae\x9e\x25"
+                       "\x3f\x4c\x7c\x7c\xf4\xa8\x26\x4d"
+                       "\x5c\xfd\x4b\x27\x18\xf9\x61\x76"
+                       "\x48\xba\x0c\x6b\xa9\x4d\xfc\xf5"
+                       "\x3b\x35\x7e\x2f\x4a\xa9\xc2\x9a"
+                       "\xae\xab\x86\x09\x89\xc9\xc2\x40"
+                       "\x39\x2c\x81\xb3\xb8\x17\x67\xc2"
+                       "\x0d\x32\x4a\x3a\x67\x81\xd7\x1a"
+                       "\x34\x52\xc5\xdb\x0a\xf5\x63\x39"
+                       "\xea\x1f\xe1\x7c\xa1\x9e\xc1\x35"
+                       "\xe3\xb1\x18\x45\x67\xf9\x22\x38"
+                       "\x95\xd9\x34\x34\x86\xc6\x41\x94"
+                       "\x15\xf9\x5b\x41\xa6\x87\x8b\xf8"
+                       "\xd5\xe1\x1b\xe2\x5b\xf3\x86\x10"
+                       "\xff\xe6\xae\x69\x76\xbc\x0d\xb4"
+                       "\x09\x90\x0c\xa2\x65\x0c\xad\x74"
+                       "\xf5\xd7\xff\xda\xc1\xce\x85\xbe"
+                       "\x00\xa7\xff\x4d\x2f\x65\xd3\x8c"
+                       "\x86\x2d\x05\xe8\xed\x3e\x6b\x8b"
+                       "\x0f\x3d\x83\x8c\xf1\x1d\x5b\x96"
+                       "\x2e\xb1\x9c\xc2\x98\xe1\x70\xb9"
+                       "\xba\x5c\x8a\x43\xd6\x34\xa7\x2d"
+                       "\xc9\x92\xae\xf2\xa5\x7b\x05\x49"
+                       "\xa7\x33\x34\x86\xca\xe4\x96\x23"
+                       "\x76\x5b\xf2\xc6\xf1\x51\x28\x42"
+                       "\x7b\xcc\x76\x8f\xfa\xa2\xad\x31"
+                       "\xd4\xd6\x7a\x6d\x25\x25\x54\xe4"
+                       "\x3f\x50\x59\xe1\x5c\x05\xb7\x27"
+                       "\x48\xbf\x07\xec\x1b\x13\xbe\x2b"
+                       "\xa1\x57\x2b\xd5\xab\xd7\xd0\x4c"
+                       "\x1e\xcb\x71\x9b\xc5\x90\x85\xd3"
+                       "\xde\x59\xec\x71\xeb\x89\xbb\xd0"
+                       "\x09\x50\xe1\x16\x3f\xfd\x1c\x34"
+                       "\xc3\x1c\xa1\x10\x77\x53\x98\xef"
+                       "\xf2\xfd\xa5\x01\x59\xc2\x9b\x26"
+                       "\xc7\x42\xd9\x49\xda\x58\x2b\x6e"
+                       "\x9f\x53\x19\x76\x7e\xd9\xc9\x0e"
+                       "\x68\xc8\x7f\x51\x22\x42\xef\x49"
+                       "\xa4\x55\xb6\x36\xac\x09\xc7\x31"
+                       "\x88\x15\x4b\x2e\x8f\x3a\x08\xf7"
+                       "\xd8\xf7\xa8\xc5\xa9\x33\xa6\x45"
+                       "\xe4\xc4\x94\x76\xf3\x0d\x8f\x7e"
+                       "\xc8\xf6\xbc\x23\x0a\xb6\x4c\xd3"
+                       "\x6a\xcd\x36\xc2\x90\x5c\x5c\x3c"
+                       "\x65\x7b\xc2\xd6\xcc\xe6\x0d\x87"
+                       "\x73\x2e\x71\x79\x16\x06\x63\x28"
+                       "\x09\x15\xd8\x89\x38\x38\x3d\xb5"
+                       "\x42\x1c\x08\x24\xf7\x2a\xd2\x9d"
+                       "\xc8\xca\xef\xf9\x27\xd8\x07\x86"
+                       "\xf7\x43\x0b\x55\x15\x3f\x9f\x83"
+                       "\xef\xdc\x49\x9d\x2a\xc1\x54\x62"
+                       "\xbd\x9b\x66\x55\x9f\xb7\x12\xf3"
+                       "\x1b\x4d\x9d\x2a\x5c\xed\x87\x75"
+                       "\x87\x26\xec\x61\x2c\xb4\x0f\x89"
+                       "\xb0\xfb\x2e\x68\x5d\x15\xc7\x8d"
+                       "\x2e\xc0\xd9\xec\xaf\x4f\xd2\x25"
+                       "\x29\xe8\xd2\x26\x2b\x67\xe9\xfc"
+                       "\x2b\xa8\x67\x96\x12\x1f\x5b\x96"
+                       "\xc6\x14\x53\xaf\x44\xea\xd6\xe2"
+                       "\x94\x98\xe4\x12\x93\x4c\x92\xe0"
+                       "\x18\xa5\x8d\x2d\xe4\x71\x3c\x47"
+                       "\x4c\xf7\xe6\x47\x9e\xc0\x68\xdf"
+                       "\xd4\xf5\x5a\x74\xb1\x2b\x29\x03"
+                       "\x19\x07\xaf\x90\x62\x5c\x68\x98"
+                       "\x48\x16\x11\x02\x9d\xee\xb4\x9b"
+                       "\xe5\x42\x7f\x08\xfd\x16\x32\x0b"
+                       "\xd0\xb3\xfa\x2b\xb7\x99\xf9\x29"
+                       "\xcd\x20\x45\x9f\xb3\x1a\x5d\xa2"
+                       "\xaf\x4d\xe0\xbd\x42\x0d\xbc\x74"
+                       "\x99\x9c\x8e\x53\x1a\xb4\x3e\xbd"
+                       "\xa2\x9a\x2d\xf7\xf8\x39\x0f\x67"
+                       "\x63\xfc\x6b\xc0\xaf\xb3\x4b\x4f"
+                       "\x55\xc4\xcf\xa7\xc8\x04\x11\x3e"
+                       "\x14\x32\xbb\x1b\x38\x77\xd6\x7f"
+                       "\x54\x4c\xdf\x75\xf3\x07\x2d\x33"
+                       "\x9b\xa8\x20\xe1\x7b\x12\xb5\xf3"
+                       "\xef\x2f\xce\x72\xe5\x24\x60\xc1"
+                       "\x30\xe2\xab\xa1\x8e\x11\x09\xa8"
+                       "\x21\x33\x44\xfe\x7f\x35\x32\x93"
+                       "\x39\xa7\xad\x8b\x79\x06\xb2\xcb"
+                       "\x4e\xa9\x5f\xc7\xba\x74\x29\xec"
+                       "\x93\xa0\x4e\x54\x93\xc0\xbc\x55"
+                       "\x64\xf0\x48\xe5\x57\x99\xee\x75"
+                       "\xd6\x79\x0f\x66\xb7\xc6\x57\x76"
+                       "\xf7\xb7\xf3\x9c\xc5\x60\xe8\x7f"
+                       "\x83\x76\xd6\x0e\xaa\xe6\x90\x39"
+                       "\x1d\xa6\x32\x6a\x34\xe3\x55\xf8"
+                       "\x58\xa0\x58\x7d\x33\xe0\x22\x39"
+                       "\x44\x64\x87\x86\x5a\x2f\xa7\x7e"
+                       "\x0f\x38\xea\xb0\x30\xcc\x61\xa5"
+                       "\x6a\x32\xae\x1e\xf7\xe9\xd0\xa9"
+                       "\x0c\x32\x4b\xb5\x49\x28\xab\x85"
+                       "\x2f\x8e\x01\x36\x38\x52\xd0\xba"
+                       "\xd6\x02\x78\xf8\x0e\x3e\x9c\x8b"
+                       "\x6b\x45\x99\x3f\x5c\xfe\x58\xf1"
+                       "\x5c\x94\x04\xe1\xf5\x18\x6d\x51"
+                       "\xb2\x5d\x18\x20\xb6\xc2\x9a\x42"
+                       "\x1d\xb3\xab\x3c\xb6\x3a\x13\x03"
+                       "\xb2\x46\x82\x4f\xfc\x64\xbc\x4f"
+                       "\xca\xfa\x9c\xc0\xd5\xa7\xbd\x11"
+                       "\xb7\xe4\x5a\xf6\x6f\x4d\x4d\x54"
+                       "\xea\xa4\x98\x66\xd4\x22\x3b\xd3"
+                       "\x8f\x34\x47\xd9\x7c\xf4\x72\x3b"
+                       "\x4d\x02\x77\xf6\xd6\xdd\x08\x0a"
+                       "\x81\xe1\x86\x89\x3e\x56\x10\x3c"
+                       "\xba\xd7\x81\x8c\x08\xbc\x8b\xe2"
+                       "\x53\xec\xa7\x89\xee\xc8\x56\xb5"
+                       "\x36\x2c\xb2\x03\xba\x99\xdd\x7c"
+                       "\x48\xa0\xb0\xbc\x91\x33\xe9\xa8"
+                       "\xcb\xcd\xcf\x59\x5f\x1f\x15\xe2"
+                       "\x56\xf5\x4e\x01\x35\x27\x45\x77"
+                       "\x47\xc8\xbc\xcb\x7e\x39\xc1\x97"
+                       "\x28\xd3\x84\xfc\x2c\x3e\xc8\xad"
+                       "\x9c\xf8\x8a\x61\x9c\x28\xaa\xc5"
+                       "\x99\x20\x43\x85\x9d\xa5\xe2\x8b"
+                       "\xb8\xae\xeb\xd0\x32\x0d\x52\x78"
+                       "\x09\x56\x3f\xc7\xd8\x7e\x26\xfc"
+                       "\x37\xfb\x6f\x04\xfc\xfa\x92\x10"
+                       "\xac\xf8\x3e\x21\xdc\x8c\x21\x16"
+                       "\x7d\x67\x6e\xf6\xcd\xda\xb6\x98"
+                       "\x23\xab\x23\x3c\xb2\x10\xa0\x53"
+                       "\x5a\x56\x9f\xc5\xd0\xff\xbb\xe4"
+                       "\x98\x3c\x69\x1e\xdb\x38\x8f\x7e"
+                       "\x0f\xd2\x98\x88\x81\x8b\x45\x67"
+                       "\xea\x33\xf1\xeb\xe9\x97\x55\x2e"
+                       "\xd9\xaa\xeb\x5a\xec\xda\xe1\x68"
+                       "\xa8\x9d\x3c\x84\x7c\x05\x3d\x62"
+                       "\x87\x8f\x03\x21\x28\x95\x0c\x89"
+                       "\x25\x22\x4a\xb0\x93\xa9\x50\xa2"
+                       "\x2f\x57\x6e\x18\x42\x19\x54\x0c"
+                       "\x55\x67\xc6\x11\x49\xf4\x5c\xd2"
+                       "\xe9\x3d\xdd\x8b\x48\x71\x21\x00"
+                       "\xc3\x9a\x6c\x85\x74\x28\x83\x4a"
+                       "\x1b\x31\x05\xe1\x06\x92\xe7\xda"
+                       "\x85\x73\x78\x45\x20\x7f\xae\x13"
+                       "\x7c\x33\x06\x22\xf4\x83\xf9\x35"
+                       "\x3f\x6c\x71\xa8\x4e\x48\xbe\x9b"
+                       "\xce\x8a\xba\xda\xbe\x28\x08\xf7"
+                       "\xe2\x14\x8c\x71\xea\x72\xf9\x33"
+                       "\xf2\x88\x3f\xd7\xbb\x69\x6c\x29"
+                       "\x19\xdc\x84\xce\x1f\x12\x4f\xc8"
+                       "\xaf\xa5\x04\xba\x5a\xab\xb0\xd9"
+                       "\x14\x1f\x6c\x68\x98\x39\x89\x7a"
+                       "\xd9\xd8\x2f\xdf\xa8\x47\x4a\x25"
+                       "\xe2\xfb\x33\xf4\x59\x78\xe1\x68"
+                       "\x85\xcf\xfe\x59\x20\xd4\x05\x1d"
+                       "\x80\x99\xae\xbc\xca\xae\x0f\x2f"
+                       "\x65\x43\x34\x8e\x7e\xac\xd3\x93"
+                       "\x2f\xac\x6d\x14\x3d\x02\x07\x70"
+                       "\x9d\xa4\xf3\x1b\x5c\x36\xfc\x01"
+                       "\x73\x34\x85\x0c\x6c\xd6\xf1\xbd"
+                       "\x3f\xdf\xee\xf5\xd9\xba\x56\xef"
+                       "\xf4\x9b\x6b\xee\x9f\x5a\x78\x6d"
+                       "\x32\x19\xf4\xf7\xf8\x4c\x69\x0b"
+                       "\x4b\xbc\xbb\xb7\xf2\x85\xaf\x70"
+                       "\x75\x24\x6c\x54\xa7\x0e\x4d\x1d"
+                       "\x01\xbf\x08\xac\xcf\x7f\x2c\xe3"
+                       "\x14\x89\x5e\x70\x5a\x99\x92\xcd"
+                       "\x01\x84\xc8\xd2\xab\xe5\x4f\x58"
+                       "\xe7\x0f\x2f\x0e\xff\x68\xea\xfd"
+                       "\x15\xb3\x17\xe6\xb0\xe7\x85\xd8"
+                       "\x23\x2e\x05\xc7\xc9\xc4\x46\x1f"
+                       "\xe1\x9e\x49\x20\x23\x24\x4d\x7e"
+                       "\x29\x65\xff\xf4\xb6\xfd\x1a\x85"
+                       "\xc4\x16\xec\xfc\xea\x7b\xd6\x2c"
+                       "\x43\xf8\xb7\xbf\x79\xc0\x85\xcd"
+                       "\xef\xe1\x98\xd3\xa5\xf7\x90\x8c"
+                       "\xe9\x7f\x80\x6b\xd2\xac\x4c\x30"
+                       "\xa7\xc6\x61\x6c\xd2\xf9\x2c\xff"
+                       "\x30\xbc\x22\x81\x7d\x93\x12\xe4"
+                       "\x0a\xcd\xaf\xdd\xe8\xab\x0a\x1e"
+                       "\x13\xa4\x27\xc3\x5f\xf7\x4b\xbb"
+                       "\x37\x09\x4b\x91\x6f\x92\x4f\xaf"
+                       "\x52\xee\xdf\xef\x09\x6f\xf7\x5c"
+                       "\x6e\x12\x17\x72\x63\x57\xc7\xba"
+                       "\x3b\x6b\x38\x32\x73\x1b\x9c\x80"
+                       "\xc1\x7a\xc6\xcf\xcd\x35\xc0\x6b"
+                       "\x31\x1a\x6b\xe9\xd8\x2c\x29\x3f"
+                       "\x96\xfb\xb6\xcd\x13\x91\x3b\xc2"
+                       "\xd2\xa3\x31\x8d\xa4\xcd\x57\xcd"
+                       "\x13\x3d\x64\xfd\x06\xce\xe6\xdc"
+                       "\x0c\x24\x43\x31\x40\x57\xf1\x72"
+                       "\x17\xe3\x3a\x63\x6d\x35\xcf\x5d"
+                       "\x97\x40\x59\xdd\xf7\x3c\x02\xf7"
+                       "\x1c\x7e\x05\xbb\xa9\x0d\x01\xb1"
+                       "\x8e\xc0\x30\xa9\x53\x24\xc9\x89"
+                       "\x84\x6d\xaa\xd0\xcd\x91\xc2\x4d"
+                       "\x91\xb0\x89\xe2\xbf\x83\x44\xaa"
+                       "\x28\x72\x23\xa0\xc2\xad\xad\x1c"
+                       "\xfc\x3f\x09\x7a\x0b\xdc\xc5\x1b"
+                       "\x87\x13\xc6\x5b\x59\x8d\xf2\xc8"
+                       "\xaf\xdf\x11\x95",
+               .rlen   = 4100,
+               .np     = 2,
+               .tap    = { 4064, 36 },
+       },
+};
+
+/*
+ * CTS (Cipher Text Stealing) mode tests
+ */
+#define CTS_MODE_ENC_TEST_VECTORS 6
+#define CTS_MODE_DEC_TEST_VECTORS 6
+static struct cipher_testvec cts_mode_enc_tv_template[] = {
+       { /* from rfc3962 */
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .ilen   = 17,
+               .input  = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20",
+               .rlen   = 17,
+               .result = "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4"
+                         "\xd8\xa5\x80\x36\x2d\xa7\xff\x7f"
+                         "\x97",
+       }, {
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .ilen   = 31,
+               .input  = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+                         "\x20\x47\x61\x75\x27\x73\x20",
+               .rlen   = 31,
+               .result = "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1"
+                         "\xd4\x45\xd4\xc8\xef\xf7\xed\x22"
+                         "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5",
+       }, {
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .ilen   = 32,
+               .input  = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+                         "\x20\x47\x61\x75\x27\x73\x20\x43",
+               .rlen   = 32,
+               .result = "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
+                         "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84",
+       }, {
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .ilen   = 47,
+               .input  = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+                         "\x20\x47\x61\x75\x27\x73\x20\x43"
+                         "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
+                         "\x70\x6c\x65\x61\x73\x65\x2c",
+               .rlen   = 47,
+               .result = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+                         "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c"
+                         "\x1b\x55\x49\xd2\xf8\x38\x02\x9e"
+                         "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5",
+       }, {
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .ilen   = 48,
+               .input  = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+                         "\x20\x47\x61\x75\x27\x73\x20\x43"
+                         "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
+                         "\x70\x6c\x65\x61\x73\x65\x2c\x20",
+               .rlen   = 48,
+               .result = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+                         "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0"
+                         "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8"
+                         "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8",
+       }, {
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .ilen   = 64,
+               .input  = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+                         "\x20\x47\x61\x75\x27\x73\x20\x43"
+                         "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
+                         "\x70\x6c\x65\x61\x73\x65\x2c\x20"
+                         "\x61\x6e\x64\x20\x77\x6f\x6e\x74"
+                         "\x6f\x6e\x20\x73\x6f\x75\x70\x2e",
+               .rlen   = 64,
+               .result = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+                         "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
+                         "\x48\x07\xef\xe8\x36\xee\x89\xa5"
+                         "\x26\x73\x0d\xbc\x2f\x7b\xc8\x40"
+                         "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0"
+                         "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8",
+       }
+};
+
+static struct cipher_testvec cts_mode_dec_tv_template[] = {
+       { /* from rfc3962 */
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .rlen   = 17,
+               .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20",
+               .ilen   = 17,
+               .input  = "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4"
+                         "\xd8\xa5\x80\x36\x2d\xa7\xff\x7f"
+                         "\x97",
+       }, {
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .rlen   = 31,
+               .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+                         "\x20\x47\x61\x75\x27\x73\x20",
+               .ilen   = 31,
+               .input  = "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1"
+                         "\xd4\x45\xd4\xc8\xef\xf7\xed\x22"
+                         "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5",
+       }, {
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .rlen   = 32,
+               .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+                         "\x20\x47\x61\x75\x27\x73\x20\x43",
+               .ilen   = 32,
+               .input  = "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
+                         "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84",
+       }, {
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .rlen   = 47,
+               .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+                         "\x20\x47\x61\x75\x27\x73\x20\x43"
+                         "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
+                         "\x70\x6c\x65\x61\x73\x65\x2c",
+               .ilen   = 47,
+               .input  = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+                         "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c"
+                         "\x1b\x55\x49\xd2\xf8\x38\x02\x9e"
+                         "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5",
+       }, {
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .rlen   = 48,
+               .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+                         "\x20\x47\x61\x75\x27\x73\x20\x43"
+                         "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
+                         "\x70\x6c\x65\x61\x73\x65\x2c\x20",
+               .ilen   = 48,
+               .input  = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+                         "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0"
+                         "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8"
+                         "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8",
+       }, {
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .rlen   = 64,
+               .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+                         "\x20\x47\x61\x75\x27\x73\x20\x43"
+                         "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
+                         "\x70\x6c\x65\x61\x73\x65\x2c\x20"
+                         "\x61\x6e\x64\x20\x77\x6f\x6e\x74"
+                         "\x6f\x6e\x20\x73\x6f\x75\x70\x2e",
+               .ilen   = 64,
+               .input  = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+                         "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
+                         "\x48\x07\xef\xe8\x36\xee\x89\xa5"
+                         "\x26\x73\x0d\xbc\x2f\x7b\xc8\x40"
+                         "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0"
+                         "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8",
+       }
+};
+
+/*
+ * Compression stuff.
+ */
+#define COMP_BUF_SIZE           512
+
+struct comp_testvec {
+       int inlen, outlen;
+       char input[COMP_BUF_SIZE];
+       char output[COMP_BUF_SIZE];
+};
+
+struct pcomp_testvec {
+       void *params;
+       unsigned int paramsize;
+       int inlen, outlen;
+       char input[COMP_BUF_SIZE];
+       char output[COMP_BUF_SIZE];
+};
+
+/*
+ * Deflate test vectors (null-terminated strings).
+ * Params: winbits=-11, Z_DEFAULT_COMPRESSION, MAX_MEM_LEVEL.
+ */
+
+#define DEFLATE_COMP_TEST_VECTORS 2
+#define DEFLATE_DECOMP_TEST_VECTORS 2
+
+static struct comp_testvec deflate_comp_tv_template[] = {
+       {
+               .inlen  = 70,
+               .outlen = 38,
+               .input  = "Join us now and share the software "
+                       "Join us now and share the software ",
+               .output = "\xf3\xca\xcf\xcc\x53\x28\x2d\x56"
+                         "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51"
+                         "\x28\xce\x48\x2c\x4a\x55\x28\xc9"
+                         "\x48\x55\x28\xce\x4f\x2b\x29\x07"
+                         "\x71\xbc\x08\x2b\x01\x00",
+       }, {
+               .inlen  = 191,
+               .outlen = 122,
+               .input  = "This document describes a compression method based on the DEFLATE"
+                       "compression algorithm.  This document defines the application of "
+                       "the DEFLATE algorithm to the IP Payload Compression Protocol.",
+               .output = "\x5d\x8d\x31\x0e\xc2\x30\x10\x04"
+                         "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09"
+                         "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8"
+                         "\x24\xdb\x67\xd9\x47\xc1\xef\x49"
+                         "\x68\x12\x51\xae\x76\x67\xd6\x27"
+                         "\x19\x88\x1a\xde\x85\xab\x21\xf2"
+                         "\x08\x5d\x16\x1e\x20\x04\x2d\xad"
+                         "\xf3\x18\xa2\x15\x85\x2d\x69\xc4"
+                         "\x42\x83\x23\xb6\x6c\x89\x71\x9b"
+                         "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f"
+                         "\xed\x62\xa9\x4c\x80\xff\x13\xaf"
+                         "\x52\x37\xed\x0e\x52\x6b\x59\x02"
+                         "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98"
+                         "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a"
+                         "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79"
+                         "\xfa\x02",
+       },
+};
+
+static struct comp_testvec deflate_decomp_tv_template[] = {
+       {
+               .inlen  = 122,
+               .outlen = 191,
+               .input  = "\x5d\x8d\x31\x0e\xc2\x30\x10\x04"
+                         "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09"
+                         "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8"
+                         "\x24\xdb\x67\xd9\x47\xc1\xef\x49"
+                         "\x68\x12\x51\xae\x76\x67\xd6\x27"
+                         "\x19\x88\x1a\xde\x85\xab\x21\xf2"
+                         "\x08\x5d\x16\x1e\x20\x04\x2d\xad"
+                         "\xf3\x18\xa2\x15\x85\x2d\x69\xc4"
+                         "\x42\x83\x23\xb6\x6c\x89\x71\x9b"
+                         "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f"
+                         "\xed\x62\xa9\x4c\x80\xff\x13\xaf"
+                         "\x52\x37\xed\x0e\x52\x6b\x59\x02"
+                         "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98"
+                         "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a"
+                         "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79"
+                         "\xfa\x02",
+               .output = "This document describes a compression method based on the DEFLATE"
+                       "compression algorithm.  This document defines the application of "
+                       "the DEFLATE algorithm to the IP Payload Compression Protocol.",
+       }, {
+               .inlen  = 38,
+               .outlen = 70,
+               .input  = "\xf3\xca\xcf\xcc\x53\x28\x2d\x56"
+                         "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51"
+                         "\x28\xce\x48\x2c\x4a\x55\x28\xc9"
+                         "\x48\x55\x28\xce\x4f\x2b\x29\x07"
+                         "\x71\xbc\x08\x2b\x01\x00",
+               .output = "Join us now and share the software "
+                       "Join us now and share the software ",
+       },
+};
+
+#define ZLIB_COMP_TEST_VECTORS 2
+#define ZLIB_DECOMP_TEST_VECTORS 2
+
+static const struct {
+       struct nlattr nla;
+       int val;
+} deflate_comp_params[] = {
+       {
+               .nla = {
+                       .nla_len        = NLA_HDRLEN + sizeof(int),
+                       .nla_type       = ZLIB_COMP_LEVEL,
+               },
+               .val                    = Z_DEFAULT_COMPRESSION,
+       }, {
+               .nla = {
+                       .nla_len        = NLA_HDRLEN + sizeof(int),
+                       .nla_type       = ZLIB_COMP_METHOD,
+               },
+               .val                    = Z_DEFLATED,
+       }, {
+               .nla = {
+                       .nla_len        = NLA_HDRLEN + sizeof(int),
+                       .nla_type       = ZLIB_COMP_WINDOWBITS,
+               },
+               .val                    = -11,
+       }, {
+               .nla = {
+                       .nla_len        = NLA_HDRLEN + sizeof(int),
+                       .nla_type       = ZLIB_COMP_MEMLEVEL,
+               },
+               .val                    = MAX_MEM_LEVEL,
+       }, {
+               .nla = {
+                       .nla_len        = NLA_HDRLEN + sizeof(int),
+                       .nla_type       = ZLIB_COMP_STRATEGY,
+               },
+               .val                    = Z_DEFAULT_STRATEGY,
+       }
+};
+
+static const struct {
+       struct nlattr nla;
+       int val;
+} deflate_decomp_params[] = {
+       {
+               .nla = {
+                       .nla_len        = NLA_HDRLEN + sizeof(int),
+                       .nla_type       = ZLIB_DECOMP_WINDOWBITS,
+               },
+               .val                    = -11,
+       }
+};
+
+static struct pcomp_testvec zlib_comp_tv_template[] = {
+       {
+               .params = &deflate_comp_params,
+               .paramsize = sizeof(deflate_comp_params),
+               .inlen  = 70,
+               .outlen = 38,
+               .input  = "Join us now and share the software "
+                       "Join us now and share the software ",
+               .output = "\xf3\xca\xcf\xcc\x53\x28\x2d\x56"
+                         "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51"
+                         "\x28\xce\x48\x2c\x4a\x55\x28\xc9"
+                         "\x48\x55\x28\xce\x4f\x2b\x29\x07"
+                         "\x71\xbc\x08\x2b\x01\x00",
+       }, {
+               .params = &deflate_comp_params,
+               .paramsize = sizeof(deflate_comp_params),
+               .inlen  = 191,
+               .outlen = 122,
+               .input  = "This document describes a compression method based on the DEFLATE"
+                       "compression algorithm.  This document defines the application of "
+                       "the DEFLATE algorithm to the IP Payload Compression Protocol.",
+               .output = "\x5d\x8d\x31\x0e\xc2\x30\x10\x04"
+                         "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09"
+                         "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8"
+                         "\x24\xdb\x67\xd9\x47\xc1\xef\x49"
+                         "\x68\x12\x51\xae\x76\x67\xd6\x27"
+                         "\x19\x88\x1a\xde\x85\xab\x21\xf2"
+                         "\x08\x5d\x16\x1e\x20\x04\x2d\xad"
+                         "\xf3\x18\xa2\x15\x85\x2d\x69\xc4"
+                         "\x42\x83\x23\xb6\x6c\x89\x71\x9b"
+                         "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f"
+                         "\xed\x62\xa9\x4c\x80\xff\x13\xaf"
+                         "\x52\x37\xed\x0e\x52\x6b\x59\x02"
+                         "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98"
+                         "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a"
+                         "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79"
+                         "\xfa\x02",
+       },
+};
+
+static struct pcomp_testvec zlib_decomp_tv_template[] = {
+       {
+               .params = &deflate_decomp_params,
+               .paramsize = sizeof(deflate_decomp_params),
+               .inlen  = 122,
+               .outlen = 191,
+               .input  = "\x5d\x8d\x31\x0e\xc2\x30\x10\x04"
+                         "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09"
+                         "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8"
+                         "\x24\xdb\x67\xd9\x47\xc1\xef\x49"
+                         "\x68\x12\x51\xae\x76\x67\xd6\x27"
+                         "\x19\x88\x1a\xde\x85\xab\x21\xf2"
+                         "\x08\x5d\x16\x1e\x20\x04\x2d\xad"
+                         "\xf3\x18\xa2\x15\x85\x2d\x69\xc4"
+                         "\x42\x83\x23\xb6\x6c\x89\x71\x9b"
+                         "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f"
+                         "\xed\x62\xa9\x4c\x80\xff\x13\xaf"
+                         "\x52\x37\xed\x0e\x52\x6b\x59\x02"
+                         "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98"
+                         "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a"
+                         "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79"
+                         "\xfa\x02",
+               .output = "This document describes a compression method based on the DEFLATE"
+                       "compression algorithm.  This document defines the application of "
+                       "the DEFLATE algorithm to the IP Payload Compression Protocol.",
+       }, {
+               .params = &deflate_decomp_params,
+               .paramsize = sizeof(deflate_decomp_params),
+               .inlen  = 38,
+               .outlen = 70,
+               .input  = "\xf3\xca\xcf\xcc\x53\x28\x2d\x56"
+                         "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51"
+                         "\x28\xce\x48\x2c\x4a\x55\x28\xc9"
+                         "\x48\x55\x28\xce\x4f\x2b\x29\x07"
+                         "\x71\xbc\x08\x2b\x01\x00",
+               .output = "Join us now and share the software "
+                       "Join us now and share the software ",
+       },
+};
+
+/*
+ * LZO test vectors (null-terminated strings).
+ */
+#define LZO_COMP_TEST_VECTORS 2
+#define LZO_DECOMP_TEST_VECTORS 2
+
+static struct comp_testvec lzo_comp_tv_template[] = {
+       {
+               .inlen  = 70,
+               .outlen = 46,
+               .input  = "Join us now and share the software "
+                       "Join us now and share the software ",
+               .output = "\x00\x0d\x4a\x6f\x69\x6e\x20\x75"
+                       "\x73\x20\x6e\x6f\x77\x20\x61\x6e"
+                       "\x64\x20\x73\x68\x61\x72\x65\x20"
+                       "\x74\x68\x65\x20\x73\x6f\x66\x74"
+                       "\x77\x70\x01\x01\x4a\x6f\x69\x6e"
+                       "\x3d\x88\x00\x11\x00\x00",
+       }, {
+               .inlen  = 159,
+               .outlen = 133,
+               .input  = "This document describes a compression method based on the LZO "
+                       "compression algorithm.  This document defines the application of "
+                       "the LZO algorithm used in UBIFS.",
+               .output = "\x00\x2b\x54\x68\x69\x73\x20\x64"
+                         "\x6f\x63\x75\x6d\x65\x6e\x74\x20"
+                         "\x64\x65\x73\x63\x72\x69\x62\x65"
+                         "\x73\x20\x61\x20\x63\x6f\x6d\x70"
+                         "\x72\x65\x73\x73\x69\x6f\x6e\x20"
+                         "\x6d\x65\x74\x68\x6f\x64\x20\x62"
+                         "\x61\x73\x65\x64\x20\x6f\x6e\x20"
+                         "\x74\x68\x65\x20\x4c\x5a\x4f\x2b"
+                         "\x8c\x00\x0d\x61\x6c\x67\x6f\x72"
+                         "\x69\x74\x68\x6d\x2e\x20\x20\x54"
+                         "\x68\x69\x73\x2a\x54\x01\x02\x66"
+                         "\x69\x6e\x65\x73\x94\x06\x05\x61"
+                         "\x70\x70\x6c\x69\x63\x61\x74\x76"
+                         "\x0a\x6f\x66\x88\x02\x60\x09\x27"
+                         "\xf0\x00\x0c\x20\x75\x73\x65\x64"
+                         "\x20\x69\x6e\x20\x55\x42\x49\x46"
+                         "\x53\x2e\x11\x00\x00",
+       },
+};
+
+static struct comp_testvec lzo_decomp_tv_template[] = {
+       {
+               .inlen  = 133,
+               .outlen = 159,
+               .input  = "\x00\x2b\x54\x68\x69\x73\x20\x64"
+                         "\x6f\x63\x75\x6d\x65\x6e\x74\x20"
+                         "\x64\x65\x73\x63\x72\x69\x62\x65"
+                         "\x73\x20\x61\x20\x63\x6f\x6d\x70"
+                         "\x72\x65\x73\x73\x69\x6f\x6e\x20"
+                         "\x6d\x65\x74\x68\x6f\x64\x20\x62"
+                         "\x61\x73\x65\x64\x20\x6f\x6e\x20"
+                         "\x74\x68\x65\x20\x4c\x5a\x4f\x2b"
+                         "\x8c\x00\x0d\x61\x6c\x67\x6f\x72"
+                         "\x69\x74\x68\x6d\x2e\x20\x20\x54"
+                         "\x68\x69\x73\x2a\x54\x01\x02\x66"
+                         "\x69\x6e\x65\x73\x94\x06\x05\x61"
+                         "\x70\x70\x6c\x69\x63\x61\x74\x76"
+                         "\x0a\x6f\x66\x88\x02\x60\x09\x27"
+                         "\xf0\x00\x0c\x20\x75\x73\x65\x64"
+                         "\x20\x69\x6e\x20\x55\x42\x49\x46"
+                         "\x53\x2e\x11\x00\x00",
+               .output = "This document describes a compression method based on the LZO "
+                       "compression algorithm.  This document defines the application of "
+                       "the LZO algorithm used in UBIFS.",
+       }, {
+               .inlen  = 46,
+               .outlen = 70,
+               .input  = "\x00\x0d\x4a\x6f\x69\x6e\x20\x75"
+                         "\x73\x20\x6e\x6f\x77\x20\x61\x6e"
+                         "\x64\x20\x73\x68\x61\x72\x65\x20"
+                         "\x74\x68\x65\x20\x73\x6f\x66\x74"
+                         "\x77\x70\x01\x01\x4a\x6f\x69\x6e"
+                         "\x3d\x88\x00\x11\x00\x00",
+               .output = "Join us now and share the software "
+                       "Join us now and share the software ",
+       },
+};
+
+/*
+ * Michael MIC test vectors from IEEE 802.11i
+ */
+#define MICHAEL_MIC_TEST_VECTORS 6
+
+static struct hash_testvec michael_mic_tv_template[] = {
+       {
+               .key = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ksize = 8,
+               .plaintext = zeroed_string,
+               .psize = 0,
+               .digest = "\x82\x92\x5c\x1c\xa1\xd1\x30\xb8",
+       },
+       {
+               .key = "\x82\x92\x5c\x1c\xa1\xd1\x30\xb8",
+               .ksize = 8,
+               .plaintext = "M",
+               .psize = 1,
+               .digest = "\x43\x47\x21\xca\x40\x63\x9b\x3f",
+       },
+       {
+               .key = "\x43\x47\x21\xca\x40\x63\x9b\x3f",
+               .ksize = 8,
+               .plaintext = "Mi",
+               .psize = 2,
+               .digest = "\xe8\xf9\xbe\xca\xe9\x7e\x5d\x29",
+       },
+       {
+               .key = "\xe8\xf9\xbe\xca\xe9\x7e\x5d\x29",
+               .ksize = 8,
+               .plaintext = "Mic",
+               .psize = 3,
+               .digest = "\x90\x03\x8f\xc6\xcf\x13\xc1\xdb",
+       },
+       {
+               .key = "\x90\x03\x8f\xc6\xcf\x13\xc1\xdb",
+               .ksize = 8,
+               .plaintext = "Mich",
+               .psize = 4,
+               .digest = "\xd5\x5e\x10\x05\x10\x12\x89\x86",
+       },
+       {
+               .key = "\xd5\x5e\x10\x05\x10\x12\x89\x86",
+               .ksize = 8,
+               .plaintext = "Michael",
+               .psize = 7,
+               .digest = "\x0a\x94\x2b\x12\x4e\xca\xa5\x46",
+       }
+};
+
+/*
+ * CRC32C test vectors
+ */
+#define CRC32C_TEST_VECTORS 14
+
+static struct hash_testvec crc32c_tv_template[] = {
+       {
+               .psize = 0,
+               .digest = "\x00\x00\x00\x00",
+       },
+       {
+               .key = "\x87\xa9\xcb\xed",
+               .ksize = 4,
+               .psize = 0,
+               .digest = "\x78\x56\x34\x12",
+       },
+       {
+               .key = "\xff\xff\xff\xff",
+               .ksize = 4,
+               .plaintext = "\x01\x02\x03\x04\x05\x06\x07\x08"
+                            "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+                            "\x11\x12\x13\x14\x15\x16\x17\x18"
+                            "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
+                            "\x21\x22\x23\x24\x25\x26\x27\x28",
+               .psize = 40,
+               .digest = "\x7f\x15\x2c\x0e",
+       },
+       {
+               .key = "\xff\xff\xff\xff",
+               .ksize = 4,
+               .plaintext = "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
+                            "\x31\x32\x33\x34\x35\x36\x37\x38"
+                            "\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
+                            "\x41\x42\x43\x44\x45\x46\x47\x48"
+                            "\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50",
+               .psize = 40,
+               .digest = "\xf6\xeb\x80\xe9",
+       },
+       {
+               .key = "\xff\xff\xff\xff",
+               .ksize = 4,
+               .plaintext = "\x51\x52\x53\x54\x55\x56\x57\x58"
+                            "\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
+                            "\x61\x62\x63\x64\x65\x66\x67\x68"
+                            "\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+                            "\x71\x72\x73\x74\x75\x76\x77\x78",
+               .psize = 40,
+               .digest = "\xed\xbd\x74\xde",
+       },
+       {
+               .key = "\xff\xff\xff\xff",
+               .ksize = 4,
+               .plaintext = "\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
+                            "\x81\x82\x83\x84\x85\x86\x87\x88"
+                            "\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
+                            "\x91\x92\x93\x94\x95\x96\x97\x98"
+                            "\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0",
+               .psize = 40,
+               .digest = "\x62\xc8\x79\xd5",
+       },
+       {
+               .key = "\xff\xff\xff\xff",
+               .ksize = 4,
+               .plaintext = "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
+                            "\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
+                            "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
+                            "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
+                            "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8",
+               .psize = 40,
+               .digest = "\xd0\x9a\x97\xba",
+       },
+       {
+               .key = "\xff\xff\xff\xff",
+               .ksize = 4,
+               .plaintext = "\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
+                            "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
+                            "\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
+                            "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8"
+                            "\xe9\xea\xeb\xec\xed\xee\xef\xf0",
+               .psize = 40,
+               .digest = "\x13\xd9\x29\x2b",
+       },
+       {
+               .key = "\x80\xea\xd3\xf1",
+               .ksize = 4,
+               .plaintext = "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
+                            "\x31\x32\x33\x34\x35\x36\x37\x38"
+                            "\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
+                            "\x41\x42\x43\x44\x45\x46\x47\x48"
+                            "\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50",
+               .psize = 40,
+               .digest = "\x0c\xb5\xe2\xa2",
+       },
+       {
+               .key = "\xf3\x4a\x1d\x5d",
+               .ksize = 4,
+               .plaintext = "\x51\x52\x53\x54\x55\x56\x57\x58"
+                            "\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
+                            "\x61\x62\x63\x64\x65\x66\x67\x68"
+                            "\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+                            "\x71\x72\x73\x74\x75\x76\x77\x78",
+               .psize = 40,
+               .digest = "\xd1\x7f\xfb\xa6",
+       },
+       {
+               .key = "\x2e\x80\x04\x59",
+               .ksize = 4,
+               .plaintext = "\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
+                            "\x81\x82\x83\x84\x85\x86\x87\x88"
+                            "\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
+                            "\x91\x92\x93\x94\x95\x96\x97\x98"
+                            "\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0",
+               .psize = 40,
+               .digest = "\x59\x33\xe6\x7a",
+       },
+       {
+               .key = "\xa6\xcc\x19\x85",
+               .ksize = 4,
+               .plaintext = "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
+                            "\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
+                            "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
+                            "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
+                            "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8",
+               .psize = 40,
+               .digest = "\xbe\x03\x01\xd2",
+       },
+       {
+               .key = "\x41\xfc\xfe\x2d",
+               .ksize = 4,
+               .plaintext = "\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
+                            "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
+                            "\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
+                            "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8"
+                            "\xe9\xea\xeb\xec\xed\xee\xef\xf0",
+               .psize = 40,
+               .digest = "\x75\xd3\xc5\x24",
+       },
+       {
+               .key = "\xff\xff\xff\xff",
+               .ksize = 4,
+               .plaintext = "\x01\x02\x03\x04\x05\x06\x07\x08"
+                            "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+                            "\x11\x12\x13\x14\x15\x16\x17\x18"
+                            "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
+                            "\x21\x22\x23\x24\x25\x26\x27\x28"
+                            "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
+                            "\x31\x32\x33\x34\x35\x36\x37\x38"
+                            "\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
+                            "\x41\x42\x43\x44\x45\x46\x47\x48"
+                            "\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
+                            "\x51\x52\x53\x54\x55\x56\x57\x58"
+                            "\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
+                            "\x61\x62\x63\x64\x65\x66\x67\x68"
+                            "\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+                            "\x71\x72\x73\x74\x75\x76\x77\x78"
+                            "\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
+                            "\x81\x82\x83\x84\x85\x86\x87\x88"
+                            "\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
+                            "\x91\x92\x93\x94\x95\x96\x97\x98"
+                            "\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0"
+                            "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
+                            "\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
+                            "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
+                            "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
+                            "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8"
+                            "\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
+                            "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
+                            "\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
+                            "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8"
+                            "\xe9\xea\xeb\xec\xed\xee\xef\xf0",
+               .psize = 240,
+               .digest = "\x75\xd3\xc5\x24",
+               .np = 2,
+               .tap = { 31, 209 }
+       },
+};
+
+#endif /* _IFXMIPS_CRYPTO_TESTMGR_H */
diff --git a/package/platform/lantiq/ltq-deu/src/internal.h b/package/platform/lantiq/ltq-deu/src/internal.h
new file mode 100644 (file)
index 0000000..2d22636
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Cryptographic API.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
+ *
+ * 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.
+ *
+ */
+#ifndef _CRYPTO_INTERNAL_H
+#define _CRYPTO_INTERNAL_H
+
+#include <crypto/algapi.h>
+#include <linux/completion.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/notifier.h>
+#include <linux/rwsem.h>
+#include <linux/slab.h>
+#include <linux/fips.h>
+
+/* Crypto notification events. */
+enum {
+       CRYPTO_MSG_ALG_REQUEST,
+       CRYPTO_MSG_ALG_REGISTER,
+       CRYPTO_MSG_ALG_UNREGISTER,
+       CRYPTO_MSG_TMPL_REGISTER,
+       CRYPTO_MSG_TMPL_UNREGISTER,
+};
+
+struct crypto_instance;
+struct crypto_template;
+
+struct crypto_larval {
+       struct crypto_alg alg;
+       struct crypto_alg *adult;
+       struct completion completion;
+       u32 mask;
+};
+
+extern struct list_head crypto_alg_list;
+extern struct rw_semaphore crypto_alg_sem;
+extern struct blocking_notifier_head crypto_chain;
+
+#ifdef CONFIG_PROC_FS
+void __init crypto_init_proc(void);
+void __exit crypto_exit_proc(void);
+#else
+static inline void crypto_init_proc(void)
+{ }
+static inline void crypto_exit_proc(void)
+{ }
+#endif
+
+static inline unsigned int crypto_cipher_ctxsize(struct crypto_alg *alg)
+{
+       return alg->cra_ctxsize;
+}
+
+static inline unsigned int crypto_compress_ctxsize(struct crypto_alg *alg)
+{
+       return alg->cra_ctxsize;
+}
+
+struct crypto_alg *crypto_mod_get(struct crypto_alg *alg);
+struct crypto_alg *crypto_alg_lookup(const char *name, u32 type, u32 mask);
+struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask);
+
+int crypto_init_cipher_ops(struct crypto_tfm *tfm);
+int crypto_init_compress_ops(struct crypto_tfm *tfm);
+
+void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
+void crypto_exit_compress_ops(struct crypto_tfm *tfm);
+
+struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask);
+void crypto_larval_kill(struct crypto_alg *alg);
+struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask);
+void crypto_larval_error(const char *name, u32 type, u32 mask);
+void crypto_alg_tested(const char *name, int err);
+
+void crypto_shoot_alg(struct crypto_alg *alg);
+struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type,
+                                     u32 mask);
+void *crypto_create_tfm(struct crypto_alg *alg,
+                       const struct crypto_type *frontend);
+struct crypto_alg *crypto_find_alg(const char *alg_name,
+                                  const struct crypto_type *frontend,
+                                  u32 type, u32 mask);
+void *crypto_alloc_tfm(const char *alg_name,
+                      const struct crypto_type *frontend, u32 type, u32 mask);
+
+int crypto_register_notifier(struct notifier_block *nb);
+int crypto_unregister_notifier(struct notifier_block *nb);
+int crypto_probing_notify(unsigned long val, void *v);
+
+static inline void crypto_alg_put(struct crypto_alg *alg)
+{
+       if (atomic_dec_and_test(&alg->cra_refcnt) && alg->cra_destroy)
+               alg->cra_destroy(alg);
+}
+
+static inline int crypto_tmpl_get(struct crypto_template *tmpl)
+{
+       return try_module_get(tmpl->module);
+}
+
+static inline void crypto_tmpl_put(struct crypto_template *tmpl)
+{
+       module_put(tmpl->module);
+}
+
+static inline int crypto_is_larval(struct crypto_alg *alg)
+{
+       return alg->cra_flags & CRYPTO_ALG_LARVAL;
+}
+
+static inline int crypto_is_dead(struct crypto_alg *alg)
+{
+       return alg->cra_flags & CRYPTO_ALG_DEAD;
+}
+
+static inline int crypto_is_moribund(struct crypto_alg *alg)
+{
+       return alg->cra_flags & (CRYPTO_ALG_DEAD | CRYPTO_ALG_DYING);
+}
+
+static inline void crypto_notify(unsigned long val, void *v)
+{
+       blocking_notifier_call_chain(&crypto_chain, val, v);
+}
+
+#endif /* _CRYPTO_INTERNAL_H */
+
diff --git a/package/platform/lantiq/ltq-deu/src/ltq_deu_testmgr.c b/package/platform/lantiq/ltq-deu/src/ltq_deu_testmgr.c
new file mode 100644 (file)
index 0000000..f1b5752
--- /dev/null
@@ -0,0 +1,3957 @@
+/*
+ * Algorithm testing framework and tests.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
+ * Copyright (c) 2007 Nokia Siemens Networks
+ * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
+ *
+ * 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.
+ *
+ */
+
+#include <crypto/hash.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <crypto/rng.h>
+#include <linux/jiffies.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+
+#include "internal.h"
+#include "ifxmips_testmgr.h"
+#include "ifxmips_tcrypt.h"
+#include "ifxmips_deu.h"
+
+/* changes for LQ ablkcipher speedtest */
+#include <linux/timex.h>
+#include <linux/interrupt.h>
+#include <asm/mipsregs.h>
+
+/*
+ * Need slab memory for testing (size in number of pages).
+ */
+#define XBUFSIZE       8
+
+/*
+ * Indexes into the xbuf to simulate cross-page access.
+ */
+#define IDX1           32
+#define IDX2           32400
+#define IDX3           1
+#define IDX4           8193
+#define IDX5           22222
+#define IDX6           17101
+#define IDX7           27333
+#define IDX8           3000
+
+/*
+* Used by test_cipher()
+*/
+#define ENCRYPT 1
+#define DECRYPT 0
+
+/*
+ * Need slab memory for testing (size in number of pages).
+ */
+#define TVMEMSIZE      4
+
+/*
+* Used by test_cipher_speed()
+*/
+#define ENCRYPT 1
+#define DECRYPT 0
+
+/*
+ * Used by test_cipher_speed()
+ */
+
+
+static unsigned int sec;
+
+static char *alg = NULL;
+static u32 type;
+static u32 mask;
+static int mode;
+static char *tvmem[TVMEMSIZE];
+
+static char *check[] = {
+       "des", "md5", "des3_ede", "rot13", "sha1", "sha224", "sha256",
+       "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes",
+       "cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea",
+       "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta",  "fcrypt",
+       "camellia", "seed", "salsa20", "rmd128", "rmd160", "rmd256", "rmd320",
+       "lzo", "cts", "zlib", NULL
+};
+struct tcrypt_result {
+       struct completion completion;
+       int err;
+};
+
+struct aead_test_suite {
+       struct {
+               struct aead_testvec *vecs;
+               unsigned int count;
+       } enc, dec;
+};
+
+struct cipher_test_suite {
+       struct {
+               struct cipher_testvec *vecs;
+               unsigned int count;
+       } enc, dec;
+};
+
+struct comp_test_suite {
+       struct {
+               struct comp_testvec *vecs;
+               unsigned int count;
+       } comp, decomp;
+};
+
+struct pcomp_test_suite {
+       struct {
+               struct pcomp_testvec *vecs;
+               unsigned int count;
+       } comp, decomp;
+};
+
+struct hash_test_suite {
+       struct hash_testvec *vecs;
+       unsigned int count;
+};
+
+struct cprng_test_suite {
+       struct cprng_testvec *vecs;
+       unsigned int count;
+};
+
+struct alg_test_desc {
+       const char *alg;
+       int (*test)(const struct alg_test_desc *desc, const char *driver,
+                   u32 type, u32 mask);
+       int fips_allowed;       /* set if alg is allowed in fips mode */
+
+       union {
+               struct aead_test_suite aead;
+               struct cipher_test_suite cipher;
+               struct comp_test_suite comp;
+               struct pcomp_test_suite pcomp;
+               struct hash_test_suite hash;
+               struct cprng_test_suite cprng;
+       } suite;
+};
+
+static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 };
+
+static void hexdump(unsigned char *buf, unsigned int len)
+{
+       print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
+                       16, 1,
+                       buf, len, false);
+}
+
+static void tcrypt_complete(struct crypto_async_request *req, int err)
+{
+       struct tcrypt_result *res = req->data;
+        
+        //printk("Signal done test\n");
+
+       if (err == -EINPROGRESS) {
+                printk("********************* Completion didnt go too well **************************** \n");
+               return;
+        }
+
+       res->err = err;
+       complete_all(&res->completion);
+}
+
+static int testmgr_alloc_buf(char *buf[XBUFSIZE])
+{
+       int i;
+
+       for (i = 0; i < XBUFSIZE; i++) {
+               buf[i] = (void *)__get_free_page(GFP_KERNEL);
+               if (!buf[i])
+                       goto err_free_buf;
+       }
+
+       return 0;
+
+err_free_buf:
+       while (i-- > 0)
+               free_page((unsigned long)buf[i]);
+
+       return -ENOMEM;
+}
+
+static void testmgr_free_buf(char *buf[XBUFSIZE])
+{
+       int i;
+
+       for (i = 0; i < XBUFSIZE; i++)
+               free_page((unsigned long)buf[i]);
+}
+
+static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
+                    unsigned int tcount)
+{
+       const char *algo = crypto_tfm_alg_driver_name(crypto_ahash_tfm(tfm));
+       unsigned int i, j, k, temp;
+       struct scatterlist sg[8];
+       char result[64];
+       struct ahash_request *req;
+       struct tcrypt_result tresult;
+       void *hash_buff;
+       char *xbuf[XBUFSIZE];
+       int ret = -ENOMEM;
+
+       if (testmgr_alloc_buf(xbuf))
+               goto out_nobuf;
+
+       init_completion(&tresult.completion);
+
+       req = ahash_request_alloc(tfm, GFP_KERNEL);
+       if (!req) {
+               printk(KERN_ERR "alg: hash: Failed to allocate request for "
+                      "%s\n", algo);
+               goto out_noreq;
+       }
+       ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+                                  tcrypt_complete, &tresult);
+
+       j = 0;
+       for (i = 0; i < tcount; i++) {
+               if (template[i].np)
+                       continue;
+
+               j++;
+               memset(result, 0, 64);
+
+               hash_buff = xbuf[0];
+
+               memcpy(hash_buff, template[i].plaintext, template[i].psize);
+               sg_init_one(&sg[0], hash_buff, template[i].psize);
+
+               if (template[i].ksize) {
+                       crypto_ahash_clear_flags(tfm, ~0);
+                       ret = crypto_ahash_setkey(tfm, template[i].key,
+                                                 template[i].ksize);
+                       if (ret) {
+                               printk(KERN_ERR "alg: hash: setkey failed on "
+                                      "test %d for %s: ret=%d\n", j, algo,
+                                      -ret);
+                               goto out;
+                       }
+               }
+
+               ahash_request_set_crypt(req, sg, result, template[i].psize);
+               ret = crypto_ahash_digest(req);
+               switch (ret) {
+               case 0:
+                       break;
+               case -EINPROGRESS:
+               case -EBUSY:
+                       ret = wait_for_completion_interruptible(
+                               &tresult.completion);
+                       if (!ret && !(ret = tresult.err)) {
+                               INIT_COMPLETION(tresult.completion);
+                               break;
+                       }
+                       /* fall through */
+               default:
+                       printk(KERN_ERR "alg: hash: digest failed on test %d "
+                              "for %s: ret=%d\n", j, algo, -ret);
+                       goto out;
+               }
+
+               if (memcmp(result, template[i].digest,
+                          crypto_ahash_digestsize(tfm))) {
+                       printk(KERN_ERR "alg: hash: Test %d failed for %s\n",
+                              j, algo);
+                       hexdump(result, crypto_ahash_digestsize(tfm));
+                       ret = -EINVAL;
+                       goto out;
+               }
+               else {
+                       printk(KERN_ERR "alg: hash: Test %d passed for %s\n",
+                              j, algo);
+                       hexdump(result, crypto_ahash_digestsize(tfm));
+               }
+       }
+
+       j = 0;
+       for (i = 0; i < tcount; i++) {
+               if (template[i].np) {
+                       j++;
+                       memset(result, 0, 64);
+
+                       temp = 0;
+                       sg_init_table(sg, template[i].np);
+                       ret = -EINVAL;
+                       for (k = 0; k < template[i].np; k++) {
+                               if (WARN_ON(offset_in_page(IDX[k]) +
+                                           template[i].tap[k] > PAGE_SIZE))
+                                       goto out;
+                               sg_set_buf(&sg[k],
+                                          memcpy(xbuf[IDX[k] >> PAGE_SHIFT] +
+                                                 offset_in_page(IDX[k]),
+                                                 template[i].plaintext + temp,
+                                                 template[i].tap[k]),
+                                          template[i].tap[k]);
+                               temp += template[i].tap[k];
+                       }
+
+                       if (template[i].ksize) {
+                               crypto_ahash_clear_flags(tfm, ~0);
+                               ret = crypto_ahash_setkey(tfm, template[i].key,
+                                                         template[i].ksize);
+
+                               if (ret) {
+                                       printk(KERN_ERR "alg: hash: setkey "
+                                              "failed on chunking test %d "
+                                              "for %s: ret=%d\n", j, algo,
+                                              -ret);
+                                       goto out;
+                               }
+                       }
+
+                       ahash_request_set_crypt(req, sg, result,
+                                               template[i].psize);
+                       ret = crypto_ahash_digest(req);
+                       switch (ret) {
+                       case 0:
+                               break;
+                       case -EINPROGRESS:
+                       case -EBUSY:
+                               ret = wait_for_completion_interruptible(
+                                       &tresult.completion);
+                               if (!ret && !(ret = tresult.err)) {
+                                       INIT_COMPLETION(tresult.completion);
+                                       break;
+                               }
+                               /* fall through */
+                       default:
+                               printk(KERN_ERR "alg: hash: digest failed "
+                                      "on chunking test %d for %s: "
+                                      "ret=%d\n", j, algo, -ret);
+                               goto out;
+                       }
+
+                       if (memcmp(result, template[i].digest,
+                                  crypto_ahash_digestsize(tfm))) {
+                               printk(KERN_ERR "alg: hash: Chunking test %d "
+                                      "failed for %s\n", j, algo);
+                               hexdump(result, crypto_ahash_digestsize(tfm));
+                               ret = -EINVAL;
+                               goto out;
+                       }
+                       else {
+                               printk(KERN_ERR "alg: hash: Chunking test %d "
+                                      "passed for %s\n", j, algo);
+                               hexdump(result, crypto_ahash_digestsize(tfm));
+                       }
+               }
+       }
+
+       ret = 0;
+
+out:
+       ahash_request_free(req);
+out_noreq:
+       testmgr_free_buf(xbuf);
+out_nobuf:
+       return ret;
+}
+
+static int test_aead(struct crypto_aead *tfm, int enc,
+                    struct aead_testvec *template, unsigned int tcount)
+{
+       const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm));
+       unsigned int i, j, k, n, temp;
+       int ret = -ENOMEM;
+       char *q;
+       char *key;
+       struct aead_request *req;
+       struct scatterlist sg[8];
+       struct scatterlist asg[8];
+       const char *e;
+       struct tcrypt_result result;
+       unsigned int authsize;
+       void *input;
+       void *assoc;
+       char iv[MAX_IVLEN];
+       char *xbuf[XBUFSIZE];
+       char *axbuf[XBUFSIZE];
+
+       if (testmgr_alloc_buf(xbuf))
+               goto out_noxbuf;
+       if (testmgr_alloc_buf(axbuf))
+               goto out_noaxbuf;
+
+       if (enc == ENCRYPT)
+               e = "encryption";
+       else
+               e = "decryption";
+
+       init_completion(&result.completion);
+
+       req = aead_request_alloc(tfm, GFP_KERNEL);
+       if (!req) {
+               printk(KERN_ERR "alg: aead: Failed to allocate request for "
+                      "%s\n", algo);
+               goto out;
+       }
+
+       aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+                                 tcrypt_complete, &result);
+
+       for (i = 0, j = 0; i < tcount; i++) {
+               if (!template[i].np) {
+                       j++;
+
+                       /* some tepmplates have no input data but they will
+                        * touch input
+                        */
+                       input = xbuf[0];
+                       assoc = axbuf[0];
+
+                       ret = -EINVAL;
+                       if (WARN_ON(template[i].ilen > PAGE_SIZE ||
+                                   template[i].alen > PAGE_SIZE))
+                               goto out;
+
+                       memcpy(input, template[i].input, template[i].ilen);
+                       memcpy(assoc, template[i].assoc, template[i].alen);
+                       if (template[i].iv)
+                               memcpy(iv, template[i].iv, MAX_IVLEN);
+                       else
+                               memset(iv, 0, MAX_IVLEN);
+
+                       crypto_aead_clear_flags(tfm, ~0);
+                       if (template[i].wk)
+                               crypto_aead_set_flags(
+                                       tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+
+                       key = template[i].key;
+
+                       ret = crypto_aead_setkey(tfm, key,
+                                                template[i].klen);
+                       if (!ret == template[i].fail) {
+                               printk(KERN_ERR "alg: aead: setkey failed on "
+                                      "test %d for %s: flags=%x\n", j, algo,
+                                      crypto_aead_get_flags(tfm));
+                               goto out;
+                       } else if (ret)
+                               continue;
+
+                       authsize = abs(template[i].rlen - template[i].ilen);
+                       ret = crypto_aead_setauthsize(tfm, authsize);
+                       if (ret) {
+                               printk(KERN_ERR "alg: aead: Failed to set "
+                                      "authsize to %u on test %d for %s\n",
+                                      authsize, j, algo);
+                               goto out;
+                       }
+
+                       sg_init_one(&sg[0], input,
+                                   template[i].ilen + (enc ? authsize : 0));
+
+                       sg_init_one(&asg[0], assoc, template[i].alen);
+
+                       aead_request_set_crypt(req, sg, sg,
+                                              template[i].ilen, iv);
+
+                       aead_request_set_assoc(req, asg, template[i].alen);
+
+                       ret = enc ?
+                               crypto_aead_encrypt(req) :
+                               crypto_aead_decrypt(req);
+
+                       switch (ret) {
+                       case 0:
+                               if (template[i].novrfy) {
+                                       /* verification was supposed to fail */
+                                       printk(KERN_ERR "alg: aead: %s failed "
+                                              "on test %d for %s: ret was 0, "
+                                              "expected -EBADMSG\n",
+                                              e, j, algo);
+                                       /* so really, we got a bad message */
+                                       ret = -EBADMSG;
+                                       goto out;
+                               }
+                               break;
+                       case -EINPROGRESS:
+                       case -EBUSY:
+                               ret = wait_for_completion_interruptible(
+                                       &result.completion);
+                               if (!ret && !(ret = result.err)) {
+                                       INIT_COMPLETION(result.completion);
+                                       break;
+                               }
+                       case -EBADMSG:
+                               if (template[i].novrfy)
+                                       /* verification failure was expected */
+                                       continue;
+                               /* fall through */
+                       default:
+                               printk(KERN_ERR "alg: aead: %s failed on test "
+                                      "%d for %s: ret=%d\n", e, j, algo, -ret);
+                               goto out;
+                       }
+
+                       q = input;
+                       if (memcmp(q, template[i].result, template[i].rlen)) {
+                               printk(KERN_ERR "alg: aead: Test %d failed on "
+                                      "%s for %s\n", j, e, algo);
+                               hexdump(q, template[i].rlen);
+                               ret = -EINVAL;
+                               goto out;
+                       }
+                       else {
+                               printk(KERN_ERR "alg: aead: Test %d passed on "
+                                      "%s for %s\n", j, e, algo);
+                               hexdump(q, template[i].rlen);
+                       }
+               }
+       }
+
+       for (i = 0, j = 0; i < tcount; i++) {
+               if (template[i].np) {
+                       j++;
+
+                       if (template[i].iv)
+                               memcpy(iv, template[i].iv, MAX_IVLEN);
+                       else
+                               memset(iv, 0, MAX_IVLEN);
+
+                       crypto_aead_clear_flags(tfm, ~0);
+                       if (template[i].wk)
+                               crypto_aead_set_flags(
+                                       tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+                       key = template[i].key;
+
+                       ret = crypto_aead_setkey(tfm, key, template[i].klen);
+                       if (!ret == template[i].fail) {
+                               printk(KERN_ERR "alg: aead: setkey failed on "
+                                      "chunk test %d for %s: flags=%x\n", j,
+                                      algo, crypto_aead_get_flags(tfm));
+                               goto out;
+                       } else if (ret)
+                               continue;
+
+                       authsize = abs(template[i].rlen - template[i].ilen);
+
+                       ret = -EINVAL;
+                       sg_init_table(sg, template[i].np);
+                       for (k = 0, temp = 0; k < template[i].np; k++) {
+                               if (WARN_ON(offset_in_page(IDX[k]) +
+                                           template[i].tap[k] > PAGE_SIZE))
+                                       goto out;
+
+                               q = xbuf[IDX[k] >> PAGE_SHIFT] +
+                                   offset_in_page(IDX[k]);
+
+                               memcpy(q, template[i].input + temp,
+                                      template[i].tap[k]);
+
+                               n = template[i].tap[k];
+                               if (k == template[i].np - 1 && enc)
+                                       n += authsize;
+                               if (offset_in_page(q) + n < PAGE_SIZE)
+                                       q[n] = 0;
+
+                               sg_set_buf(&sg[k], q, template[i].tap[k]);
+                               temp += template[i].tap[k];
+                       }
+
+                       ret = crypto_aead_setauthsize(tfm, authsize);
+                       if (ret) {
+                               printk(KERN_ERR "alg: aead: Failed to set "
+                                      "authsize to %u on chunk test %d for "
+                                      "%s\n", authsize, j, algo);
+                               goto out;
+                       }
+
+                       if (enc) {
+                               if (WARN_ON(sg[k - 1].offset +
+                                           sg[k - 1].length + authsize >
+                                           PAGE_SIZE)) {
+                                       ret = -EINVAL;
+                                       goto out;
+                               }
+
+                               sg[k - 1].length += authsize;
+                       }
+
+                       sg_init_table(asg, template[i].anp);
+                       ret = -EINVAL;
+                       for (k = 0, temp = 0; k < template[i].anp; k++) {
+                               if (WARN_ON(offset_in_page(IDX[k]) +
+                                           template[i].atap[k] > PAGE_SIZE))
+                                       goto out;
+                               sg_set_buf(&asg[k],
+                                          memcpy(axbuf[IDX[k] >> PAGE_SHIFT] +
+                                                 offset_in_page(IDX[k]),
+                                                 template[i].assoc + temp,
+                                                 template[i].atap[k]),
+                                          template[i].atap[k]);
+                               temp += template[i].atap[k];
+                       }
+
+                       aead_request_set_crypt(req, sg, sg,
+                                              template[i].ilen,
+                                              iv);
+
+                       aead_request_set_assoc(req, asg, template[i].alen);
+
+                       ret = enc ?
+                               crypto_aead_encrypt(req) :
+                               crypto_aead_decrypt(req);
+
+                       switch (ret) {
+                       case 0:
+                               if (template[i].novrfy) {
+                                       /* verification was supposed to fail */
+                                       printk(KERN_ERR "alg: aead: %s failed "
+                                              "on chunk test %d for %s: ret "
+                                              "was 0, expected -EBADMSG\n",
+                                              e, j, algo);
+                                       /* so really, we got a bad message */
+                                       ret = -EBADMSG;
+                                       goto out;
+                               }
+                               break;
+                       case -EINPROGRESS:
+                       case -EBUSY:
+                               ret = wait_for_completion_interruptible(
+                                       &result.completion);
+                               if (!ret && !(ret = result.err)) {
+                                       INIT_COMPLETION(result.completion);
+                                       break;
+                               }
+                       case -EBADMSG:
+                               if (template[i].novrfy)
+                                       /* verification failure was expected */
+                                       continue;
+                               /* fall through */
+                       default:
+                               printk(KERN_ERR "alg: aead: %s failed on "
+                                      "chunk test %d for %s: ret=%d\n", e, j,
+                                      algo, -ret);
+                               goto out;
+                       }
+
+                       ret = -EINVAL;
+                       for (k = 0, temp = 0; k < template[i].np; k++) {
+                               q = xbuf[IDX[k] >> PAGE_SHIFT] +
+                                   offset_in_page(IDX[k]);
+
+                               n = template[i].tap[k];
+                               if (k == template[i].np - 1)
+                                       n += enc ? authsize : -authsize;
+
+                               if (memcmp(q, template[i].result + temp, n)) {
+                                       printk(KERN_ERR "alg: aead: Chunk "
+                                              "test %d failed on %s at page "
+                                              "%u for %s\n", j, e, k, algo);
+                                       hexdump(q, n);
+                                       goto out;
+                               }
+                               else {
+                                       printk(KERN_ERR "alg: aead: Chunk "
+                                              "test %d passed on %s at page "
+                                              "%u for %s\n", j, e, k, algo);
+                                       hexdump(q, n);
+                               }
+
+                               q += n;
+                               if (k == template[i].np - 1 && !enc) {
+                                       if (memcmp(q, template[i].input +
+                                                     temp + n, authsize))
+                                               n = authsize;
+                                       else
+                                               n = 0;
+                               } else {
+                                       for (n = 0; offset_in_page(q + n) &&
+                                                   q[n]; n++)
+                                               ;
+                               }
+                               if (n) {
+                                       printk(KERN_ERR "alg: aead: Result "
+                                              "buffer corruption in chunk "
+                                              "test %d on %s at page %u for "
+                                              "%s: %u bytes:\n", j, e, k,
+                                              algo, n);
+                                       hexdump(q, n);
+                                       goto out;
+                               }
+                               temp += template[i].tap[k];
+                       }
+               }
+       }
+
+       ret = 0;
+
+out:
+       aead_request_free(req);
+       testmgr_free_buf(axbuf);
+out_noaxbuf:
+       testmgr_free_buf(xbuf);
+out_noxbuf:
+       return ret;
+}
+
+static int test_cipher(struct crypto_cipher *tfm, int enc,
+                      struct cipher_testvec *template, unsigned int tcount)
+{
+       const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm));
+       unsigned int i, j, k;
+       char *q;
+       const char *e;
+       void *data;
+       char *xbuf[XBUFSIZE];
+       int ret = -ENOMEM;
+
+       if (testmgr_alloc_buf(xbuf))
+               goto out_nobuf;
+
+       if (enc == ENCRYPT)
+               e = "encryption";
+       else
+               e = "decryption";
+
+       j = 0;
+       for (i = 0; i < tcount; i++) {
+               if (template[i].np)
+                       continue;
+
+               j++;
+
+               ret = -EINVAL;
+               if (WARN_ON(template[i].ilen > PAGE_SIZE))
+                       goto out;
+
+               data = xbuf[0];
+               memcpy(data, template[i].input, template[i].ilen);
+
+               crypto_cipher_clear_flags(tfm, ~0);
+               if (template[i].wk)
+                       crypto_cipher_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+
+               ret = crypto_cipher_setkey(tfm, template[i].key,
+                                          template[i].klen);
+               if (!ret == template[i].fail) {
+                       printk(KERN_ERR "alg: cipher: setkey failed "
+                              "on test %d for %s: flags=%x\n", j,
+                              algo, crypto_cipher_get_flags(tfm));
+                       goto out;
+               } else if (ret)
+                       continue;
+
+               for (k = 0; k < template[i].ilen;
+                    k += crypto_cipher_blocksize(tfm)) {
+                       if (enc)
+                               crypto_cipher_encrypt_one(tfm, data + k,
+                                                         data + k);
+                       else
+                               crypto_cipher_decrypt_one(tfm, data + k,
+                                                         data + k);
+               }
+
+               q = data;
+               if (memcmp(q, template[i].result, template[i].rlen)) {
+                       printk(KERN_ERR "alg: cipher: Test %d failed "
+                              "on %s for %s\n", j, e, algo);
+                       hexdump(q, template[i].rlen);
+                       ret = -EINVAL;
+                       goto out;
+               }
+               else {
+                       printk(KERN_ERR "alg: cipher: Test %d passed "
+                              "on %s for %s\n", j, e, algo);
+                       hexdump(q, template[i].rlen);
+               }
+       }
+
+       ret = 0;
+
+out:
+       testmgr_free_buf(xbuf);
+out_nobuf:
+       return ret;
+}
+
+static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
+                        struct cipher_testvec *template, unsigned int tcount)
+{
+       const char *algo =
+               crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm));
+       unsigned int i, j, k, n, temp;
+       char *q;
+       struct ablkcipher_request *req;
+       struct scatterlist sg[8];
+       const char *e;
+       struct tcrypt_result result;
+       void *data;
+       char iv[MAX_IVLEN];
+       char *xbuf[XBUFSIZE];
+       int ret = -ENOMEM;
+
+       if (testmgr_alloc_buf(xbuf))
+               goto out_nobuf;
+
+       if (enc == ENCRYPT)
+               e = "encryption";
+       else
+               e = "decryption";
+
+       init_completion(&result.completion);
+
+       req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
+       if (!req) {
+               printk(KERN_ERR "alg: skcipher: Failed to allocate request "
+                      "for %s\n", algo);
+               goto out;
+       }
+        //printk("tcount: %u\n", tcount);
+
+       ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+                                       tcrypt_complete, &result);
+
+       j = 0;
+       for (i = 0; i < tcount; i++) {
+               if (template[i].iv)
+                       memcpy(iv, template[i].iv, MAX_IVLEN);
+               else
+                       memset(iv, 0, MAX_IVLEN);
+
+               if (!(template[i].np)) {
+                        //printk("np: %d, i: %d, j: %d\n", template[i].np, i, j);
+                       j++;
+
+                       ret = -EINVAL;
+                       if (WARN_ON(template[i].ilen > PAGE_SIZE))
+                               goto out;
+
+                       data = xbuf[0];
+                       memcpy(data, template[i].input, template[i].ilen);
+
+                       crypto_ablkcipher_clear_flags(tfm, ~0);
+                       if (template[i].wk)
+                               crypto_ablkcipher_set_flags(
+                                       tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+
+                       ret = crypto_ablkcipher_setkey(tfm, template[i].key,
+                                                      template[i].klen);
+                       if (!ret == template[i].fail) {
+                               printk(KERN_ERR "alg: skcipher: setkey failed "
+                                      "on test %d for %s: flags=%x\n", j,
+                                      algo, crypto_ablkcipher_get_flags(tfm));
+                                printk("ERROR\n");
+                               goto out;
+                       } else if (ret)
+                               continue;
+
+                       sg_init_one(&sg[0], data, template[i].ilen);
+
+                       ablkcipher_request_set_crypt(req, sg, sg,
+                                                    template[i].ilen, iv);
+                       ret = enc ?
+                               crypto_ablkcipher_encrypt(req) :
+                               crypto_ablkcipher_decrypt(req);
+
+                       switch (ret) {
+                       case 0:
+                               break;
+                       case -EINPROGRESS:
+                       case -EBUSY:
+                               ret = wait_for_completion_interruptible(
+                                       &result.completion);
+                               if (!ret && !((ret = result.err))) {
+                                       INIT_COMPLETION(result.completion);
+                                       break;
+                               }
+                               /* fall through */
+                       default:
+                               printk(KERN_ERR "alg: skcipher: %s failed on "
+                                      "test %d for %s: ret=%d\n", e, j, algo,
+                                      -ret);
+                                printk("ERROR\n");
+                               goto out;
+                       }
+                       q = data;
+                       if (memcmp(q, template[i].result, template[i].rlen)) {
+                               printk(KERN_ERR "alg: skcipher: Test %d "
+                                      "failed on %s for %s\n", j, e, algo);
+                               hexdump(q, template[i].rlen);
+                                printk("ERROR\n");
+                               ret = -EINVAL;
+                               goto out;
+                       }
+                       else {
+                               printk(KERN_ERR "alg: skcipher: Test %d "
+                                      "*PASSED* on %s for %s\n", j, e, algo);
+                               hexdump(q, template[i].rlen);
+                                printk("DONE\n");
+                       }
+               }
+       }
+        printk("Testing %s chunking across pages.\n", algo);
+       j = 0;
+       for (i = 0; i < tcount; i++) {             
+               if (template[i].iv)
+                       memcpy(iv, template[i].iv, MAX_IVLEN);
+               else
+                       memset(iv, 0, MAX_IVLEN);
+
+               if (template[i].np) {
+                       j++;
+
+                       crypto_ablkcipher_clear_flags(tfm, ~0);
+                       if (template[i].wk)
+                               crypto_ablkcipher_set_flags(
+                                       tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+
+                       ret = crypto_ablkcipher_setkey(tfm, template[i].key,
+                                                      template[i].klen);
+                       if (!ret == template[i].fail) {
+                               printk(KERN_ERR "alg: skcipher: setkey failed "
+                                      "on chunk test %d for %s: flags=%x\n",
+                                      j, algo,
+                                      crypto_ablkcipher_get_flags(tfm));
+                                printk("ERROR\n");
+                               goto out;
+                       } else if (ret)
+                               continue;
+
+                       temp = 0;
+                       ret = -EINVAL;
+                       sg_init_table(sg, template[i].np);
+                       for (k = 0; k < template[i].np; k++) {
+                               if (WARN_ON(offset_in_page(IDX[k]) +
+                                           template[i].tap[k] > PAGE_SIZE))
+                                       goto out;
+
+                               q = xbuf[IDX[k] >> PAGE_SHIFT] +
+                                   offset_in_page(IDX[k]);
+
+                               memcpy(q, template[i].input + temp,
+                                      template[i].tap[k]);
+
+                               if (offset_in_page(q) + template[i].tap[k] <
+                                   PAGE_SIZE)
+                                       q[template[i].tap[k]] = 0;
+
+                               sg_set_buf(&sg[k], q, template[i].tap[k]);
+
+                               temp += template[i].tap[k];
+                       }
+
+                       ablkcipher_request_set_crypt(req, sg, sg,
+                                       template[i].ilen, iv);
+
+                       ret = enc ?
+                               crypto_ablkcipher_encrypt(req) :
+                               crypto_ablkcipher_decrypt(req);
+
+                       switch (ret) {
+                       case 0:
+                               break;
+                       case -EINPROGRESS:
+                       case -EBUSY:
+                               ret = wait_for_completion_interruptible(
+                                       &result.completion);
+                               if (!ret && !((ret = result.err))) {
+                                       INIT_COMPLETION(result.completion);
+                                       break;
+                               }
+                               /* fall through */
+                       default:
+                               printk(KERN_ERR "alg: skcipher: %s failed on "
+                                      "chunk test %d for %s: ret=%d\n", e, j,
+                                      algo, -ret);
+                                printk("ERROR\n");
+                               goto out;
+                       }
+
+                       temp = 0;
+                       ret = -EINVAL;
+                       for (k = 0; k < template[i].np; k++) {
+                               q = xbuf[IDX[k] >> PAGE_SHIFT] +
+                                   offset_in_page(IDX[k]);
+
+                               if (memcmp(q, template[i].result + temp,
+                                          template[i].tap[k])) {
+                                       printk(KERN_ERR "alg: skcipher: Chunk "
+                                              "test %d failed on %s at page "
+                                              "%u for %s\n", j, e, k, algo);
+                                       hexdump(q, template[i].tap[k]);
+                                        printk("ERROR\n");
+                                       goto out;
+                               }
+                               else {
+                                       printk(KERN_ERR "alg: skcipher: Chunk "
+                                              "test %d *PASSED* on %s at page "
+                                              "%u for %s\n", j, e, k, algo);
+                                       hexdump(q, template[i].tap[k]);
+                                        printk("DONE\n");
+                               }
+
+                               q += template[i].tap[k];
+                               for (n = 0; offset_in_page(q + n) && q[n]; n++)
+                                       ;
+#if 1
+                               if (n) {
+                                       printk(KERN_ERR "alg: skcipher: "
+                                              "Result buffer corruption in "
+                                              "chunk test %d on %s at page "
+                                              "%u for %s: %u bytes:\n", j, e,
+                                              k, algo, n);
+                                       hexdump(q, n);
+                                        printk("ERROR\n");
+                                       goto out;
+                               }
+                                else {
+                                       printk(KERN_ERR "alg: skcipher: "
+                                              "Result buffer clean in "
+                                              "chunk test %d on %s at page "
+                                              "%u for %s: %u bytes:\n", j, e,
+                                              k, algo, n);
+                                       hexdump(q, n);
+                                        printk("Chunk Buffer clean\n");
+                                }
+#endif
+                               temp += template[i].tap[k];
+                       }
+               }
+       }
+
+       ret = 0;
+out:
+       ablkcipher_request_free(req);
+       testmgr_free_buf(xbuf);
+out_nobuf:
+       return ret;
+}
+
+static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
+                    struct comp_testvec *dtemplate, int ctcount, int dtcount)
+{
+       const char *algo = crypto_tfm_alg_driver_name(crypto_comp_tfm(tfm));
+       unsigned int i;
+       char result[COMP_BUF_SIZE];
+       int ret;
+
+       for (i = 0; i < ctcount; i++) {
+               int ilen;
+               unsigned int dlen = COMP_BUF_SIZE;
+
+               memset(result, 0, sizeof (result));
+
+               ilen = ctemplate[i].inlen;
+               ret = crypto_comp_compress(tfm, ctemplate[i].input,
+                                          ilen, result, &dlen);
+               if (ret) {
+                       printk(KERN_ERR "alg: comp: compression failed "
+                              "on test %d for %s: ret=%d\n", i + 1, algo,
+                              -ret);
+                       goto out;
+               }
+
+               if (dlen != ctemplate[i].outlen) {
+                       printk(KERN_ERR "alg: comp: Compression test %d "
+                              "failed for %s: output len = %d\n", i + 1, algo,
+                              dlen);
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               if (memcmp(result, ctemplate[i].output, dlen)) {
+                       printk(KERN_ERR "alg: comp: Compression test %d "
+                              "failed for %s\n", i + 1, algo);
+                       hexdump(result, dlen);
+                       ret = -EINVAL;
+                       goto out;
+               }
+               else {
+                       printk(KERN_ERR "alg: comp: Compression test %d "
+                              "passed for %s\n", i + 1, algo);
+                       hexdump(result, dlen);
+               }
+       }
+
+       for (i = 0; i < dtcount; i++) {
+               int ilen;
+               unsigned int dlen = COMP_BUF_SIZE;
+
+               memset(result, 0, sizeof (result));
+
+               ilen = dtemplate[i].inlen;
+               ret = crypto_comp_decompress(tfm, dtemplate[i].input,
+                                            ilen, result, &dlen);
+               if (ret) {
+                       printk(KERN_ERR "alg: comp: decompression failed "
+                              "on test %d for %s: ret=%d\n", i + 1, algo,
+                              -ret);
+                       goto out;
+               }
+
+               if (dlen != dtemplate[i].outlen) {
+                       printk(KERN_ERR "alg: comp: Decompression test %d "
+                              "failed for %s: output len = %d\n", i + 1, algo,
+                              dlen);
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               if (memcmp(result, dtemplate[i].output, dlen)) {
+                       printk(KERN_ERR "alg: comp: Decompression test %d "
+                              "failed for %s\n", i + 1, algo);
+                       hexdump(result, dlen);
+                       ret = -EINVAL;
+                       goto out;
+               }
+               else {
+                       printk(KERN_ERR "alg: comp: Decompression test %d "
+                              "passed for %s\n", i + 1, algo);
+                       hexdump(result, dlen);
+               }
+       }
+
+       ret = 0;
+
+out:
+       return ret;
+}
+
+static int test_pcomp(struct crypto_pcomp *tfm,
+                     struct pcomp_testvec *ctemplate,
+                     struct pcomp_testvec *dtemplate, int ctcount,
+                     int dtcount)
+{
+       const char *algo = crypto_tfm_alg_driver_name(crypto_pcomp_tfm(tfm));
+       unsigned int i;
+       char result[COMP_BUF_SIZE];
+       int res;
+
+       for (i = 0; i < ctcount; i++) {
+               struct comp_request req;
+               unsigned int produced = 0;
+
+               res = crypto_compress_setup(tfm, ctemplate[i].params,
+                                           ctemplate[i].paramsize);
+               if (res) {
+                       pr_err("alg: pcomp: compression setup failed on test "
+                              "%d for %s: error=%d\n", i + 1, algo, res);
+                       return res;
+               }
+
+               res = crypto_compress_init(tfm);
+               if (res) {
+                       pr_err("alg: pcomp: compression init failed on test "
+                              "%d for %s: error=%d\n", i + 1, algo, res);
+                       return res;
+               }
+
+               memset(result, 0, sizeof(result));
+
+               req.next_in = ctemplate[i].input;
+               req.avail_in = ctemplate[i].inlen / 2;
+               req.next_out = result;
+               req.avail_out = ctemplate[i].outlen / 2;
+
+               res = crypto_compress_update(tfm, &req);
+               if (res < 0 && (res != -EAGAIN || req.avail_in)) {
+                       pr_err("alg: pcomp: compression update failed on test "
+                              "%d for %s: error=%d\n", i + 1, algo, res);
+                       return res;
+               }
+               if (res > 0)
+                       produced += res;
+
+               /* Add remaining input data */
+               req.avail_in += (ctemplate[i].inlen + 1) / 2;
+
+               res = crypto_compress_update(tfm, &req);
+               if (res < 0 && (res != -EAGAIN || req.avail_in)) {
+                       pr_err("alg: pcomp: compression update failed on test "
+                              "%d for %s: error=%d\n", i + 1, algo, res);
+                       return res;
+               }
+               if (res > 0)
+                       produced += res;
+
+               /* Provide remaining output space */
+               req.avail_out += COMP_BUF_SIZE - ctemplate[i].outlen / 2;
+
+               res = crypto_compress_final(tfm, &req);
+               if (res < 0) {
+                       pr_err("alg: pcomp: compression final failed on test "
+                              "%d for %s: error=%d\n", i + 1, algo, res);
+                       return res;
+               }
+               produced += res;
+
+               if (COMP_BUF_SIZE - req.avail_out != ctemplate[i].outlen) {
+                       pr_err("alg: comp: Compression test %d failed for %s: "
+                              "output len = %d (expected %d)\n", i + 1, algo,
+                              COMP_BUF_SIZE - req.avail_out,
+                              ctemplate[i].outlen);
+                       return -EINVAL;
+               }
+
+               if (produced != ctemplate[i].outlen) {
+                       pr_err("alg: comp: Compression test %d failed for %s: "
+                              "returned len = %u (expected %d)\n", i + 1,
+                              algo, produced, ctemplate[i].outlen);
+                       return -EINVAL;
+               }
+
+               if (memcmp(result, ctemplate[i].output, ctemplate[i].outlen)) {
+                       pr_err("alg: pcomp: Compression test %d failed for "
+                              "%s\n", i + 1, algo);
+                       hexdump(result, ctemplate[i].outlen);
+                       return -EINVAL;
+               }
+       }
+
+       for (i = 0; i < dtcount; i++) {
+               struct comp_request req;
+               unsigned int produced = 0;
+
+               res = crypto_decompress_setup(tfm, dtemplate[i].params,
+                                             dtemplate[i].paramsize);
+               if (res) {
+                       pr_err("alg: pcomp: decompression setup failed on "
+                              "test %d for %s: error=%d\n", i + 1, algo, res);
+                       return res;
+               }
+
+               res = crypto_decompress_init(tfm);
+               if (res) {
+                       pr_err("alg: pcomp: decompression init failed on test "
+                              "%d for %s: error=%d\n", i + 1, algo, res);
+                       return res;
+               }
+
+               memset(result, 0, sizeof(result));
+
+               req.next_in = dtemplate[i].input;
+               req.avail_in = dtemplate[i].inlen / 2;
+               req.next_out = result;
+               req.avail_out = dtemplate[i].outlen / 2;
+
+               res = crypto_decompress_update(tfm, &req);
+               if (res < 0 && (res != -EAGAIN || req.avail_in)) {
+                       pr_err("alg: pcomp: decompression update failed on "
+                              "test %d for %s: error=%d\n", i + 1, algo, res);
+                       return res;
+               }
+               if (res > 0)
+                       produced += res;
+
+               /* Add remaining input data */
+               req.avail_in += (dtemplate[i].inlen + 1) / 2;
+
+               res = crypto_decompress_update(tfm, &req);
+               if (res < 0 && (res != -EAGAIN || req.avail_in)) {
+                       pr_err("alg: pcomp: decompression update failed on "
+                              "test %d for %s: error=%d\n", i + 1, algo, res);
+                       return res;
+               }
+               if (res > 0)
+                       produced += res;
+
+               /* Provide remaining output space */
+               req.avail_out += COMP_BUF_SIZE - dtemplate[i].outlen / 2;
+
+               res = crypto_decompress_final(tfm, &req);
+               if (res < 0 && (res != -EAGAIN || req.avail_in)) {
+                       pr_err("alg: pcomp: decompression final failed on "
+                              "test %d for %s: error=%d\n", i + 1, algo, res);
+                       return res;
+               }
+               if (res > 0)
+                       produced += res;
+
+               if (COMP_BUF_SIZE - req.avail_out != dtemplate[i].outlen) {
+                       pr_err("alg: comp: Decompression test %d failed for "
+                              "%s: output len = %d (expected %d)\n", i + 1,
+                              algo, COMP_BUF_SIZE - req.avail_out,
+                              dtemplate[i].outlen);
+                       return -EINVAL;
+               }
+
+               if (produced != dtemplate[i].outlen) {
+                       pr_err("alg: comp: Decompression test %d failed for "
+                              "%s: returned len = %u (expected %d)\n", i + 1,
+                              algo, produced, dtemplate[i].outlen);
+                       return -EINVAL;
+               }
+
+               if (memcmp(result, dtemplate[i].output, dtemplate[i].outlen)) {
+                       pr_err("alg: pcomp: Decompression test %d failed for "
+                              "%s\n", i + 1, algo);
+                       hexdump(result, dtemplate[i].outlen);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static int test_ablkcipher_jiffies(struct ablkcipher_request *req, int enc,
+                                  int sec, struct tcrypt_result *result,
+                                  int blen)
+{
+        unsigned long start, end;
+        int bcount;
+        int ret;
+
+        for (start = jiffies, end = start + sec * HZ, bcount = 0;
+             time_before(jiffies, end); bcount++) {
+
+                if (enc)
+                        ret = crypto_ablkcipher_encrypt(req);
+                else
+                        ret = crypto_ablkcipher_decrypt(req);
+
+                switch (ret) {
+                    case 0:
+                       break;
+                   case -EINPROGRESS: 
+                   case -EBUSY:
+                       ret = wait_for_completion_interruptible(
+                              &result->completion);
+                         if (!ret && !((ret = result->err))) {
+                              INIT_COMPLETION(result->completion);
+                              break;
+                         }
+                   default:
+                        printk("ERROR\n");
+                       return ret;
+                }       
+        }
+
+        printk("%d operations in %d seconds (%ld bytes)\n",
+               bcount, sec, (long)bcount * blen);
+   
+       return 0;
+}
+
+static int test_ablkcipher_cycles(struct ablkcipher_request *req, int enc,
+                                 int sec, struct tcrypt_result *result,
+                                 int blen)
+{
+        unsigned long cycles = 0;
+        int ret = 0;
+        int i;
+        unsigned long start, end = 0;
+        //local_bh_disable();
+        //local_irq_disable();
+        /* Warm-up run. */
+        for (i = 0; i < 4; i++) {
+                if (enc)
+                        ret = crypto_ablkcipher_encrypt(req);
+                else
+                        ret = crypto_ablkcipher_decrypt(req);
+
+                switch (ret) {
+                    case 0:
+                       break;
+                   case -EINPROGRESS: 
+                   case -EBUSY:
+#if 0
+                       ret = wait_for_completion_interruptible(
+                              &result->completion);
+                        if (!ret && !((ret = result->err))) {
+                              INIT_COMPLETION(result->completion);
+                              break;
+                        } 
+#else
+
+                        wait_for_completion(&result->completion);
+                         INIT_COMPLETION(result->completion);
+                         break;
+#endif
+                   default:
+                        printk("ERROR\n");
+                       return ret;
+                }     
+               if (signal_pending(current)) {
+                   printk("Signal caught\n");
+                   break;
+               } 
+
+        }
+
+       //printk("Debug ln: (%d), fn: %s\n", __LINE__, __func__);
+        /* The real thing. */
+        for (i = 0; i < 8; i++) {
+                end = 0;
+                start = 0;
+                start = read_c0_count();
+                if (enc)
+                        ret = crypto_ablkcipher_encrypt(req);
+                else
+                        ret = crypto_ablkcipher_decrypt(req);
+
+                switch (ret) {
+                    case 0:
+                       break;
+                   case -EINPROGRESS: 
+                   case -EBUSY:
+#if 0
+                       ret = wait_for_completion_interruptible(
+                              &result->completion);
+                             end = get_cycles();
+                         if (!ret && !((ret = result->err))) {
+                              INIT_COMPLETION(result->completion);
+                              break;
+                         }
+#else
+                        wait_for_completion(&result->completion);
+                         end = read_c0_count();
+                         INIT_COMPLETION(result->completion);
+                         break;
+#endif
+                   default:
+                        printk("ERROR\n");
+                       return ret;
+                }       
+
+               if (signal_pending(current)) {
+                   printk("Signal caught\n");
+                   break;
+               } 
+        
+                cycles += end - start;
+        }
+
+       // local_irq_enable();
+       // local_bh_enable();
+
+        printk("1 operation in %lu cycles (%d bytes)\n",
+               (cycles + 4) / 8, blen);
+
+        return 0;
+
+}
+
+static u32 b_size[] = {16, 64, 256, 1024, 8192, 0};
+
+static int test_skcipher_speed(struct crypto_ablkcipher *tfm, int enc,
+                              struct cipher_speed_template *template, 
+                               unsigned int tcount, unsigned int sec, 
+                               u8* keysize)    
+{
+       const char *algo =
+               crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm));
+
+       unsigned int i = 0, j, iv_len;
+       struct ablkcipher_request *req;
+       //struct scatterlist sg[8];
+       const char *e;
+       struct tcrypt_result result;
+       char iv[MAX_IVLEN];
+       static char *xbuf[XBUFSIZE];
+       int ret = -ENOMEM;
+        u32 *block_size;
+        static char *tvmem_buf[4];
+        const char *key;
+       
+       if (testmgr_alloc_buf(xbuf))
+               goto out_nobuf;
+
+       if (enc == ENCRYPT)
+               e = "encryption";
+       else
+               e = "decryption";
+
+       init_completion(&result.completion);
+
+        printk("Start ablkcipher speed test\n");
+
+       req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
+       if (!req) {
+               printk(KERN_ERR "alg: skcipher: Failed to allocate request "
+                      "for %s\n", algo);
+               goto out;
+       }
+//     ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+       ablkcipher_request_set_callback(req, 0,
+                                       tcrypt_complete, &result);
+
+        do {
+
+            block_size = b_size;      
+
+            do {
+                struct scatterlist sg[4];
+                if ((*keysize + *block_size) > 4 * PAGE_SIZE) {
+                    printk("template (%u) too big for "
+                          "tvmem_buf (%lu)\n", *keysize + *block_size,
+                           4 * PAGE_SIZE);
+                           goto out;
+                }
+               crypto_ablkcipher_clear_flags(tfm, ~0);
+
+                printk("test %u (%d bit key, %d byte blocks): ", i,
+                        *keysize * 8, *block_size);                
+
+                memset(tvmem_buf[0], 0xff, PAGE_SIZE);
+                key = tvmem_buf[0];
+
+                for (j = 0; j < tcount; j++) {
+                    if (template[j].klen == *keysize) {
+                        key = template[j].key;
+                        break;
+                    }    
+                }
+                ret = crypto_ablkcipher_setkey(tfm, key, *keysize);
+                if (ret) {
+                    printk("Error setting of keys\n");
+                    goto out;
+                }
+
+                sg_init_table(sg, 4); 
+
+                for (j = 0; j < 4; j++) {
+                   tvmem_buf[j] = xbuf[j];
+                   memset(tvmem_buf[j], 0xff, PAGE_SIZE);
+                    sg_set_buf(sg + j, tvmem_buf[j], PAGE_SIZE);
+                }
+
+               iv_len = crypto_ablkcipher_ivsize(tfm);
+                if (iv_len) {
+                    memset(&iv, 0xff, iv_len);
+                }
+
+               ablkcipher_request_set_crypt(req, sg, sg,
+                                             *block_size, iv);
+              
+                //printk("Debug ln: %d, %s\n", __LINE__, __func__);
+               if (sec) 
+                   ret = test_ablkcipher_jiffies(req, enc, sec,
+                                                 &result, *block_size);
+                else
+                    ret = test_ablkcipher_cycles(req, enc, sec,
+                                                &result, *block_size);
+                
+                
+                if (ret) {
+                   printk(KERN_ERR "alg: skcipher: %s failed on "
+                          "test %d for %s: ret=%d\n", e, j, algo,
+                          -ret);
+                    goto out;
+               }
+
+                block_size++;
+                i++;
+            } while (*block_size);
+            keysize++;
+        } while (*keysize);  
+
+       ret = 0;
+out:
+        printk("End ablkcipher speed test\n");
+       ablkcipher_request_free(req);
+       testmgr_free_buf(xbuf);
+#if 0
+       if (!completion_done(&result->completion)) {
+           printk("There are threads waiting for completion, completing all\n");
+           complete_all(&result->completion); 
+       }
+#endif 
+
+       //testmgr_free_buf(tvbuf);
+out_nobuf:
+       return ret;
+
+}
+
+static int test_cprng(struct crypto_rng *tfm, struct cprng_testvec *template,
+                     unsigned int tcount)
+{
+       const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm));
+       int err = 0, i, j, seedsize;
+       u8 *seed;
+       char result[32];
+
+       seedsize = crypto_rng_seedsize(tfm);
+
+       seed = kmalloc(seedsize, GFP_KERNEL);
+       if (!seed) {
+               printk(KERN_ERR "alg: cprng: Failed to allocate seed space "
+                      "for %s\n", algo);
+               return -ENOMEM;
+       }
+
+       for (i = 0; i < tcount; i++) {
+               memset(result, 0, 32);
+
+               memcpy(seed, template[i].v, template[i].vlen);
+               memcpy(seed + template[i].vlen, template[i].key,
+                      template[i].klen);
+               memcpy(seed + template[i].vlen + template[i].klen,
+                      template[i].dt, template[i].dtlen);
+
+               err = crypto_rng_reset(tfm, seed, seedsize);
+               if (err) {
+                       printk(KERN_ERR "alg: cprng: Failed to reset rng "
+                              "for %s\n", algo);
+                       goto out;
+               }
+
+               for (j = 0; j < template[i].loops; j++) {
+                       err = crypto_rng_get_bytes(tfm, result,
+                                                  template[i].rlen);
+                       if (err != template[i].rlen) {
+                               printk(KERN_ERR "alg: cprng: Failed to obtain "
+                                      "the correct amount of random data for "
+                                      "%s (requested %d, got %d)\n", algo,
+                                      template[i].rlen, err);
+                               goto out;
+                       }
+               }
+
+               err = memcmp(result, template[i].result,
+                            template[i].rlen);
+               if (err) {
+                       printk(KERN_ERR "alg: cprng: Test %d failed for %s\n",
+                              i, algo);
+                       hexdump(result, template[i].rlen);
+                       err = -EINVAL;
+                       goto out;
+               }
+       }
+
+out:
+       kfree(seed);
+       return err;
+}
+
+static int alg_test_aead(const struct alg_test_desc *desc, const char *driver,
+                        u32 type, u32 mask)
+{
+       struct crypto_aead *tfm;
+       int err = 0;
+
+       tfm = crypto_alloc_aead(driver, type, mask);
+       if (IS_ERR(tfm)) {
+               printk(KERN_ERR "alg: aead: Failed to load transform for %s: "
+                      "%ld\n", driver, PTR_ERR(tfm));
+               return PTR_ERR(tfm);
+       }
+
+       if (desc->suite.aead.enc.vecs) {
+               err = test_aead(tfm, ENCRYPT, desc->suite.aead.enc.vecs,
+                               desc->suite.aead.enc.count);
+               if (err)
+                       goto out;
+       }
+
+       if (!err && desc->suite.aead.dec.vecs)
+               err = test_aead(tfm, DECRYPT, desc->suite.aead.dec.vecs,
+                               desc->suite.aead.dec.count);
+
+out:
+       crypto_free_aead(tfm);
+       return err;
+}
+
+static int alg_test_cipher(const struct alg_test_desc *desc,
+                          const char *driver, u32 type, u32 mask)
+{
+       struct crypto_cipher *tfm;
+       int err = 0;
+
+       tfm = crypto_alloc_cipher(driver, type, mask);
+       if (IS_ERR(tfm)) {
+               printk(KERN_ERR "alg: cipher: Failed to load transform for "
+                      "%s: %ld\n", driver, PTR_ERR(tfm));
+               return PTR_ERR(tfm);
+       }
+
+       if (desc->suite.cipher.enc.vecs) {
+               err = test_cipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs,
+                                 desc->suite.cipher.enc.count);
+               if (err)
+                       goto out;
+       }
+
+       if (desc->suite.cipher.dec.vecs)
+               err = test_cipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs,
+                                 desc->suite.cipher.dec.count);
+
+out:
+       crypto_free_cipher(tfm);
+       return err;
+}
+
+static int alg_test_skcipher(const struct alg_test_desc *desc,
+                            const char *driver, u32 type, u32 mask)
+{
+       struct crypto_ablkcipher *tfm;
+       int err = 0;
+
+       tfm = crypto_alloc_ablkcipher(driver, type, mask);
+       if (IS_ERR(tfm)) {
+               printk(KERN_ERR "alg: skcipher: Failed to load transform for "
+                      "%s: %ld\n", driver, PTR_ERR(tfm));
+               return PTR_ERR(tfm);
+       }
+
+       if (desc->suite.cipher.enc.vecs) {
+               err = test_skcipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs,
+                                   desc->suite.cipher.enc.count);
+               if (err)
+                       goto out;
+       }
+
+       if (desc->suite.cipher.dec.vecs)
+               err = test_skcipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs,
+                                   desc->suite.cipher.dec.count);
+
+out:
+       crypto_free_ablkcipher(tfm);
+       return err;
+}
+
+static int alg_test_comp(const struct alg_test_desc *desc, const char *driver,
+                        u32 type, u32 mask)
+{
+       struct crypto_comp *tfm;
+       int err;
+
+       tfm = crypto_alloc_comp(driver, type, mask);
+       if (IS_ERR(tfm)) {
+               printk(KERN_ERR "alg: comp: Failed to load transform for %s: "
+                      "%ld\n", driver, PTR_ERR(tfm));
+               return PTR_ERR(tfm);
+       }
+
+       err = test_comp(tfm, desc->suite.comp.comp.vecs,
+                       desc->suite.comp.decomp.vecs,
+                       desc->suite.comp.comp.count,
+                       desc->suite.comp.decomp.count);
+
+       crypto_free_comp(tfm);
+       return err;
+}
+
+static int alg_test_pcomp(const struct alg_test_desc *desc, const char *driver,
+                         u32 type, u32 mask)
+{
+       struct crypto_pcomp *tfm;
+       int err;
+
+       tfm = crypto_alloc_pcomp(driver, type, mask);
+       if (IS_ERR(tfm)) {
+               pr_err("alg: pcomp: Failed to load transform for %s: %ld\n",
+                      driver, PTR_ERR(tfm));
+               return PTR_ERR(tfm);
+       }
+
+       err = test_pcomp(tfm, desc->suite.pcomp.comp.vecs,
+                        desc->suite.pcomp.decomp.vecs,
+                        desc->suite.pcomp.comp.count,
+                        desc->suite.pcomp.decomp.count);
+
+       crypto_free_pcomp(tfm);
+       return err;
+}
+
+static int alg_test_hash(const struct alg_test_desc *desc, const char *driver,
+                        u32 type, u32 mask)
+{
+       struct crypto_ahash *tfm;
+       int err;
+
+       tfm = crypto_alloc_ahash(driver, type, mask);
+       if (IS_ERR(tfm)) {
+               printk(KERN_ERR "alg: hash: Failed to load transform for %s: "
+                      "%ld\n", driver, PTR_ERR(tfm));
+               return PTR_ERR(tfm);
+       }
+
+       err = test_hash(tfm, desc->suite.hash.vecs, desc->suite.hash.count);
+
+       crypto_free_ahash(tfm);
+       return err;
+}
+
+static int alg_test_crc32c(const struct alg_test_desc *desc,
+                          const char *driver, u32 type, u32 mask)
+{
+       struct crypto_shash *tfm;
+       u32 val;
+       int err;
+
+       err = alg_test_hash(desc, driver, type, mask);
+       if (err)
+               goto out;
+
+       tfm = crypto_alloc_shash(driver, type, mask);
+       if (IS_ERR(tfm)) {
+               printk(KERN_ERR "alg: crc32c: Failed to load transform for %s: "
+                      "%ld\n", driver, PTR_ERR(tfm));
+               err = PTR_ERR(tfm);
+               goto out;
+       }
+
+       do {
+               struct {
+                       struct shash_desc shash;
+                       char ctx[crypto_shash_descsize(tfm)];
+               } sdesc;
+
+               sdesc.shash.tfm = tfm;
+               sdesc.shash.flags = 0;
+
+               *(u32 *)sdesc.ctx = le32_to_cpu(420553207);
+               err = crypto_shash_final(&sdesc.shash, (u8 *)&val);
+               if (err) {
+                       printk(KERN_ERR "alg: crc32c: Operation failed for "
+                              "%s: %d\n", driver, err);
+                       break;
+               }
+
+               if (val != ~420553207) {
+                       printk(KERN_ERR "alg: crc32c: Test failed for %s: "
+                              "%d\n", driver, val);
+                       err = -EINVAL;
+               }
+       } while (0);
+
+       crypto_free_shash(tfm);
+
+out:
+       return err;
+}
+
+static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver,
+                         u32 type, u32 mask)
+{
+       struct crypto_rng *rng;
+       int err = 0;
+
+       rng = crypto_alloc_rng(driver, type, mask);
+       if (IS_ERR(rng)) {
+               printk(KERN_ERR "alg: cprng: Failed to load transform for %s: "
+                      "%ld\n", driver, PTR_ERR(rng));
+               return PTR_ERR(rng);
+       }
+
+       err = test_cprng(rng, desc->suite.cprng.vecs, desc->suite.cprng.count);
+
+       crypto_free_rng(rng);
+
+       return err;
+}
+
+/* Please keep this list sorted by algorithm name. */
+static const struct alg_test_desc alg_test_descs[] = {
+       {
+               .alg = "ansi_cprng",
+               .test = alg_test_cprng,
+               .fips_allowed = 1,
+               .suite = {
+                       .cprng = {
+                               .vecs = ansi_cprng_aes_tv_template,
+                               .count = ANSI_CPRNG_AES_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "cbc(aes)",
+               .test = alg_test_skcipher,
+               .fips_allowed = 1,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = aes_cbc_enc_tv_template,
+                                       .count = AES_CBC_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = aes_cbc_dec_tv_template,
+                                       .count = AES_CBC_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "cbc(anubis)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = anubis_cbc_enc_tv_template,
+                                       .count = ANUBIS_CBC_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = anubis_cbc_dec_tv_template,
+                                       .count = ANUBIS_CBC_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "cbc(blowfish)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = bf_cbc_enc_tv_template,
+                                       .count = BF_CBC_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = bf_cbc_dec_tv_template,
+                                       .count = BF_CBC_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "cbc(camellia)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = camellia_cbc_enc_tv_template,
+                                       .count = CAMELLIA_CBC_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = camellia_cbc_dec_tv_template,
+                                       .count = CAMELLIA_CBC_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "cbc(des)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = des_cbc_enc_tv_template,
+                                       .count = DES_CBC_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = des_cbc_dec_tv_template,
+                                       .count = DES_CBC_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "cbc(des3_ede)",
+               .test = alg_test_skcipher,
+               .fips_allowed = 1,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = des3_ede_cbc_enc_tv_template,
+                                       .count = DES3_EDE_CBC_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = des3_ede_cbc_dec_tv_template,
+                                       .count = DES3_EDE_CBC_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "cbc(twofish)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = tf_cbc_enc_tv_template,
+                                       .count = TF_CBC_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = tf_cbc_dec_tv_template,
+                                       .count = TF_CBC_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ccm(aes)",
+               .test = alg_test_aead,
+               .fips_allowed = 1,
+               .suite = {
+                       .aead = {
+                               .enc = {
+                                       .vecs = aes_ccm_enc_tv_template,
+                                       .count = AES_CCM_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = aes_ccm_dec_tv_template,
+                                       .count = AES_CCM_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "crc32c",
+               .test = alg_test_crc32c,
+               .fips_allowed = 1,
+               .suite = {
+                       .hash = {
+                               .vecs = crc32c_tv_template,
+                               .count = CRC32C_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "ctr(aes)",
+               .test = alg_test_skcipher,
+               .fips_allowed = 1,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = aes_ctr_enc_tv_template,
+                                       .count = AES_CTR_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = aes_ctr_dec_tv_template,
+                                       .count = AES_CTR_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "cts(cbc(aes))",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = cts_mode_enc_tv_template,
+                                       .count = CTS_MODE_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = cts_mode_dec_tv_template,
+                                       .count = CTS_MODE_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "deflate",
+               .test = alg_test_comp,
+               .suite = {
+                       .comp = {
+                               .comp = {
+                                       .vecs = deflate_comp_tv_template,
+                                       .count = DEFLATE_COMP_TEST_VECTORS
+                               },
+                               .decomp = {
+                                       .vecs = deflate_decomp_tv_template,
+                                       .count = DEFLATE_DECOMP_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(aes)",
+               .test = alg_test_skcipher,
+               .fips_allowed = 1,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = aes_enc_tv_template,
+                                       .count = AES_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = aes_dec_tv_template,
+                                       .count = AES_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(anubis)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = anubis_enc_tv_template,
+                                       .count = ANUBIS_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = anubis_dec_tv_template,
+                                       .count = ANUBIS_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(arc4)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = arc4_enc_tv_template,
+                                       .count = ARC4_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = arc4_dec_tv_template,
+                                       .count = ARC4_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(blowfish)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = bf_enc_tv_template,
+                                       .count = BF_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = bf_dec_tv_template,
+                                       .count = BF_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(camellia)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = camellia_enc_tv_template,
+                                       .count = CAMELLIA_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = camellia_dec_tv_template,
+                                       .count = CAMELLIA_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(cast5)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = cast5_enc_tv_template,
+                                       .count = CAST5_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = cast5_dec_tv_template,
+                                       .count = CAST5_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(cast6)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = cast6_enc_tv_template,
+                                       .count = CAST6_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = cast6_dec_tv_template,
+                                       .count = CAST6_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(des)",
+               .test = alg_test_skcipher,
+               .fips_allowed = 1,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = des_enc_tv_template,
+                                       .count = DES_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = des_dec_tv_template,
+                                       .count = DES_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(des3_ede)",
+               .test = alg_test_skcipher,
+               .fips_allowed = 1,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = des3_ede_enc_tv_template,
+                                       .count = DES3_EDE_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = des3_ede_dec_tv_template,
+                                       .count = DES3_EDE_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(khazad)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = khazad_enc_tv_template,
+                                       .count = KHAZAD_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = khazad_dec_tv_template,
+                                       .count = KHAZAD_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(seed)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = seed_enc_tv_template,
+                                       .count = SEED_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = seed_dec_tv_template,
+                                       .count = SEED_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(serpent)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = serpent_enc_tv_template,
+                                       .count = SERPENT_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = serpent_dec_tv_template,
+                                       .count = SERPENT_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(tea)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = tea_enc_tv_template,
+                                       .count = TEA_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = tea_dec_tv_template,
+                                       .count = TEA_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(tnepres)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = tnepres_enc_tv_template,
+                                       .count = TNEPRES_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = tnepres_dec_tv_template,
+                                       .count = TNEPRES_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(twofish)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = tf_enc_tv_template,
+                                       .count = TF_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = tf_dec_tv_template,
+                                       .count = TF_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(xeta)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = xeta_enc_tv_template,
+                                       .count = XETA_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = xeta_dec_tv_template,
+                                       .count = XETA_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(xtea)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = xtea_enc_tv_template,
+                                       .count = XTEA_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = xtea_dec_tv_template,
+                                       .count = XTEA_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "gcm(aes)",
+               .test = alg_test_aead,
+               .fips_allowed = 1,
+               .suite = {
+                       .aead = {
+                               .enc = {
+                                       .vecs = aes_gcm_enc_tv_template,
+                                       .count = AES_GCM_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = aes_gcm_dec_tv_template,
+                                       .count = AES_GCM_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "hmac(md5)",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = hmac_md5_tv_template,
+                               .count = HMAC_MD5_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "hmac(rmd128)",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = hmac_rmd128_tv_template,
+                               .count = HMAC_RMD128_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "hmac(rmd160)",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = hmac_rmd160_tv_template,
+                               .count = HMAC_RMD160_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "hmac(sha1)",
+               .test = alg_test_hash,
+               .fips_allowed = 1,
+               .suite = {
+                       .hash = {
+                               .vecs = hmac_sha1_tv_template,
+                               .count = HMAC_SHA1_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "hmac(sha224)",
+               .test = alg_test_hash,
+               .fips_allowed = 1,
+               .suite = {
+                       .hash = {
+                               .vecs = hmac_sha224_tv_template,
+                               .count = HMAC_SHA224_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "hmac(sha256)",
+               .test = alg_test_hash,
+               .fips_allowed = 1,
+               .suite = {
+                       .hash = {
+                               .vecs = hmac_sha256_tv_template,
+                               .count = HMAC_SHA256_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "hmac(sha384)",
+               .test = alg_test_hash,
+               .fips_allowed = 1,
+               .suite = {
+                       .hash = {
+                               .vecs = hmac_sha384_tv_template,
+                               .count = HMAC_SHA384_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "hmac(sha512)",
+               .test = alg_test_hash,
+               .fips_allowed = 1,
+               .suite = {
+                       .hash = {
+                               .vecs = hmac_sha512_tv_template,
+                               .count = HMAC_SHA512_TEST_VECTORS
+                       }
+               }
+#if !defined(CONFIG_CRYPTO_DEV_AES) && !defined(CONFIG_CRYPTO_ASYNC_AES)
+       }, {
+               .alg = "lrw(aes)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = aes_lrw_enc_tv_template,
+                                       .count = AES_LRW_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = aes_lrw_dec_tv_template,
+                                       .count = AES_LRW_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+#endif
+       }, {
+               .alg = "lzo",
+               .test = alg_test_comp,
+               .suite = {
+                       .comp = {
+                               .comp = {
+                                       .vecs = lzo_comp_tv_template,
+                                       .count = LZO_COMP_TEST_VECTORS
+                               },
+                               .decomp = {
+                                       .vecs = lzo_decomp_tv_template,
+                                       .count = LZO_DECOMP_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "md4",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = md4_tv_template,
+                               .count = MD4_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "md5",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = md5_tv_template,
+                               .count = MD5_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "michael_mic",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = michael_mic_tv_template,
+                               .count = MICHAEL_MIC_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "pcbc(fcrypt)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = fcrypt_pcbc_enc_tv_template,
+                                       .count = FCRYPT_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = fcrypt_pcbc_dec_tv_template,
+                                       .count = FCRYPT_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+
+       }, {
+               .alg = "rfc3686(ctr(aes))",
+               .test = alg_test_skcipher,
+               .fips_allowed = 1,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = aes_ctr_rfc3686_enc_tv_template,
+                                       .count = AES_CTR_3686_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = aes_ctr_rfc3686_dec_tv_template,
+                                       .count = AES_CTR_3686_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "rfc4309(ccm(aes))",
+               .test = alg_test_aead,
+               .fips_allowed = 1,
+               .suite = {
+                       .aead = {
+                               .enc = {
+                                       .vecs = aes_ccm_rfc4309_enc_tv_template,
+                                       .count = AES_CCM_4309_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = aes_ccm_rfc4309_dec_tv_template,
+                                       .count = AES_CCM_4309_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "rmd128",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = rmd128_tv_template,
+                               .count = RMD128_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "rmd160",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = rmd160_tv_template,
+                               .count = RMD160_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "rmd256",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = rmd256_tv_template,
+                               .count = RMD256_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "rmd320",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = rmd320_tv_template,
+                               .count = RMD320_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "salsa20",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = salsa20_stream_enc_tv_template,
+                                       .count = SALSA20_STREAM_ENC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "sha1",
+               .test = alg_test_hash,
+               .fips_allowed = 1,
+               .suite = {
+                       .hash = {
+                               .vecs = sha1_tv_template,
+                               .count = SHA1_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "sha224",
+               .test = alg_test_hash,
+               .fips_allowed = 1,
+               .suite = {
+                       .hash = {
+                               .vecs = sha224_tv_template,
+                               .count = SHA224_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "sha256",
+               .test = alg_test_hash,
+               .fips_allowed = 1,
+               .suite = {
+                       .hash = {
+                               .vecs = sha256_tv_template,
+                               .count = SHA256_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "sha384",
+               .test = alg_test_hash,
+               .fips_allowed = 1,
+               .suite = {
+                       .hash = {
+                               .vecs = sha384_tv_template,
+                               .count = SHA384_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "sha512",
+               .test = alg_test_hash,
+               .fips_allowed = 1,
+               .suite = {
+                       .hash = {
+                               .vecs = sha512_tv_template,
+                               .count = SHA512_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "tgr128",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = tgr128_tv_template,
+                               .count = TGR128_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "tgr160",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = tgr160_tv_template,
+                               .count = TGR160_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "tgr192",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = tgr192_tv_template,
+                               .count = TGR192_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "vmac(aes)",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = aes_vmac128_tv_template,
+                               .count = VMAC_AES_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "wp256",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = wp256_tv_template,
+                               .count = WP256_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "wp384",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = wp384_tv_template,
+                               .count = WP384_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "wp512",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = wp512_tv_template,
+                               .count = WP512_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "xcbc(aes)",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = aes_xcbc128_tv_template,
+                               .count = XCBC_AES_TEST_VECTORS
+                       }
+               }
+#if 0
+       }, {
+               .alg = "xts(aes)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = aes_xts_enc_tv_template,
+                                       .count = AES_XTS_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = aes_xts_dec_tv_template,
+                                       .count = AES_XTS_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+#endif
+       }, {
+               .alg = "zlib",
+               .test = alg_test_pcomp,
+               .suite = {
+                       .pcomp = {
+                               .comp = {
+                                       .vecs = zlib_comp_tv_template,
+                                       .count = ZLIB_COMP_TEST_VECTORS
+                               },
+                               .decomp = {
+                                       .vecs = zlib_decomp_tv_template,
+                                       .count = ZLIB_DECOMP_TEST_VECTORS
+                               }
+                       }
+               }
+       }
+};
+
+static int alg_find_test(const char *alg)
+{
+       int start = 0;
+       int end = ARRAY_SIZE(alg_test_descs);
+
+       while (start < end) {
+               int i = (start + end) / 2;
+               int diff = strcmp(alg_test_descs[i].alg, alg);
+
+               if (diff > 0) {
+                       end = i;
+                       continue;
+               }
+
+               if (diff < 0) {
+                       start = i + 1;
+                       continue;
+               }
+
+               return i;
+       }
+
+       return -1;
+}
+
+static int ifx_alg_test(const char *driver, const char *alg, u32 type, u32 mask)
+{
+       int i;
+       int j;
+       int rc;
+
+       if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) {
+               char nalg[CRYPTO_MAX_ALG_NAME];
+
+               if (snprintf(nalg, sizeof(nalg), "ecb(%s)", alg) >=
+                   sizeof(nalg))
+                       return -ENAMETOOLONG;
+
+               i = alg_find_test(nalg);
+               if (i < 0)
+                       goto notest;
+
+               if (fips_enabled && !alg_test_descs[i].fips_allowed)
+                       goto non_fips_alg;
+
+               rc = alg_test_cipher(alg_test_descs + i, driver, type, mask);
+               goto test_done;
+       }
+
+       i = alg_find_test(alg);
+       j = alg_find_test(driver);
+       if (i < 0 && j < 0)
+               goto notest;
+
+       if (fips_enabled && ((i >= 0 && !alg_test_descs[i].fips_allowed) ||
+                            (j >= 0 && !alg_test_descs[j].fips_allowed)))
+               goto non_fips_alg;
+
+       rc = 0;
+       if (i >= 0)
+               rc |= alg_test_descs[i].test(alg_test_descs + i, driver,
+                                            type, mask);
+       if (j >= 0)
+               rc |= alg_test_descs[j].test(alg_test_descs + j, driver,
+                                            type, mask);
+
+test_done:
+       if (fips_enabled && rc)
+               panic("%s: %s alg self test failed in fips mode!\n", driver, alg);
+
+       if (fips_enabled && !rc)
+               printk(KERN_INFO "alg: self-tests for %s (%s) passed\n",
+                      driver, alg);
+
+       return rc;
+
+notest:
+       printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver);
+       return 0;
+non_fips_alg:
+       return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(ifx_alg_test);
+
+/* Modified speed test for async block cipher mode*/
+
+static int ifx_alg_speed_test(const char *driver, const char *alg, 
+                  unsigned int sec,
+                  struct cipher_speed_template *template,
+                  unsigned int tcount, u8 *keysize)
+{
+       int i;
+       int j;
+       int err;
+       int type = 0, mask = 0;
+       struct crypto_ablkcipher *tfm;
+
+       i = alg_find_test(alg);
+       j = alg_find_test(driver);
+
+       if (i < 0 && j < 0)
+               goto notest;
+
+       if (fips_enabled && ((i >= 0 && !alg_test_descs[i].fips_allowed) ||
+                            (j >= 0 && !alg_test_descs[j].fips_allowed)))
+               goto non_fips_alg;
+
+       tfm = crypto_alloc_ablkcipher(driver, type, mask);
+
+       if (IS_ERR(tfm)) {
+               printk(KERN_ERR "alg: skcipher: Failed to load transform for "
+                      "%s: %ld\n", driver, PTR_ERR(tfm));
+               return PTR_ERR(tfm);
+       }
+        err = test_skcipher_speed(tfm, ENCRYPT, template,
+                                         tcount, sec, keysize);
+        if (err)
+           goto test_done;
+
+               err = test_skcipher_speed(tfm, DECRYPT, template,
+                                          tcount, sec, keysize);
+       if (!err)
+          goto test_done;
+
+notest:
+       return 0;
+non_fips_alg:
+       return -EINVAL;
+
+test_done:
+       if (fips_enabled && err)
+               panic("%s: %s alg self test failed in fips mode!\n", driver, alg);
+
+       if (fips_enabled && !err)
+               printk(KERN_INFO "alg: self-tests for %s (%s) passed\n",
+                      driver, alg);
+
+        crypto_free_ablkcipher(tfm);
+       return err;
+}
+EXPORT_SYMBOL_GPL(ifx_alg_speed_test);
+
+
+static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc,
+                              struct scatterlist *sg, int blen, int sec)
+{
+       unsigned long start, end;
+       int bcount;
+       int ret;
+
+       for (start = jiffies, end = start + sec * HZ, bcount = 0;
+            time_before(jiffies, end); bcount++) {
+               if (enc)
+                       ret = crypto_blkcipher_encrypt(desc, sg, sg, blen);
+               else
+                       ret = crypto_blkcipher_decrypt(desc, sg, sg, blen);
+
+               if (ret)
+                       return ret;
+       }
+
+       printk("%d operations in %d seconds (%ld bytes)\n",
+              bcount, sec, (long)bcount * blen);
+       return 0;
+}
+
+static int test_cipher_cycles(struct blkcipher_desc *desc, int enc,
+                             struct scatterlist *sg, int blen)
+{
+       unsigned long cycles = 0;
+        unsigned long start, end;
+       int ret = 0;
+       int i;
+
+       local_bh_disable();
+       local_irq_disable();
+
+       /* Warm-up run. */
+       for (i = 0; i < 4; i++) {
+               if (enc)
+                       ret = crypto_blkcipher_encrypt(desc, sg, sg, blen);
+               else
+                       ret = crypto_blkcipher_decrypt(desc, sg, sg, blen);
+
+               if (ret)
+                       goto out;
+       }
+
+       /* The real thing. */
+       for (i = 0; i < 8; i++) {
+                /* Original code to get cycles, does not work with MIPS
+                * cycles_t start, end;
+                 * start = get_cycles();
+                 */
+                
+                start = read_c0_count(); // LQ modified tcrypt      
+
+               if (enc)
+                       ret = crypto_blkcipher_encrypt(desc, sg, sg, blen);
+               else
+                       ret = crypto_blkcipher_decrypt(desc, sg, sg, blen);
+               
+                /* Original code to get cycles, does not work with MIPS
+                 * end = get_cycles();
+                 */
+
+                end = read_c0_count(); //LQ modified tcrypt
+
+               if (ret)
+                       goto out;
+
+               cycles += end - start;
+       }
+
+out:
+       local_irq_enable();
+       local_bh_enable();
+
+       if (ret == 0)
+               printk("1 operation in %lu cycles (%d bytes)\n",
+                      (cycles + 4) / 8, blen);
+
+       return ret;
+}
+
+static u32 block_sizes[] = { 16, 64, 256, 1024, 8192, 0 };
+
+static void test_cipher_speed(const char *algo, int enc, unsigned int sec,
+                             struct cipher_speed_template *template,
+                             unsigned int tcount, u8 *keysize)
+{
+       unsigned int ret, i, j, iv_len;
+       const char *key, iv[128];
+       struct crypto_blkcipher *tfm;
+       struct blkcipher_desc desc;
+       const char *e;
+       u32 *b_size;
+
+       if (enc == ENCRYPT)
+               e = "encryption";
+       else
+               e = "decryption";
+
+       printk("\n ******* testing speed of %s %s ******* \n", algo, e);
+
+       tfm = crypto_alloc_blkcipher(algo, 0, CRYPTO_ALG_ASYNC);
+
+       if (IS_ERR(tfm)) {
+               printk("failed to load transform for %s: %ld\n", algo,
+                      PTR_ERR(tfm));
+               return;
+       }
+       desc.tfm = tfm;
+       desc.flags = 0;
+
+       i = 0;
+       do {
+
+               b_size = block_sizes;
+               do {
+                       struct scatterlist sg[TVMEMSIZE];
+
+                       if ((*keysize + *b_size) > TVMEMSIZE * PAGE_SIZE) {
+                               printk("template (%u) too big for "
+                                      "tvmem (%lu)\n", *keysize + *b_size,
+                                      TVMEMSIZE * PAGE_SIZE);
+                               goto out;
+                       }
+
+                       printk("test %u (%d bit key, %d byte blocks): ", i,
+                                       *keysize * 8, *b_size);
+
+                       memset(tvmem[0], 0xff, PAGE_SIZE);
+
+                       /* set key, plain text and IV */
+                       key = tvmem[0];
+                       for (j = 0; j < tcount; j++) {
+                               if (template[j].klen == *keysize) {
+                                       key = template[j].key;
+                                       break;
+                               }
+                       }
+
+                       ret = crypto_blkcipher_setkey(tfm, key, *keysize);
+                       if (ret) {
+                               printk("setkey() failed flags=%x\n",
+                                               crypto_blkcipher_get_flags(tfm));
+                               goto out;
+                       }
+
+                       sg_init_table(sg, TVMEMSIZE);
+                       sg_set_buf(sg, tvmem[0] + *keysize,
+                                  PAGE_SIZE - *keysize);
+                       for (j = 1; j < TVMEMSIZE; j++) {
+                               sg_set_buf(sg + j, tvmem[j], PAGE_SIZE);
+                               memset (tvmem[j], 0xff, PAGE_SIZE);
+                       }
+
+                       iv_len = crypto_blkcipher_ivsize(tfm);
+                       if (iv_len) {
+                               memset(&iv, 0xff, iv_len);
+                               crypto_blkcipher_set_iv(tfm, iv, iv_len);
+                       }
+
+                       if (sec)
+                               ret = test_cipher_jiffies(&desc, enc, sg,
+                                                         *b_size, sec);
+                       else
+                               ret = test_cipher_cycles(&desc, enc, sg,
+                                                        *b_size);
+
+                       if (ret) {
+                               printk("%s() failed flags=%x\n", e, desc.flags);
+                               break;
+                       }
+                       b_size++;
+                       i++;
+               } while (*b_size);
+               keysize++;
+       } while (*keysize);
+
+out:
+       crypto_free_blkcipher(tfm);
+}
+
+static int test_hash_jiffies_digest(struct hash_desc *desc,
+                                   struct scatterlist *sg, int blen,
+                                   char *out, int sec)
+{
+       unsigned long start, end;
+       int bcount;
+       int ret;
+
+       for (start = jiffies, end = start + sec * HZ, bcount = 0;
+            time_before(jiffies, end); bcount++) {
+               ret = crypto_hash_digest(desc, sg, blen, out);
+               if (ret)
+                       return ret;
+       }
+
+       printk("%6u opers/sec, %9lu bytes/sec\n",
+              bcount / sec, ((long)bcount * blen) / sec);
+
+       return 0;
+}
+
+static int test_hash_jiffies(struct hash_desc *desc, struct scatterlist *sg,
+                            int blen, int plen, char *out, int sec)
+{
+       unsigned long start, end;
+       int bcount, pcount;
+       int ret;
+
+       if (plen == blen)
+               return test_hash_jiffies_digest(desc, sg, blen, out, sec);
+
+       for (start = jiffies, end = start + sec * HZ, bcount = 0;
+            time_before(jiffies, end); bcount++) {
+               ret = crypto_hash_init(desc);
+               if (ret)
+                       return ret;
+               for (pcount = 0; pcount < blen; pcount += plen) {
+                       ret = crypto_hash_update(desc, sg, plen);
+                       if (ret)
+                               return ret;
+               }
+               /* we assume there is enough space in 'out' for the result */
+               ret = crypto_hash_final(desc, out);
+               if (ret)
+                       return ret;
+       }
+
+       printk("%6u opers/sec, %9lu bytes/sec\n",
+              bcount / sec, ((long)bcount * blen) / sec);
+
+       return 0;
+}
+
+static int test_hash_cycles_digest(struct hash_desc *desc,
+                                  struct scatterlist *sg, int blen, char *out)
+{
+       unsigned long cycles = 0;
+        unsigned long start, end;
+       int i;
+       int ret;
+
+       local_bh_disable();
+       local_irq_disable();
+
+       /* Warm-up run. */
+       for (i = 0; i < 4; i++) {
+               ret = crypto_hash_digest(desc, sg, blen, out);
+               if (ret)
+                       goto out;
+       }
+
+       /* The real thing. */
+       for (i = 0; i < 8; i++) {
+                
+                /* Original code to get cycles, does not work with MIPS
+                * cycles_t start, end;
+                 * start = get_cycles();
+                 */
+
+                start = read_c0_count(); // LQ modified tcrypt
+
+               ret = crypto_hash_digest(desc, sg, blen, out);
+               if (ret)
+                       goto out;
+
+                /* Original code to get cycles, does not work with MIPS
+                * end = get_cycles();
+                 */
+
+                 end = read_c0_count(); // LQ modified tcrypt
+
+               cycles += end - start;
+       }
+
+out:
+       local_irq_enable();
+       local_bh_enable();
+
+       if (ret)
+               return ret;
+
+       printk("%6lu cycles/operation, %4lu cycles/byte\n",
+              cycles / 8, cycles / (8 * blen));
+
+       return 0;
+}
+
+static int test_hash_cycles(struct hash_desc *desc, struct scatterlist *sg,
+                           int blen, int plen, char *out)
+{
+       unsigned long cycles = 0;
+        unsigned long start, end;
+       int i, pcount;
+       int ret;
+
+       if (plen == blen)
+               return test_hash_cycles_digest(desc, sg, blen, out);
+
+       local_bh_disable();
+       local_irq_disable();
+
+       /* Warm-up run. */
+       for (i = 0; i < 4; i++) {
+               ret = crypto_hash_init(desc);
+               if (ret)
+                       goto out;
+               for (pcount = 0; pcount < blen; pcount += plen) {
+                       ret = crypto_hash_update(desc, sg, plen);
+                       if (ret)
+                               goto out;
+               }
+               ret = crypto_hash_final(desc, out);
+               if (ret)
+                       goto out;
+       }
+
+       /* The real thing. */
+       for (i = 0; i < 8; i++) {
+              
+                /* Original code for getting cycles, not working for MIPS
+                 * cycle_t start, end;
+                * end = get_cycles();
+                 */
+                
+               start = read_c0_count(); // LQ modified tcrypt
+
+               ret = crypto_hash_init(desc);
+               if (ret)
+                       goto out;
+               for (pcount = 0; pcount < blen; pcount += plen) {
+                       ret = crypto_hash_update(desc, sg, plen);
+                       if (ret)
+                               goto out;
+               }
+               ret = crypto_hash_final(desc, out);
+               if (ret)
+                       goto out;
+
+                /* Original code for getting cycles, not working for MIPS
+                * end = get_cycles();
+                 */ 
+
+                end = read_c0_count(); // LQ modified tcrypt
+
+               cycles += end - start;
+       }
+
+out:
+       local_irq_enable();
+       local_bh_enable();
+
+       if (ret)
+               return ret;
+
+       printk("%6lu cycles/operation, %4lu cycles/byte\n",
+              cycles / 8, cycles / (8 * blen));
+
+       return 0;
+}
+
+static void test_hash_speed(const char *algo, unsigned int sec,
+                           struct hash_speed *speed)
+{
+       struct scatterlist sg[TVMEMSIZE];
+       struct crypto_hash *tfm;
+       struct hash_desc desc;
+       static char output[1024];
+       int i;
+       int ret;
+
+       printk(KERN_INFO "\ntesting speed of %s\n", algo);
+
+       tfm = crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC);
+
+       if (IS_ERR(tfm)) {
+               printk(KERN_ERR "failed to load transform for %s: %ld\n", algo,
+                      PTR_ERR(tfm));
+               return;
+       }
+
+       desc.tfm = tfm;
+       desc.flags = 0;
+
+       if (crypto_hash_digestsize(tfm) > sizeof(output)) {
+               printk(KERN_ERR "digestsize(%u) > outputbuffer(%zu)\n",
+                      crypto_hash_digestsize(tfm), sizeof(output));
+               goto out;
+       }
+
+       sg_init_table(sg, TVMEMSIZE);
+       for (i = 0; i < TVMEMSIZE; i++) {
+               sg_set_buf(sg + i, tvmem[i], PAGE_SIZE);
+               memset(tvmem[i], 0xff, PAGE_SIZE);
+       }
+
+       for (i = 0; speed[i].blen != 0; i++) {
+               if (speed[i].blen > TVMEMSIZE * PAGE_SIZE) {
+                       printk(KERN_ERR
+                              "template (%u) too big for tvmem (%lu)\n",
+                              speed[i].blen, TVMEMSIZE * PAGE_SIZE);
+                       goto out;
+               }
+
+               printk(KERN_INFO "test%3u "
+                      "(%5u byte blocks,%5u bytes per update,%4u updates): ",
+                      i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen);
+
+               if (sec)
+                       ret = test_hash_jiffies(&desc, sg, speed[i].blen,
+                                               speed[i].plen, output, sec);
+               else
+                       ret = test_hash_cycles(&desc, sg, speed[i].blen,
+                                              speed[i].plen, output);
+
+               if (ret) {
+                       printk(KERN_ERR "hashing failed ret=%d\n", ret);
+                       break;
+               }
+       }
+
+out:
+       crypto_free_hash(tfm);
+}
+
+
+static void test_available(void)
+{
+       char **name = check;
+
+       while (*name) {
+               printk("alg %s ", *name);
+               printk(crypto_has_alg(*name, 0, 0) ?
+                      "found\n" : "not found\n");
+               name++;
+       }
+}
+
+static inline int tcrypt_test(const char *alg)
+{
+       int ret;
+
+       printk("Running test %s\n", alg);
+       ret = ifx_alg_test(alg, alg, 0, 0);
+       /* non-fips algs return -EINVAL in fips mode */
+       if (fips_enabled && ret == -EINVAL)
+               ret = 0;
+       return ret;
+}
+
+static inline int tcrypt_speedtest(const char *alg,
+                                  struct cipher_speed_template *template,
+                                  unsigned int tcount, u8 *keysize)
+{
+       int ret;
+
+        printk("[****** Running speedtest %s *******]\n", alg);        
+       ret = ifx_alg_speed_test(alg, alg, sec, template, tcount, keysize);
+        if (fips_enabled && ret == -EINVAL)
+                ret = 0;
+        return ret;
+}
+
+
+static int do_test(int m)
+{
+       int i;
+       int ret = 0;
+
+       switch (m) {
+       case 0:
+               for (i = 1; i < 200; i++)
+                       ret += do_test(i);
+               break;
+
+       case 1:
+               ret += tcrypt_test("md5");
+               break;
+
+       case 2:
+               ret += tcrypt_test("sha1");
+               break;
+
+       case 3:
+               ret += tcrypt_test("ecb(des)");
+               ret += tcrypt_test("cbc(des)");
+               break;
+
+       case 4:
+               ret += tcrypt_test("ecb(des3_ede)");
+               ret += tcrypt_test("cbc(des3_ede)");
+               break;
+
+       case 5:
+               ret += tcrypt_test("md4");
+               break;
+
+       case 6:
+               ret += tcrypt_test("sha256");
+               break;
+
+       case 7:
+               ret += tcrypt_test("ecb(blowfish)");
+               ret += tcrypt_test("cbc(blowfish)");
+               break;
+
+       case 8:
+               ret += tcrypt_test("ecb(twofish)");
+               ret += tcrypt_test("cbc(twofish)");
+               break;
+
+       case 9:
+               ret += tcrypt_test("ecb(serpent)");
+               break;
+
+       case 10:
+               ret += tcrypt_test("ecb(aes)");
+               ret += tcrypt_test("cbc(aes)");
+       //      ret += tcrypt_test("lrw(aes)");
+       //      ret += tcrypt_test("xts(aes)");
+               ret += tcrypt_test("ctr(aes)");
+               ret += tcrypt_test("rfc3686(ctr(aes))");
+               break;
+
+       case 11:
+               ret += tcrypt_test("sha384");
+               break;
+
+       case 12:
+               ret += tcrypt_test("sha512");
+               break;
+
+       case 13:
+               ret += tcrypt_test("deflate");
+               break;
+
+       case 14:
+               ret += tcrypt_test("ecb(cast5)");
+               break;
+
+       case 15:
+               ret += tcrypt_test("ecb(cast6)");
+               break;
+
+       case 16:
+               ret += tcrypt_test("ecb(arc4)");
+               break;
+
+       case 17:
+               ret += tcrypt_test("michael_mic");
+               break;
+
+       case 18:
+               ret += tcrypt_test("crc32c");
+               break;
+
+       case 19:
+               ret += tcrypt_test("ecb(tea)");
+               break;
+
+       case 20:
+               ret += tcrypt_test("ecb(xtea)");
+               break;
+
+       case 21:
+               ret += tcrypt_test("ecb(khazad)");
+               break;
+
+       case 22:
+               ret += tcrypt_test("wp512");
+               break;
+
+       case 23:
+               ret += tcrypt_test("wp384");
+               break;
+
+       case 24:
+               ret += tcrypt_test("wp256");
+               break;
+
+       case 25:
+               ret += tcrypt_test("ecb(tnepres)");
+               break;
+
+       case 26:
+               ret += tcrypt_test("ecb(anubis)");
+               ret += tcrypt_test("cbc(anubis)");
+               break;
+
+       case 27:
+               ret += tcrypt_test("tgr192");
+               break;
+
+       case 28:
+
+               ret += tcrypt_test("tgr160");
+               break;
+
+       case 29:
+               ret += tcrypt_test("tgr128");
+               break;
+
+       case 30:
+               ret += tcrypt_test("ecb(xeta)");
+               break;
+
+       case 31:
+               ret += tcrypt_test("pcbc(fcrypt)");
+               break;
+
+       case 32:
+               ret += tcrypt_test("ecb(camellia)");
+               ret += tcrypt_test("cbc(camellia)");
+               break;
+       case 33:
+               ret += tcrypt_test("sha224");
+               break;
+
+       case 34:
+               ret += tcrypt_test("salsa20");
+               break;
+
+       case 35:
+               ret += tcrypt_test("gcm(aes)");
+               break;
+
+       case 36:
+               ret += tcrypt_test("lzo");
+               break;
+
+       case 37:
+               ret += tcrypt_test("ccm(aes)");
+               break;
+
+       case 38:
+               ret += tcrypt_test("cts(cbc(aes))");
+               break;
+
+        case 39:
+               ret += tcrypt_test("rmd128");
+               break;
+
+        case 40:
+               ret += tcrypt_test("rmd160");
+               break;
+
+       case 41:
+               ret += tcrypt_test("rmd256");
+               break;
+
+       case 42:
+               ret += tcrypt_test("rmd320");
+               break;
+
+       case 43:
+               ret += tcrypt_test("ecb(seed)");
+               break;
+
+       case 44:
+               ret += tcrypt_test("zlib");
+               break;
+
+       case 45:
+               ret += tcrypt_test("rfc4309(ccm(aes))");
+               break;
+
+       case 100:
+               ret += tcrypt_test("hmac(md5)");
+               break;
+
+       case 101:
+               ret += tcrypt_test("hmac(sha1)");
+               break;
+
+       case 102:
+               ret += tcrypt_test("hmac(sha256)");
+               break;
+
+       case 103:
+               ret += tcrypt_test("hmac(sha384)");
+               break;
+
+       case 104:
+               ret += tcrypt_test("hmac(sha512)");
+               break;
+
+       case 105:
+               ret += tcrypt_test("hmac(sha224)");
+               break;
+
+       case 106:
+               ret += tcrypt_test("xcbc(aes)");
+               break;
+
+       case 107:
+               ret += tcrypt_test("hmac(rmd128)");
+               break;
+
+       case 108:
+               ret += tcrypt_test("hmac(rmd160)");
+               break;
+
+       case 109:
+               ret += tcrypt_test("vmac(aes)");
+               break;
+
+       case 150:
+               ret += tcrypt_test("ansi_cprng");
+               break;
+
+       case 200:
+               test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
+                               speed_template_16_24_32);
+               test_cipher_speed("ecb(aes)", DECRYPT, sec, NULL, 0,
+                               speed_template_16_24_32);
+               test_cipher_speed("cbc(aes)", ENCRYPT, sec, NULL, 0,
+                               speed_template_16_24_32);
+               test_cipher_speed("cbc(aes)", DECRYPT, sec, NULL, 0,
+                               speed_template_16_24_32);
+#if !defined(CONFIG_CRYPTO_DEV_AES) && !defined(CONFIG_CRYPTO_ASYNC_AES)
+               test_cipher_speed("lrw(aes)", ENCRYPT, sec, NULL, 0,
+                               speed_template_32_40_48);
+               test_cipher_speed("lrw(aes)", DECRYPT, sec, NULL, 0,
+                               speed_template_32_40_48);
+               test_cipher_speed("xts(aes)", ENCRYPT, sec, NULL, 0,
+                               speed_template_32_48_64);
+               test_cipher_speed("xts(aes)", DECRYPT, sec, NULL, 0,
+                               speed_template_32_48_64);
+#endif
+               break;
+
+       case 201:
+               test_cipher_speed("ecb(des3_ede)", ENCRYPT, sec,
+                               des3_speed_template, DES3_SPEED_VECTORS,
+                               speed_template_24);
+               test_cipher_speed("ecb(des3_ede)", DECRYPT, sec,
+                               des3_speed_template, DES3_SPEED_VECTORS,
+                               speed_template_24);
+               test_cipher_speed("cbc(des3_ede)", ENCRYPT, sec,
+                               des3_speed_template, DES3_SPEED_VECTORS,
+                               speed_template_24);
+               test_cipher_speed("cbc(des3_ede)", DECRYPT, sec,
+                               des3_speed_template, DES3_SPEED_VECTORS,
+                               speed_template_24);
+               break;
+
+       case 202:
+               test_cipher_speed("ecb(twofish)", ENCRYPT, sec, NULL, 0,
+                               speed_template_16_24_32);
+               test_cipher_speed("ecb(twofish)", DECRYPT, sec, NULL, 0,
+                               speed_template_16_24_32);
+               test_cipher_speed("cbc(twofish)", ENCRYPT, sec, NULL, 0,
+                               speed_template_16_24_32);
+               test_cipher_speed("cbc(twofish)", DECRYPT, sec, NULL, 0,
+                               speed_template_16_24_32);
+               break;
+
+       case 203:
+               test_cipher_speed("ecb(blowfish)", ENCRYPT, sec, NULL, 0,
+                                 speed_template_8_32);
+               test_cipher_speed("ecb(blowfish)", DECRYPT, sec, NULL, 0,
+                                 speed_template_8_32);
+               test_cipher_speed("cbc(blowfish)", ENCRYPT, sec, NULL, 0,
+                                 speed_template_8_32);
+               test_cipher_speed("cbc(blowfish)", DECRYPT, sec, NULL, 0,
+                                 speed_template_8_32);
+               break;
+
+       case 204:
+               test_cipher_speed("ecb(des)", ENCRYPT, sec, NULL, 0,
+                                 speed_template_8);
+               test_cipher_speed("ecb(des)", DECRYPT, sec, NULL, 0,
+                                 speed_template_8);
+               test_cipher_speed("cbc(des)", ENCRYPT, sec, NULL, 0,
+                                 speed_template_8);
+               test_cipher_speed("cbc(des)", DECRYPT, sec, NULL, 0,
+                                 speed_template_8);
+               break;
+
+       case 205:
+               test_cipher_speed("ecb(camellia)", ENCRYPT, sec, NULL, 0,
+                               speed_template_16_24_32);
+               test_cipher_speed("ecb(camellia)", DECRYPT, sec, NULL, 0,
+                               speed_template_16_24_32);
+               test_cipher_speed("cbc(camellia)", ENCRYPT, sec, NULL, 0,
+                               speed_template_16_24_32);
+               test_cipher_speed("cbc(camellia)", DECRYPT, sec, NULL, 0,
+                               speed_template_16_24_32);
+               break;
+
+       case 206:
+               test_cipher_speed("salsa20", ENCRYPT, sec, NULL, 0,
+                                 speed_template_16_32);
+               break;
+
+       case 300:
+               /* fall through */
+
+       case 301:
+               test_hash_speed("md4", sec, generic_hash_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 302:
+               test_hash_speed("md5", sec, generic_hash_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 303:
+               test_hash_speed("sha1", sec, generic_hash_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 304:
+               test_hash_speed("sha256", sec, generic_hash_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 305:
+               test_hash_speed("sha384", sec, generic_hash_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 306:
+               test_hash_speed("sha512", sec, generic_hash_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 307:
+               test_hash_speed("wp256", sec, generic_hash_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 308:
+               test_hash_speed("wp384", sec, generic_hash_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 309:
+               test_hash_speed("wp512", sec, generic_hash_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 310:
+               test_hash_speed("tgr128", sec, generic_hash_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 311:
+               test_hash_speed("tgr160", sec, generic_hash_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 312:
+               test_hash_speed("tgr192", sec, generic_hash_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 313:
+               test_hash_speed("sha224", sec, generic_hash_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 314:
+               test_hash_speed("rmd128", sec, generic_hash_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 315:
+               test_hash_speed("rmd160", sec, generic_hash_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 316:
+               test_hash_speed("rmd256", sec, generic_hash_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 317:
+               test_hash_speed("rmd320", sec, generic_hash_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 399:
+               break;
+
+        /* Modified speed test for async block cipher mode */
+        case 400:
+               tcrypt_speedtest("ecb(aes)", NULL, 0,
+                                speed_template_16_24_32);
+               tcrypt_speedtest("cbc(aes)", NULL, 0,
+                               speed_template_16_24_32);
+               break;
+
+       case 401:
+               tcrypt_speedtest("ecb(des3_ede)", des3_speed_template, 
+                               DES3_SPEED_VECTORS,speed_template_24);
+               tcrypt_speedtest("cbc(des3_ede)", des3_speed_template, 
+                               DES3_SPEED_VECTORS,speed_template_24);
+               break;
+
+       case 404:
+               tcrypt_speedtest("ecb(des)", NULL, 0, 
+                               speed_template_8);
+               tcrypt_speedtest("cbc(des)", NULL, 0, 
+                               speed_template_8);
+               break;
+
+       case 1000:
+               test_available();
+               break;
+       }
+
+       return ret;
+}
+#if !defined(CONFIG_CRYPTO_DEV_DEU)
+static int do_alg_test(const char *alg, u32 type, u32 mask)
+{
+       return crypto_has_alg(alg, type, mask ?: CRYPTO_ALG_TYPE_MASK) ?
+              0 : -ENOENT;
+}
+#endif
+
+static int __init tcrypt_mod_init(void)
+{
+       int err = -ENOMEM;
+       int i;
+
+       printk("Starting Lantiq DEU Crypto TESTS . . . . . . .\n");
+
+       for (i = 0; i < TVMEMSIZE; i++) {
+               tvmem[i] = (void *)__get_free_page(GFP_KERNEL);
+               if (!tvmem[i])
+                       goto err_free_tv;
+       }
+
+#if defined(CONFIG_CRYPTO_DEV_DEU)
+#if defined(CONFIG_CRYPTO_DEV_MD5)
+        mode = 1; // test md5 only
+        err = do_test(mode);
+        if (err)
+            goto md5_err;
+
+md5_err:       
+       if (err) {
+                printk(KERN_ERR "md5: one or more tests failed!\n");
+                goto err_free_tv;
+        }
+#endif
+#if defined(CONFIG_CRYPTO_DEV_SHA1)
+        mode = 2; // test sha1 only
+        err = do_test(mode);
+        if (err)
+            goto sha1_err;
+
+sha1_err:
+       if (err) {
+                printk(KERN_ERR "sha1: one or more tests failed!\n");
+                goto err_free_tv;
+        }
+#endif
+#if defined (CONFIG_CRYPTO_DEV_DES) || defined (CONFIG_CRYPTO_ASYNC_DES)
+        mode = 3; // test des only
+        err = do_test(mode);
+       if (err) 
+            goto des_err;
+       
+        mode = 4; // test des3 only
+        err = do_test(mode);
+        if (err)
+            goto des_err;
+
+des_err:
+       if (err) {
+                printk(KERN_ERR "des3: one or more tests failed!\n");
+                goto err_free_tv;
+        }
+#endif
+#if defined (CONFIG_CRYPTO_ASYNC_AES) ||  defined (CONFIG_CRYPTO_DEV_AES)                 
+       mode = 10; // test aes only
+        err = do_test(mode);
+        if (err)
+             goto aes_err;
+
+aes_err:
+       if (err) {
+                printk(KERN_ERR "aes: one or more tests failed!\n");
+                goto err_free_tv;
+        }
+#endif
+#if defined(CONFIG_CRYPTO_DEV_ARC4)
+       mode = 16;
+       err = do_test(mode);
+
+       if (err) {
+                printk(KERN_ERR "arc4: one or more tests failed!\n");
+                goto err_free_tv;
+        }
+#endif
+#if defined (CONFIG_CRYPTO_DEV_MD5_HMAC)       
+       mode = 100;
+       err = do_test(mode);
+
+       if (err) {
+                printk(KERN_ERR "tcrypt: one or more tests failed!\n");
+                goto err_free_tv;
+        }
+#endif
+#if defined (CONFIG_CRYPTO_DEV_SHA1_HMAC)      
+        mode = 101;
+       err = do_test(mode);
+
+       if (err) {
+                printk(KERN_ERR "tcrypt: one or more tests failed!\n");
+                goto err_free_tv;
+        }
+#endif
+
+/* Start Speed tests test modes */
+#if defined(CONFIG_CRYPTO_DEV_SPEED_TEST)
+#if   defined(CONFIG_CRYPTO_DEV_AES) 
+     mode = 200;
+     err = do_test(mode);
+     if (err) 
+         goto speed_err;
+#endif
+#if   defined (CONFIG_CRYPTO_DEV_DES)
+      mode = 201;
+      err = do_test(mode);  
+      if (err)
+         goto speed_err;
+
+      mode = 204;
+      err = do_test(mode);  
+      if (err)
+         goto speed_err;
+#endif
+#if defined (CONFIG_CRYPTO_DEV_MD5)
+      mode = 302;
+      err = do_test(mode);
+      if (err)
+          goto speed_err;  
+#endif 
+#if defined (CONFIG_CRYPTO_DEV_SHA1)
+      mode = 303;
+      err = do_test(mode); 
+      if (err)
+          goto speed_err;
+#endif
+      printk("Speed tests finished successfully\n"); 
+      goto fips_check;
+
+speed_err:
+       printk(KERN_ERR "tcrypt: one or more tests failed!\n");
+        goto err_free_tv;
+#endif /* CONFIG_CRYPTO_DEV_SPEED_TEST */
+
+#else
+       if (alg)
+               err = do_alg_test(alg, type, mask);
+       else
+               err = do_test(mode);
+
+       if (err) {
+               printk(KERN_ERR "tcrypt: one or more tests failed!\n");
+               goto err_free_tv;
+       }
+#endif /* CONFIG_CRYPTO_DEV_DEU */
+
+fips_check:
+       /* We intentionaly return -EAGAIN to prevent keeping the module,
+        * unless we're running in fips mode. It does all its work from
+        * init() and doesn't offer any runtime functionality, but in
+        * the fips case, checking for a successful load is helpful.
+        * => we don't need it in the memory, do we?
+        *                                        -- mludvig
+        */
+       if (!fips_enabled)
+               err = -EAGAIN;
+
+err_free_tv:
+       for (i = 0; i < TVMEMSIZE && tvmem[i]; i++ ){
+               printk("Freeing page: %d\n", i);
+               free_page((unsigned long)tvmem[i]);
+       }
+
+       printk("Finished DEU testing . . . . . .\n");
+       return err;
+}
+
+/*
+ * If an init function is provided, an exit function must also be provided
+ * to allow module unload.
+ */
+static void __exit tcrypt_mod_fini(void) {}
+
+
+module_init(tcrypt_mod_init);
+module_exit(tcrypt_mod_fini);
+
+module_param(alg, charp, 0);
+module_param(type, uint, 0);
+module_param(mask, uint, 0);
+module_param(mode, int, 0);
+module_param(sec, uint, 0);
+MODULE_PARM_DESC(sec, "Length in seconds of speed tests "
+                     "(defaults to zero which uses CPU cycles instead)");
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Quick & dirty crypto testing module");
+MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
+