public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/2] staging: skein: Adds CryptoAPI and Module Support
@ 2014-10-23 22:11 Eric Rost
  2014-10-23 22:12 ` [PATCH v3 1/2] staging: skein: Adds CryptoAPI Support Eric Rost
  2014-10-23 22:12 ` [PATCH v3 2/2] staging: skein: Adds Loadable Module Support Eric Rost
  0 siblings, 2 replies; 4+ messages in thread
From: Eric Rost @ 2014-10-23 22:11 UTC (permalink / raw)
  To: gregkh, jason, jake, antonysaraev; +Cc: devel, linux-kernel

Adds CryptoAPI and Loadable Module support to the Skein Hashing
Algorithm.

Eric Rost (2):
  staging: skein: Adds CryptoAPI Support
  staging: skein: Adds Loadable Module Support

 drivers/staging/skein/Kconfig         |  24 +-
 drivers/staging/skein/Makefile        |  13 +-
 drivers/staging/skein/skein.c         | 883 ---------------------------------
 drivers/staging/skein/skein.h         | 346 -------------
 drivers/staging/skein/skein_api.h     |   2 +-
 drivers/staging/skein/skein_base.c    | 884 ++++++++++++++++++++++++++++++++++
 drivers/staging/skein/skein_base.h    | 351 ++++++++++++++
 drivers/staging/skein/skein_block.c   |   2 +-
 drivers/staging/skein/skein_block.h   |   2 +-
 drivers/staging/skein/skein_generic.c | 211 ++++++++
 drivers/staging/skein/skein_iv.h      |   2 +-
 drivers/staging/skein/threefish_api.h |   2 +-
 12 files changed, 1462 insertions(+), 1260 deletions(-)
 delete mode 100644 drivers/staging/skein/skein.c
 delete mode 100644 drivers/staging/skein/skein.h
 create mode 100644 drivers/staging/skein/skein_base.c
 create mode 100644 drivers/staging/skein/skein_base.h
 create mode 100644 drivers/staging/skein/skein_generic.c

-- 
2.1.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v3 1/2] staging: skein: Adds CryptoAPI Support
  2014-10-23 22:11 [PATCH v3 0/2] staging: skein: Adds CryptoAPI and Module Support Eric Rost
@ 2014-10-23 22:12 ` Eric Rost
  2014-10-24  4:51   ` Dan Carpenter
  2014-10-23 22:12 ` [PATCH v3 2/2] staging: skein: Adds Loadable Module Support Eric Rost
  1 sibling, 1 reply; 4+ messages in thread
From: Eric Rost @ 2014-10-23 22:12 UTC (permalink / raw)
  To: gregkh, jason, jake, antonysaraev; +Cc: devel, linux-kernel

Adds CryptoAPI support for skein256, skein512, and skein1024
algorithms. Also collapses threefish algorithm into skein.o and removes
Kconfig option for Threefish.

Signed-off-by: Eric Rost <eric.rost@mybabylon.net>
---
 drivers/staging/skein/Kconfig         |  22 +-
 drivers/staging/skein/Makefile        |  13 +-
 drivers/staging/skein/skein.c         | 883 ---------------------------------
 drivers/staging/skein/skein.h         | 346 -------------
 drivers/staging/skein/skein_api.h     |   2 +-
 drivers/staging/skein/skein_base.c    | 884 ++++++++++++++++++++++++++++++++++
 drivers/staging/skein/skein_base.h    | 351 ++++++++++++++
 drivers/staging/skein/skein_block.c   |   2 +-
 drivers/staging/skein/skein_block.h   |   2 +-
 drivers/staging/skein/skein_generic.c | 194 ++++++++
 drivers/staging/skein/skein_iv.h      |   2 +-
 drivers/staging/skein/threefish_api.h |   2 +-
 12 files changed, 1444 insertions(+), 1259 deletions(-)
 delete mode 100644 drivers/staging/skein/skein.c
 delete mode 100644 drivers/staging/skein/skein.h
 create mode 100644 drivers/staging/skein/skein_base.c
 create mode 100644 drivers/staging/skein/skein_base.h
 create mode 100644 drivers/staging/skein/skein_generic.c

diff --git a/drivers/staging/skein/Kconfig b/drivers/staging/skein/Kconfig
index b9172bf..de8bdd7 100644
--- a/drivers/staging/skein/Kconfig
+++ b/drivers/staging/skein/Kconfig
@@ -1,8 +1,8 @@
 config CRYPTO_SKEIN
 	bool "Skein digest algorithm"
 	depends on (X86 || UML_X86) && 64BIT && CRYPTO
-	select CRYPTO_THREEFISH
 	select CRYPTO_HASH
+	select CRYPTO_ALGAPI
 	help
 	  Skein secure hash algorithm is one of 5 finalists from the NIST SHA3
 	  competition.
@@ -12,21 +12,5 @@ config CRYPTO_SKEIN
 
 	  http://www.skein-hash.info/sites/default/files/skein1.3.pdf
 
-	  for more information.  This module depends on the threefish block
-	  cipher module.
-
-config CRYPTO_THREEFISH
-	bool "Threefish tweakable block cipher"
-	depends on (X86 || UML_X86) && 64BIT && CRYPTO
-	select CRYPTO_ALGAPI
-	help
-	  Threefish cipher algorithm is the tweakable block cipher underneath
-	  the Skein family of secure hash algorithms.  Skein is one of 5
-	  finalists from the NIST SHA3 competition.
-
-	  Skein is optimized for modern, 64bit processors and is highly
-	  customizable.  See:
-
-	  http://www.skein-hash.info/sites/default/files/skein1.3.pdf
-
-	  for more information.
+	  for more information. This module also contains the threefish block
+	  cipher algorithm.
diff --git a/drivers/staging/skein/Makefile b/drivers/staging/skein/Makefile
index a14aadd..66c8799 100644
--- a/drivers/staging/skein/Makefile
+++ b/drivers/staging/skein/Makefile
@@ -1,9 +1,10 @@
 #
 # Makefile for the skein secure hash algorithm
 #
-obj-$(CONFIG_CRYPTO_SKEIN) +=   skein.o \
-				skein_api.o \
-				skein_block.o
-
-obj-$(CONFIG_CRYPTO_THREEFISH) += threefish_block.o \
-				  threefish_api.o
+obj-$(CONFIG_CRYPTO_SKEIN) += skein.o
+skein-y := skein_base.o \
+	skein_api.o \
+	skein_block.o \
+	threefish_block.o \
+	threefish_api.o \
+	skein_generic.o
diff --git a/drivers/staging/skein/skein.c b/drivers/staging/skein/skein.c
deleted file mode 100644
index 8cc8358..0000000
--- a/drivers/staging/skein/skein.c
+++ /dev/null
@@ -1,883 +0,0 @@
-/***********************************************************************
-**
-** Implementation of the Skein hash function.
-**
-** Source code author: Doug Whiting, 2008.
-**
-** This algorithm and source code is released to the public domain.
-**
-************************************************************************/
-
-#define  SKEIN_PORT_CODE /* instantiate any code in skein_port.h */
-
-#include <linux/string.h>       /* get the memcpy/memset functions */
-#include "skein.h" /* get the Skein API definitions   */
-#include "skein_iv.h"    /* get precomputed IVs */
-#include "skein_block.h"
-
-/*****************************************************************/
-/*     256-bit Skein                                             */
-/*****************************************************************/
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* init the context for a straight hashing operation  */
-int skein_256_init(struct skein_256_ctx *ctx, size_t hash_bit_len)
-{
-	union {
-		u8 b[SKEIN_256_STATE_BYTES];
-		u64 w[SKEIN_256_STATE_WORDS];
-	} cfg;                              /* config block */
-
-	skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
-	ctx->h.hash_bit_len = hash_bit_len;         /* output hash bit count */
-
-	switch (hash_bit_len) { /* use pre-computed values, where available */
-	case  256:
-		memcpy(ctx->x, SKEIN_256_IV_256, sizeof(ctx->x));
-		break;
-	case  224:
-		memcpy(ctx->x, SKEIN_256_IV_224, sizeof(ctx->x));
-		break;
-	case  160:
-		memcpy(ctx->x, SKEIN_256_IV_160, sizeof(ctx->x));
-		break;
-	case  128:
-		memcpy(ctx->x, SKEIN_256_IV_128, sizeof(ctx->x));
-		break;
-	default:
-		/* here if there is no precomputed IV value available */
-		/*
-		 * build/process the config block, type == CONFIG (could be
-		 * precomputed)
-		 */
-		/* set tweaks: T0=0; T1=CFG | FINAL */
-		skein_start_new_type(ctx, CFG_FINAL);
-
-		/* set the schema, version */
-		cfg.w[0] = skein_swap64(SKEIN_SCHEMA_VER);
-		/* hash result length in bits */
-		cfg.w[1] = skein_swap64(hash_bit_len);
-		cfg.w[2] = skein_swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
-		/* zero pad config block */
-		memset(&cfg.w[3], 0, sizeof(cfg) - 3*sizeof(cfg.w[0]));
-
-		/* compute the initial chaining values from config block */
-		/* zero the chaining variables */
-		memset(ctx->x, 0, sizeof(ctx->x));
-		skein_256_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
-		break;
-	}
-	/* The chaining vars ctx->x are now initialized for hash_bit_len. */
-	/* Set up to process the data message portion of the hash (default) */
-	skein_start_new_type(ctx, MSG);              /* T0=0, T1= MSG type */
-
-	return SKEIN_SUCCESS;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* init the context for a MAC and/or tree hash operation */
-/* [identical to skein_256_init() when key_bytes == 0 && \
- *	tree_info == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
-int skein_256_init_ext(struct skein_256_ctx *ctx, size_t hash_bit_len,
-		       u64 tree_info, const u8 *key, size_t key_bytes)
-{
-	union {
-		u8  b[SKEIN_256_STATE_BYTES];
-		u64 w[SKEIN_256_STATE_WORDS];
-	} cfg; /* config block */
-
-	skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
-	skein_assert_ret(key_bytes == 0 || key != NULL, SKEIN_FAIL);
-
-	/* compute the initial chaining values ctx->x[], based on key */
-	if (key_bytes == 0) { /* is there a key? */
-		/* no key: use all zeroes as key for config block */
-		memset(ctx->x, 0, sizeof(ctx->x));
-	} else { /* here to pre-process a key */
-		skein_assert(sizeof(cfg.b) >= sizeof(ctx->x));
-		/* do a mini-Init right here */
-		/* set output hash bit count = state size */
-		ctx->h.hash_bit_len = 8*sizeof(ctx->x);
-		/* set tweaks: T0 = 0; T1 = KEY type */
-		skein_start_new_type(ctx, KEY);
-		/* zero the initial chaining variables */
-		memset(ctx->x, 0, sizeof(ctx->x));
-		/* hash the key */
-		skein_256_update(ctx, key, key_bytes);
-		/* put result into cfg.b[] */
-		skein_256_final_pad(ctx, cfg.b);
-		/* copy over into ctx->x[] */
-		memcpy(ctx->x, cfg.b, sizeof(cfg.b));
-	}
-	/*
-	 * build/process the config block, type == CONFIG (could be
-	 * precomputed for each key)
-	 */
-	/* output hash bit count */
-	ctx->h.hash_bit_len = hash_bit_len;
-	skein_start_new_type(ctx, CFG_FINAL);
-
-	/* pre-pad cfg.w[] with zeroes */
-	memset(&cfg.w, 0, sizeof(cfg.w));
-	cfg.w[0] = skein_swap64(SKEIN_SCHEMA_VER);
-	/* hash result length in bits */
-	cfg.w[1] = skein_swap64(hash_bit_len);
-	/* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
-	cfg.w[2] = skein_swap64(tree_info);
-
-	skein_show_key(256, &ctx->h, key, key_bytes);
-
-	/* compute the initial chaining values from config block */
-	skein_256_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
-
-	/* The chaining vars ctx->x are now initialized */
-	/* Set up to process the data message portion of the hash (default) */
-	skein_start_new_type(ctx, MSG);
-
-	return SKEIN_SUCCESS;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* process the input bytes */
-int skein_256_update(struct skein_256_ctx *ctx, const u8 *msg,
-		     size_t msg_byte_cnt)
-{
-	size_t n;
-
-	/* catch uninitialized context */
-	skein_assert_ret(ctx->h.b_cnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
-
-	/* process full blocks, if any */
-	if (msg_byte_cnt + ctx->h.b_cnt > SKEIN_256_BLOCK_BYTES) {
-		/* finish up any buffered message data */
-		if (ctx->h.b_cnt) {
-			/* # bytes free in buffer b[] */
-			n = SKEIN_256_BLOCK_BYTES - ctx->h.b_cnt;
-			if (n) {
-				/* check on our logic here */
-				skein_assert(n < msg_byte_cnt);
-				memcpy(&ctx->b[ctx->h.b_cnt], msg, n);
-				msg_byte_cnt  -= n;
-				msg         += n;
-				ctx->h.b_cnt += n;
-			}
-			skein_assert(ctx->h.b_cnt == SKEIN_256_BLOCK_BYTES);
-			skein_256_process_block(ctx, ctx->b, 1,
-						SKEIN_256_BLOCK_BYTES);
-			ctx->h.b_cnt = 0;
-		}
-		/*
-		 * now process any remaining full blocks, directly from input
-		 * message data
-		 */
-		if (msg_byte_cnt > SKEIN_256_BLOCK_BYTES) {
-			/* number of full blocks to process */
-			n = (msg_byte_cnt-1) / SKEIN_256_BLOCK_BYTES;
-			skein_256_process_block(ctx, msg, n,
-						SKEIN_256_BLOCK_BYTES);
-			msg_byte_cnt -= n * SKEIN_256_BLOCK_BYTES;
-			msg        += n * SKEIN_256_BLOCK_BYTES;
-		}
-		skein_assert(ctx->h.b_cnt == 0);
-	}
-
-	/* copy any remaining source message data bytes into b[] */
-	if (msg_byte_cnt) {
-		skein_assert(msg_byte_cnt + ctx->h.b_cnt <=
-			     SKEIN_256_BLOCK_BYTES);
-		memcpy(&ctx->b[ctx->h.b_cnt], msg, msg_byte_cnt);
-		ctx->h.b_cnt += msg_byte_cnt;
-	}
-
-	return SKEIN_SUCCESS;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* finalize the hash computation and output the result */
-int skein_256_final(struct skein_256_ctx *ctx, u8 *hash_val)
-{
-	size_t i, n, byte_cnt;
-	u64 x[SKEIN_256_STATE_WORDS];
-	/* catch uninitialized context */
-	skein_assert_ret(ctx->h.b_cnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
-
-	/* tag as the final block */
-	ctx->h.tweak[1] |= SKEIN_T1_FLAG_FINAL;
-	/* zero pad b[] if necessary */
-	if (ctx->h.b_cnt < SKEIN_256_BLOCK_BYTES)
-		memset(&ctx->b[ctx->h.b_cnt], 0,
-			SKEIN_256_BLOCK_BYTES - ctx->h.b_cnt);
-
-	/* process the final block */
-	skein_256_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
-
-	/* now output the result */
-	/* total number of output bytes */
-	byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
-
-	/* run Threefish in "counter mode" to generate output */
-	/* zero out b[], so it can hold the counter */
-	memset(ctx->b, 0, sizeof(ctx->b));
-	/* keep a local copy of counter mode "key" */
-	memcpy(x, ctx->x, sizeof(x));
-	for (i = 0; i*SKEIN_256_BLOCK_BYTES < byte_cnt; i++) {
-		/* build the counter block */
-		((u64 *)ctx->b)[0] = skein_swap64((u64) i);
-		skein_start_new_type(ctx, OUT_FINAL);
-		/* run "counter mode" */
-		skein_256_process_block(ctx, ctx->b, 1, sizeof(u64));
-		/* number of output bytes left to go */
-		n = byte_cnt - i*SKEIN_256_BLOCK_BYTES;
-		if (n >= SKEIN_256_BLOCK_BYTES)
-			n  = SKEIN_256_BLOCK_BYTES;
-		/* "output" the ctr mode bytes */
-		skein_put64_lsb_first(hash_val+i*SKEIN_256_BLOCK_BYTES, ctx->x,
-				      n);
-		skein_show_final(256, &ctx->h, n,
-				 hash_val+i*SKEIN_256_BLOCK_BYTES);
-		/* restore the counter mode key for next time */
-		memcpy(ctx->x, x, sizeof(x));
-	}
-	return SKEIN_SUCCESS;
-}
-
-/*****************************************************************/
-/*     512-bit Skein                                             */
-/*****************************************************************/
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* init the context for a straight hashing operation  */
-int skein_512_init(struct skein_512_ctx *ctx, size_t hash_bit_len)
-{
-	union {
-		u8 b[SKEIN_512_STATE_BYTES];
-		u64 w[SKEIN_512_STATE_WORDS];
-	} cfg;                              /* config block */
-
-	skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
-	ctx->h.hash_bit_len = hash_bit_len;         /* output hash bit count */
-
-	switch (hash_bit_len) { /* use pre-computed values, where available */
-	case  512:
-		memcpy(ctx->x, SKEIN_512_IV_512, sizeof(ctx->x));
-		break;
-	case  384:
-		memcpy(ctx->x, SKEIN_512_IV_384, sizeof(ctx->x));
-		break;
-	case  256:
-		memcpy(ctx->x, SKEIN_512_IV_256, sizeof(ctx->x));
-		break;
-	case  224:
-		memcpy(ctx->x, SKEIN_512_IV_224, sizeof(ctx->x));
-		break;
-	default:
-		/* here if there is no precomputed IV value available */
-		/*
-		 * build/process the config block, type == CONFIG (could be
-		 * precomputed)
-		 */
-		/* set tweaks: T0=0; T1=CFG | FINAL */
-		skein_start_new_type(ctx, CFG_FINAL);
-
-		/* set the schema, version */
-		cfg.w[0] = skein_swap64(SKEIN_SCHEMA_VER);
-		/* hash result length in bits */
-		cfg.w[1] = skein_swap64(hash_bit_len);
-		cfg.w[2] = skein_swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
-		/* zero pad config block */
-		memset(&cfg.w[3], 0, sizeof(cfg) - 3*sizeof(cfg.w[0]));
-
-		/* compute the initial chaining values from config block */
-		/* zero the chaining variables */
-		memset(ctx->x, 0, sizeof(ctx->x));
-		skein_512_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
-		break;
-	}
-
-	/*
-	 * The chaining vars ctx->x are now initialized for the given
-	 * hash_bit_len.
-	 */
-	/* Set up to process the data message portion of the hash (default) */
-	skein_start_new_type(ctx, MSG);              /* T0=0, T1= MSG type */
-
-	return SKEIN_SUCCESS;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* init the context for a MAC and/or tree hash operation */
-/* [identical to skein_512_init() when key_bytes == 0 && \
- *	tree_info == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
-int skein_512_init_ext(struct skein_512_ctx *ctx, size_t hash_bit_len,
-		       u64 tree_info, const u8 *key, size_t key_bytes)
-{
-	union {
-		u8 b[SKEIN_512_STATE_BYTES];
-		u64 w[SKEIN_512_STATE_WORDS];
-	} cfg;                              /* config block */
-
-	skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
-	skein_assert_ret(key_bytes == 0 || key != NULL, SKEIN_FAIL);
-
-	/* compute the initial chaining values ctx->x[], based on key */
-	if (key_bytes == 0) { /* is there a key? */
-		/* no key: use all zeroes as key for config block */
-		memset(ctx->x, 0, sizeof(ctx->x));
-	} else { /* here to pre-process a key */
-		skein_assert(sizeof(cfg.b) >= sizeof(ctx->x));
-		/* do a mini-Init right here */
-		/* set output hash bit count = state size */
-		ctx->h.hash_bit_len = 8*sizeof(ctx->x);
-		/* set tweaks: T0 = 0; T1 = KEY type */
-		skein_start_new_type(ctx, KEY);
-		/* zero the initial chaining variables */
-		memset(ctx->x, 0, sizeof(ctx->x));
-		/* hash the key */
-		skein_512_update(ctx, key, key_bytes);
-		/* put result into cfg.b[] */
-		skein_512_final_pad(ctx, cfg.b);
-		/* copy over into ctx->x[] */
-		memcpy(ctx->x, cfg.b, sizeof(cfg.b));
-	}
-	/*
-	 * build/process the config block, type == CONFIG (could be
-	 * precomputed for each key)
-	 */
-	ctx->h.hash_bit_len = hash_bit_len;          /* output hash bit count */
-	skein_start_new_type(ctx, CFG_FINAL);
-
-	/* pre-pad cfg.w[] with zeroes */
-	memset(&cfg.w, 0, sizeof(cfg.w));
-	cfg.w[0] = skein_swap64(SKEIN_SCHEMA_VER);
-	/* hash result length in bits */
-	cfg.w[1] = skein_swap64(hash_bit_len);
-	/* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
-	cfg.w[2] = skein_swap64(tree_info);
-
-	skein_show_key(512, &ctx->h, key, key_bytes);
-
-	/* compute the initial chaining values from config block */
-	skein_512_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
-
-	/* The chaining vars ctx->x are now initialized */
-	/* Set up to process the data message portion of the hash (default) */
-	skein_start_new_type(ctx, MSG);
-
-	return SKEIN_SUCCESS;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* process the input bytes */
-int skein_512_update(struct skein_512_ctx *ctx, const u8 *msg,
-		     size_t msg_byte_cnt)
-{
-	size_t n;
-
-	/* catch uninitialized context */
-	skein_assert_ret(ctx->h.b_cnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
-
-	/* process full blocks, if any */
-	if (msg_byte_cnt + ctx->h.b_cnt > SKEIN_512_BLOCK_BYTES) {
-		/* finish up any buffered message data */
-		if (ctx->h.b_cnt) {
-			/* # bytes free in buffer b[] */
-			n = SKEIN_512_BLOCK_BYTES - ctx->h.b_cnt;
-			if (n) {
-				/* check on our logic here */
-				skein_assert(n < msg_byte_cnt);
-				memcpy(&ctx->b[ctx->h.b_cnt], msg, n);
-				msg_byte_cnt  -= n;
-				msg         += n;
-				ctx->h.b_cnt += n;
-			}
-			skein_assert(ctx->h.b_cnt == SKEIN_512_BLOCK_BYTES);
-			skein_512_process_block(ctx, ctx->b, 1,
-						SKEIN_512_BLOCK_BYTES);
-			ctx->h.b_cnt = 0;
-		}
-		/*
-		 * now process any remaining full blocks, directly from input
-		 * message data
-		 */
-		if (msg_byte_cnt > SKEIN_512_BLOCK_BYTES) {
-			/* number of full blocks to process */
-			n = (msg_byte_cnt-1) / SKEIN_512_BLOCK_BYTES;
-			skein_512_process_block(ctx, msg, n,
-						SKEIN_512_BLOCK_BYTES);
-			msg_byte_cnt -= n * SKEIN_512_BLOCK_BYTES;
-			msg        += n * SKEIN_512_BLOCK_BYTES;
-		}
-		skein_assert(ctx->h.b_cnt == 0);
-	}
-
-	/* copy any remaining source message data bytes into b[] */
-	if (msg_byte_cnt) {
-		skein_assert(msg_byte_cnt + ctx->h.b_cnt <=
-			     SKEIN_512_BLOCK_BYTES);
-		memcpy(&ctx->b[ctx->h.b_cnt], msg, msg_byte_cnt);
-		ctx->h.b_cnt += msg_byte_cnt;
-	}
-
-	return SKEIN_SUCCESS;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* finalize the hash computation and output the result */
-int skein_512_final(struct skein_512_ctx *ctx, u8 *hash_val)
-{
-	size_t i, n, byte_cnt;
-	u64 x[SKEIN_512_STATE_WORDS];
-	/* catch uninitialized context */
-	skein_assert_ret(ctx->h.b_cnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
-
-	/* tag as the final block */
-	ctx->h.tweak[1] |= SKEIN_T1_FLAG_FINAL;
-	/* zero pad b[] if necessary */
-	if (ctx->h.b_cnt < SKEIN_512_BLOCK_BYTES)
-		memset(&ctx->b[ctx->h.b_cnt], 0,
-			SKEIN_512_BLOCK_BYTES - ctx->h.b_cnt);
-
-	/* process the final block */
-	skein_512_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
-
-	/* now output the result */
-	/* total number of output bytes */
-	byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
-
-	/* run Threefish in "counter mode" to generate output */
-	/* zero out b[], so it can hold the counter */
-	memset(ctx->b, 0, sizeof(ctx->b));
-	/* keep a local copy of counter mode "key" */
-	memcpy(x, ctx->x, sizeof(x));
-	for (i = 0; i*SKEIN_512_BLOCK_BYTES < byte_cnt; i++) {
-		/* build the counter block */
-		((u64 *)ctx->b)[0] = skein_swap64((u64) i);
-		skein_start_new_type(ctx, OUT_FINAL);
-		/* run "counter mode" */
-		skein_512_process_block(ctx, ctx->b, 1, sizeof(u64));
-		/* number of output bytes left to go */
-		n = byte_cnt - i*SKEIN_512_BLOCK_BYTES;
-		if (n >= SKEIN_512_BLOCK_BYTES)
-			n  = SKEIN_512_BLOCK_BYTES;
-		/* "output" the ctr mode bytes */
-		skein_put64_lsb_first(hash_val+i*SKEIN_512_BLOCK_BYTES, ctx->x,
-				      n);
-		skein_show_final(512, &ctx->h, n,
-				 hash_val+i*SKEIN_512_BLOCK_BYTES);
-		/* restore the counter mode key for next time */
-		memcpy(ctx->x, x, sizeof(x));
-	}
-	return SKEIN_SUCCESS;
-}
-
-/*****************************************************************/
-/*    1024-bit Skein                                             */
-/*****************************************************************/
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* init the context for a straight hashing operation  */
-int skein_1024_init(struct skein_1024_ctx *ctx, size_t hash_bit_len)
-{
-	union {
-		u8 b[SKEIN_1024_STATE_BYTES];
-		u64 w[SKEIN_1024_STATE_WORDS];
-	} cfg;                              /* config block */
-
-	skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
-	ctx->h.hash_bit_len = hash_bit_len;         /* output hash bit count */
-
-	switch (hash_bit_len) { /* use pre-computed values, where available */
-	case  512:
-		memcpy(ctx->x, SKEIN_1024_IV_512, sizeof(ctx->x));
-		break;
-	case  384:
-		memcpy(ctx->x, SKEIN_1024_IV_384, sizeof(ctx->x));
-		break;
-	case 1024:
-		memcpy(ctx->x, SKEIN_1024_IV_1024, sizeof(ctx->x));
-		break;
-	default:
-		/* here if there is no precomputed IV value available */
-		/*
-		 * build/process the config block, type == CONFIG
-		 * (could be precomputed)
-		 */
-		/* set tweaks: T0=0; T1=CFG | FINAL */
-		skein_start_new_type(ctx, CFG_FINAL);
-
-		/* set the schema, version */
-		cfg.w[0] = skein_swap64(SKEIN_SCHEMA_VER);
-		/* hash result length in bits */
-		cfg.w[1] = skein_swap64(hash_bit_len);
-		cfg.w[2] = skein_swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
-		/* zero pad config block */
-		memset(&cfg.w[3], 0, sizeof(cfg) - 3*sizeof(cfg.w[0]));
-
-		/* compute the initial chaining values from config block */
-		/* zero the chaining variables */
-		memset(ctx->x, 0, sizeof(ctx->x));
-		skein_1024_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
-		break;
-	}
-
-	/* The chaining vars ctx->x are now initialized for the hash_bit_len. */
-	/* Set up to process the data message portion of the hash (default) */
-	skein_start_new_type(ctx, MSG);              /* T0=0, T1= MSG type */
-
-	return SKEIN_SUCCESS;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* init the context for a MAC and/or tree hash operation */
-/* [identical to skein_1024_init() when key_bytes == 0 && \
- *	tree_info == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
-int skein_1024_init_ext(struct skein_1024_ctx *ctx, size_t hash_bit_len,
-			u64 tree_info, const u8 *key, size_t key_bytes)
-{
-	union {
-		u8 b[SKEIN_1024_STATE_BYTES];
-		u64 w[SKEIN_1024_STATE_WORDS];
-	} cfg;                              /* config block */
-
-	skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
-	skein_assert_ret(key_bytes == 0 || key != NULL, SKEIN_FAIL);
-
-	/* compute the initial chaining values ctx->x[], based on key */
-	if (key_bytes == 0) { /* is there a key? */
-		/* no key: use all zeroes as key for config block */
-		memset(ctx->x, 0, sizeof(ctx->x));
-	} else { /* here to pre-process a key */
-		skein_assert(sizeof(cfg.b) >= sizeof(ctx->x));
-		/* do a mini-Init right here */
-		/* set output hash bit count = state size */
-		ctx->h.hash_bit_len = 8*sizeof(ctx->x);
-		/* set tweaks: T0 = 0; T1 = KEY type */
-		skein_start_new_type(ctx, KEY);
-		/* zero the initial chaining variables */
-		memset(ctx->x, 0, sizeof(ctx->x));
-		/* hash the key */
-		skein_1024_update(ctx, key, key_bytes);
-		/* put result into cfg.b[] */
-		skein_1024_final_pad(ctx, cfg.b);
-		/* copy over into ctx->x[] */
-		memcpy(ctx->x, cfg.b, sizeof(cfg.b));
-	}
-	/*
-	 * build/process the config block, type == CONFIG (could be
-	 * precomputed for each key)
-	 */
-	/* output hash bit count */
-	ctx->h.hash_bit_len = hash_bit_len;
-	skein_start_new_type(ctx, CFG_FINAL);
-
-	/* pre-pad cfg.w[] with zeroes */
-	memset(&cfg.w, 0, sizeof(cfg.w));
-	cfg.w[0] = skein_swap64(SKEIN_SCHEMA_VER);
-	/* hash result length in bits */
-	cfg.w[1] = skein_swap64(hash_bit_len);
-	/* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
-	cfg.w[2] = skein_swap64(tree_info);
-
-	skein_show_key(1024, &ctx->h, key, key_bytes);
-
-	/* compute the initial chaining values from config block */
-	skein_1024_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
-
-	/* The chaining vars ctx->x are now initialized */
-	/* Set up to process the data message portion of the hash (default) */
-	skein_start_new_type(ctx, MSG);
-
-	return SKEIN_SUCCESS;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* process the input bytes */
-int skein_1024_update(struct skein_1024_ctx *ctx, const u8 *msg,
-		      size_t msg_byte_cnt)
-{
-	size_t n;
-
-	/* catch uninitialized context */
-	skein_assert_ret(ctx->h.b_cnt <= SKEIN_1024_BLOCK_BYTES, SKEIN_FAIL);
-
-	/* process full blocks, if any */
-	if (msg_byte_cnt + ctx->h.b_cnt > SKEIN_1024_BLOCK_BYTES) {
-		/* finish up any buffered message data */
-		if (ctx->h.b_cnt) {
-			/* # bytes free in buffer b[] */
-			n = SKEIN_1024_BLOCK_BYTES - ctx->h.b_cnt;
-			if (n) {
-				/* check on our logic here */
-				skein_assert(n < msg_byte_cnt);
-				memcpy(&ctx->b[ctx->h.b_cnt], msg, n);
-				msg_byte_cnt  -= n;
-				msg         += n;
-				ctx->h.b_cnt += n;
-			}
-			skein_assert(ctx->h.b_cnt == SKEIN_1024_BLOCK_BYTES);
-			skein_1024_process_block(ctx, ctx->b, 1,
-						 SKEIN_1024_BLOCK_BYTES);
-			ctx->h.b_cnt = 0;
-		}
-		/*
-		 * now process any remaining full blocks, directly from input
-		 * message data
-		 */
-		if (msg_byte_cnt > SKEIN_1024_BLOCK_BYTES) {
-			/* number of full blocks to process */
-			n = (msg_byte_cnt-1) / SKEIN_1024_BLOCK_BYTES;
-			skein_1024_process_block(ctx, msg, n,
-						 SKEIN_1024_BLOCK_BYTES);
-			msg_byte_cnt -= n * SKEIN_1024_BLOCK_BYTES;
-			msg        += n * SKEIN_1024_BLOCK_BYTES;
-		}
-		skein_assert(ctx->h.b_cnt == 0);
-	}
-
-	/* copy any remaining source message data bytes into b[] */
-	if (msg_byte_cnt) {
-		skein_assert(msg_byte_cnt + ctx->h.b_cnt <=
-			     SKEIN_1024_BLOCK_BYTES);
-		memcpy(&ctx->b[ctx->h.b_cnt], msg, msg_byte_cnt);
-		ctx->h.b_cnt += msg_byte_cnt;
-	}
-
-	return SKEIN_SUCCESS;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* finalize the hash computation and output the result */
-int skein_1024_final(struct skein_1024_ctx *ctx, u8 *hash_val)
-{
-	size_t i, n, byte_cnt;
-	u64 x[SKEIN_1024_STATE_WORDS];
-	/* catch uninitialized context */
-	skein_assert_ret(ctx->h.b_cnt <= SKEIN_1024_BLOCK_BYTES, SKEIN_FAIL);
-
-	/* tag as the final block */
-	ctx->h.tweak[1] |= SKEIN_T1_FLAG_FINAL;
-	/* zero pad b[] if necessary */
-	if (ctx->h.b_cnt < SKEIN_1024_BLOCK_BYTES)
-		memset(&ctx->b[ctx->h.b_cnt], 0,
-			SKEIN_1024_BLOCK_BYTES - ctx->h.b_cnt);
-
-	/* process the final block */
-	skein_1024_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
-
-	/* now output the result */
-	/* total number of output bytes */
-	byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
-
-	/* run Threefish in "counter mode" to generate output */
-	/* zero out b[], so it can hold the counter */
-	memset(ctx->b, 0, sizeof(ctx->b));
-	/* keep a local copy of counter mode "key" */
-	memcpy(x, ctx->x, sizeof(x));
-	for (i = 0; i*SKEIN_1024_BLOCK_BYTES < byte_cnt; i++) {
-		/* build the counter block */
-		((u64 *)ctx->b)[0] = skein_swap64((u64) i);
-		skein_start_new_type(ctx, OUT_FINAL);
-		/* run "counter mode" */
-		skein_1024_process_block(ctx, ctx->b, 1, sizeof(u64));
-		/* number of output bytes left to go */
-		n = byte_cnt - i*SKEIN_1024_BLOCK_BYTES;
-		if (n >= SKEIN_1024_BLOCK_BYTES)
-			n  = SKEIN_1024_BLOCK_BYTES;
-		/* "output" the ctr mode bytes */
-		skein_put64_lsb_first(hash_val+i*SKEIN_1024_BLOCK_BYTES, ctx->x,
-				      n);
-		skein_show_final(1024, &ctx->h, n,
-				 hash_val+i*SKEIN_1024_BLOCK_BYTES);
-		/* restore the counter mode key for next time */
-		memcpy(ctx->x, x, sizeof(x));
-	}
-	return SKEIN_SUCCESS;
-}
-
-/**************** Functions to support MAC/tree hashing ***************/
-/*   (this code is identical for Optimized and Reference versions)    */
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* finalize the hash computation and output the block, no OUTPUT stage */
-int skein_256_final_pad(struct skein_256_ctx *ctx, u8 *hash_val)
-{
-	/* catch uninitialized context */
-	skein_assert_ret(ctx->h.b_cnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
-
-	/* tag as the final block */
-	ctx->h.tweak[1] |= SKEIN_T1_FLAG_FINAL;
-	/* zero pad b[] if necessary */
-	if (ctx->h.b_cnt < SKEIN_256_BLOCK_BYTES)
-		memset(&ctx->b[ctx->h.b_cnt], 0,
-			SKEIN_256_BLOCK_BYTES - ctx->h.b_cnt);
-	/* process the final block */
-	skein_256_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
-
-	/* "output" the state bytes */
-	skein_put64_lsb_first(hash_val, ctx->x, SKEIN_256_BLOCK_BYTES);
-
-	return SKEIN_SUCCESS;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* finalize the hash computation and output the block, no OUTPUT stage */
-int skein_512_final_pad(struct skein_512_ctx *ctx, u8 *hash_val)
-{
-	/* catch uninitialized context */
-	skein_assert_ret(ctx->h.b_cnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
-
-	/* tag as the final block */
-	ctx->h.tweak[1] |= SKEIN_T1_FLAG_FINAL;
-	/* zero pad b[] if necessary */
-	if (ctx->h.b_cnt < SKEIN_512_BLOCK_BYTES)
-		memset(&ctx->b[ctx->h.b_cnt], 0,
-			SKEIN_512_BLOCK_BYTES - ctx->h.b_cnt);
-	/* process the final block */
-	skein_512_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
-
-	/* "output" the state bytes */
-	skein_put64_lsb_first(hash_val, ctx->x, SKEIN_512_BLOCK_BYTES);
-
-	return SKEIN_SUCCESS;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* finalize the hash computation and output the block, no OUTPUT stage */
-int skein_1024_final_pad(struct skein_1024_ctx *ctx, u8 *hash_val)
-{
-	/* catch uninitialized context */
-	skein_assert_ret(ctx->h.b_cnt <= SKEIN_1024_BLOCK_BYTES, SKEIN_FAIL);
-
-	/* tag as the final block */
-	ctx->h.tweak[1] |= SKEIN_T1_FLAG_FINAL;
-	/* zero pad b[] if necessary */
-	if (ctx->h.b_cnt < SKEIN_1024_BLOCK_BYTES)
-		memset(&ctx->b[ctx->h.b_cnt], 0,
-			SKEIN_1024_BLOCK_BYTES - ctx->h.b_cnt);
-	/* process the final block */
-	skein_1024_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
-
-	/* "output" the state bytes */
-	skein_put64_lsb_first(hash_val, ctx->x, SKEIN_1024_BLOCK_BYTES);
-
-	return SKEIN_SUCCESS;
-}
-
-#if SKEIN_TREE_HASH
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* just do the OUTPUT stage                                       */
-int skein_256_output(struct skein_256_ctx *ctx, u8 *hash_val)
-{
-	size_t i, n, byte_cnt;
-	u64 x[SKEIN_256_STATE_WORDS];
-	/* catch uninitialized context */
-	skein_assert_ret(ctx->h.b_cnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
-
-	/* now output the result */
-	/* total number of output bytes */
-	byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
-
-	/* run Threefish in "counter mode" to generate output */
-	/* zero out b[], so it can hold the counter */
-	memset(ctx->b, 0, sizeof(ctx->b));
-	/* keep a local copy of counter mode "key" */
-	memcpy(x, ctx->x, sizeof(x));
-	for (i = 0; i*SKEIN_256_BLOCK_BYTES < byte_cnt; i++) {
-		/* build the counter block */
-		((u64 *)ctx->b)[0] = skein_swap64((u64) i);
-		skein_start_new_type(ctx, OUT_FINAL);
-		/* run "counter mode" */
-		skein_256_process_block(ctx, ctx->b, 1, sizeof(u64));
-		/* number of output bytes left to go */
-		n = byte_cnt - i*SKEIN_256_BLOCK_BYTES;
-		if (n >= SKEIN_256_BLOCK_BYTES)
-			n  = SKEIN_256_BLOCK_BYTES;
-		/* "output" the ctr mode bytes */
-		skein_put64_lsb_first(hash_val+i*SKEIN_256_BLOCK_BYTES, ctx->x,
-				      n);
-		skein_show_final(256, &ctx->h, n,
-				 hash_val+i*SKEIN_256_BLOCK_BYTES);
-		/* restore the counter mode key for next time */
-		memcpy(ctx->x, x, sizeof(x));
-	}
-	return SKEIN_SUCCESS;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* just do the OUTPUT stage                                       */
-int skein_512_output(struct skein_512_ctx *ctx, u8 *hash_val)
-{
-	size_t i, n, byte_cnt;
-	u64 x[SKEIN_512_STATE_WORDS];
-	/* catch uninitialized context */
-	skein_assert_ret(ctx->h.b_cnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
-
-	/* now output the result */
-	/* total number of output bytes */
-	byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
-
-	/* run Threefish in "counter mode" to generate output */
-	/* zero out b[], so it can hold the counter */
-	memset(ctx->b, 0, sizeof(ctx->b));
-	/* keep a local copy of counter mode "key" */
-	memcpy(x, ctx->x, sizeof(x));
-	for (i = 0; i*SKEIN_512_BLOCK_BYTES < byte_cnt; i++) {
-		/* build the counter block */
-		((u64 *)ctx->b)[0] = skein_swap64((u64) i);
-		skein_start_new_type(ctx, OUT_FINAL);
-		/* run "counter mode" */
-		skein_512_process_block(ctx, ctx->b, 1, sizeof(u64));
-		/* number of output bytes left to go */
-		n = byte_cnt - i*SKEIN_512_BLOCK_BYTES;
-		if (n >= SKEIN_512_BLOCK_BYTES)
-			n  = SKEIN_512_BLOCK_BYTES;
-		/* "output" the ctr mode bytes */
-		skein_put64_lsb_first(hash_val+i*SKEIN_512_BLOCK_BYTES, ctx->x,
-				      n);
-		skein_show_final(256, &ctx->h, n,
-				 hash_val+i*SKEIN_512_BLOCK_BYTES);
-		/* restore the counter mode key for next time */
-		memcpy(ctx->x, x, sizeof(x));
-	}
-	return SKEIN_SUCCESS;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* just do the OUTPUT stage                                       */
-int skein_1024_output(struct skein_1024_ctx *ctx, u8 *hash_val)
-{
-	size_t i, n, byte_cnt;
-	u64 x[SKEIN_1024_STATE_WORDS];
-	/* catch uninitialized context */
-	skein_assert_ret(ctx->h.b_cnt <= SKEIN_1024_BLOCK_BYTES, SKEIN_FAIL);
-
-	/* now output the result */
-	/* total number of output bytes */
-	byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
-
-	/* run Threefish in "counter mode" to generate output */
-	/* zero out b[], so it can hold the counter */
-	memset(ctx->b, 0, sizeof(ctx->b));
-	/* keep a local copy of counter mode "key" */
-	memcpy(x, ctx->x, sizeof(x));
-	for (i = 0; i*SKEIN_1024_BLOCK_BYTES < byte_cnt; i++) {
-		/* build the counter block */
-		((u64 *)ctx->b)[0] = skein_swap64((u64) i);
-		skein_start_new_type(ctx, OUT_FINAL);
-		/* run "counter mode" */
-		skein_1024_process_block(ctx, ctx->b, 1, sizeof(u64));
-		/* number of output bytes left to go */
-		n = byte_cnt - i*SKEIN_1024_BLOCK_BYTES;
-		if (n >= SKEIN_1024_BLOCK_BYTES)
-			n  = SKEIN_1024_BLOCK_BYTES;
-		/* "output" the ctr mode bytes */
-		skein_put64_lsb_first(hash_val+i*SKEIN_1024_BLOCK_BYTES, ctx->x,
-				      n);
-		skein_show_final(256, &ctx->h, n,
-				 hash_val+i*SKEIN_1024_BLOCK_BYTES);
-		/* restore the counter mode key for next time */
-		memcpy(ctx->x, x, sizeof(x));
-	}
-	return SKEIN_SUCCESS;
-}
-#endif
diff --git a/drivers/staging/skein/skein.h b/drivers/staging/skein/skein.h
deleted file mode 100644
index e6669f1..0000000
--- a/drivers/staging/skein/skein.h
+++ /dev/null
@@ -1,346 +0,0 @@
-#ifndef _SKEIN_H_
-#define _SKEIN_H_     1
-/**************************************************************************
-**
-** Interface declarations and internal definitions for Skein hashing.
-**
-** Source code author: Doug Whiting, 2008.
-**
-** This algorithm and source code is released to the public domain.
-**
-***************************************************************************
-**
-** The following compile-time switches may be defined to control some
-** tradeoffs between speed, code size, error checking, and security.
-**
-** The "default" note explains what happens when the switch is not defined.
-**
-**  SKEIN_DEBUG            -- make callouts from inside Skein code
-**                            to examine/display intermediate values.
-**                            [default: no callouts (no overhead)]
-**
-**  SKEIN_ERR_CHECK        -- how error checking is handled inside Skein
-**                            code. If not defined, most error checking
-**                            is disabled (for performance). Otherwise,
-**                            the switch value is interpreted as:
-**                                0: use assert()      to flag errors
-**                                1: return SKEIN_FAIL to flag errors
-**
-***************************************************************************/
-
-#ifndef rotl_64
-#define rotl_64(x, N)    (((x) << (N)) | ((x) >> (64-(N))))
-#endif
-
-/* below two prototype assume we are handed aligned data */
-#define skein_put64_lsb_first(dst08, src64, b_cnt) memcpy(dst08, src64, b_cnt)
-#define skein_get64_lsb_first(dst64, src08, w_cnt) \
-		memcpy(dst64, src08, 8*(w_cnt))
-#define skein_swap64(w64)  (w64)
-
-enum {
-	SKEIN_SUCCESS         =      0, /* return codes from Skein calls */
-	SKEIN_FAIL            =      1,
-	SKEIN_BAD_HASHLEN     =      2
-};
-
-#define  SKEIN_MODIFIER_WORDS   (2) /* number of modifier (tweak) words */
-
-#define  SKEIN_256_STATE_WORDS  (4)
-#define  SKEIN_512_STATE_WORDS  (8)
-#define  SKEIN_1024_STATE_WORDS (16)
-#define  SKEIN_MAX_STATE_WORDS (16)
-
-#define  SKEIN_256_STATE_BYTES  (8*SKEIN_256_STATE_WORDS)
-#define  SKEIN_512_STATE_BYTES  (8*SKEIN_512_STATE_WORDS)
-#define  SKEIN_1024_STATE_BYTES  (8*SKEIN_1024_STATE_WORDS)
-
-#define  SKEIN_256_STATE_BITS  (64*SKEIN_256_STATE_WORDS)
-#define  SKEIN_512_STATE_BITS  (64*SKEIN_512_STATE_WORDS)
-#define  SKEIN_1024_STATE_BITS  (64*SKEIN_1024_STATE_WORDS)
-
-#define  SKEIN_256_BLOCK_BYTES  (8*SKEIN_256_STATE_WORDS)
-#define  SKEIN_512_BLOCK_BYTES  (8*SKEIN_512_STATE_WORDS)
-#define  SKEIN_1024_BLOCK_BYTES  (8*SKEIN_1024_STATE_WORDS)
-
-struct skein_ctx_hdr {
-	size_t hash_bit_len;		/* size of hash result, in bits */
-	size_t b_cnt;			/* current byte count in buffer b[] */
-	u64 tweak[SKEIN_MODIFIER_WORDS]; /* tweak[0]=byte cnt, tweak[1]=flags */
-};
-
-struct skein_256_ctx { /* 256-bit Skein hash context structure */
-	struct skein_ctx_hdr h;		/* common header context variables */
-	u64 x[SKEIN_256_STATE_WORDS];	/* chaining variables */
-	u8 b[SKEIN_256_BLOCK_BYTES];	/* partial block buf (8-byte aligned) */
-};
-
-struct skein_512_ctx { /* 512-bit Skein hash context structure */
-	struct skein_ctx_hdr h;		/* common header context variables */
-	u64 x[SKEIN_512_STATE_WORDS];	/* chaining variables */
-	u8 b[SKEIN_512_BLOCK_BYTES];	/* partial block buf (8-byte aligned) */
-};
-
-struct skein_1024_ctx { /* 1024-bit Skein hash context structure */
-	struct skein_ctx_hdr h;		/* common header context variables */
-	u64 x[SKEIN_1024_STATE_WORDS];	/* chaining variables */
-	u8 b[SKEIN_1024_BLOCK_BYTES];	/* partial block buf (8-byte aligned) */
-};
-
-/* Skein APIs for (incremental) "straight hashing" */
-int skein_256_init(struct skein_256_ctx *ctx, size_t hash_bit_len);
-int skein_512_init(struct skein_512_ctx *ctx, size_t hash_bit_len);
-int skein_1024_init(struct skein_1024_ctx *ctx, size_t hash_bit_len);
-
-int skein_256_update(struct skein_256_ctx *ctx, const u8 *msg,
-		     size_t msg_byte_cnt);
-int skein_512_update(struct skein_512_ctx *ctx, const u8 *msg,
-		     size_t msg_byte_cnt);
-int skein_1024_update(struct skein_1024_ctx *ctx, const u8 *msg,
-		      size_t msg_byte_cnt);
-
-int skein_256_final(struct skein_256_ctx *ctx, u8 *hash_val);
-int skein_512_final(struct skein_512_ctx *ctx, u8 *hash_val);
-int skein_1024_final(struct skein_1024_ctx *ctx, u8 *hash_val);
-
-/*
-**   Skein APIs for "extended" initialization: MAC keys, tree hashing.
-**   After an init_ext() call, just use update/final calls as with init().
-**
-**   Notes: Same parameters as _init() calls, plus tree_info/key/key_bytes.
-**          When key_bytes == 0 and tree_info == SKEIN_SEQUENTIAL,
-**              the results of init_ext() are identical to calling init().
-**          The function init() may be called once to "precompute" the IV for
-**              a given hash_bit_len value, then by saving a copy of the context
-**              the IV computation may be avoided in later calls.
-**          Similarly, the function init_ext() may be called once per MAC key
-**              to precompute the MAC IV, then a copy of the context saved and
-**              reused for each new MAC computation.
-**/
-int skein_256_init_ext(struct skein_256_ctx *ctx, size_t hash_bit_len,
-		       u64 tree_info, const u8 *key, size_t key_bytes);
-int skein_512_init_ext(struct skein_512_ctx *ctx, size_t hash_bit_len,
-		       u64 tree_info, const u8 *key, size_t key_bytes);
-int skein_1024_init_ext(struct skein_1024_ctx *ctx, size_t hash_bit_len,
-			u64 tree_info, const u8 *key, size_t key_bytes);
-
-/*
-**   Skein APIs for MAC and tree hash:
-**      final_pad:  pad, do final block, but no OUTPUT type
-**      output:     do just the output stage
-*/
-int skein_256_final_pad(struct skein_256_ctx *ctx, u8 *hash_val);
-int skein_512_final_pad(struct skein_512_ctx *ctx, u8 *hash_val);
-int skein_1024_final_pad(struct skein_1024_ctx *ctx, u8 *hash_val);
-
-#ifndef SKEIN_TREE_HASH
-#define SKEIN_TREE_HASH (1)
-#endif
-#if  SKEIN_TREE_HASH
-int skein_256_output(struct skein_256_ctx *ctx, u8 *hash_val);
-int skein_512_output(struct skein_512_ctx *ctx, u8 *hash_val);
-int skein_1024_output(struct skein_1024_ctx *ctx, u8 *hash_val);
-#endif
-
-/*****************************************************************
-** "Internal" Skein definitions
-**    -- not needed for sequential hashing API, but will be
-**           helpful for other uses of Skein (e.g., tree hash mode).
-**    -- included here so that they can be shared between
-**           reference and optimized code.
-******************************************************************/
-
-/* tweak word tweak[1]: bit field starting positions */
-#define SKEIN_T1_BIT(BIT)       ((BIT) - 64)      /* second word  */
-
-#define SKEIN_T1_POS_TREE_LVL   SKEIN_T1_BIT(112) /* 112..118 hash tree level */
-#define SKEIN_T1_POS_BIT_PAD    SKEIN_T1_BIT(119) /* 119 part. final in byte */
-#define SKEIN_T1_POS_BLK_TYPE   SKEIN_T1_BIT(120) /* 120..125 type field `*/
-#define SKEIN_T1_POS_FIRST      SKEIN_T1_BIT(126) /* 126      first blk flag */
-#define SKEIN_T1_POS_FINAL      SKEIN_T1_BIT(127) /* 127      final blk flag */
-
-/* tweak word tweak[1]: flag bit definition(s) */
-#define SKEIN_T1_FLAG_FIRST     (((u64)  1) << SKEIN_T1_POS_FIRST)
-#define SKEIN_T1_FLAG_FINAL     (((u64)  1) << SKEIN_T1_POS_FINAL)
-#define SKEIN_T1_FLAG_BIT_PAD   (((u64)  1) << SKEIN_T1_POS_BIT_PAD)
-
-/* tweak word tweak[1]: tree level bit field mask */
-#define SKEIN_T1_TREE_LVL_MASK  (((u64)0x7F) << SKEIN_T1_POS_TREE_LVL)
-#define SKEIN_T1_TREE_LEVEL(n)  (((u64) (n)) << SKEIN_T1_POS_TREE_LVL)
-
-/* tweak word tweak[1]: block type field */
-#define SKEIN_BLK_TYPE_KEY       (0) /* key, for MAC and KDF */
-#define SKEIN_BLK_TYPE_CFG       (4) /* configuration block */
-#define SKEIN_BLK_TYPE_PERS      (8) /* personalization string */
-#define SKEIN_BLK_TYPE_PK       (12) /* pubkey (for digital sigs) */
-#define SKEIN_BLK_TYPE_KDF      (16) /* key identifier for KDF */
-#define SKEIN_BLK_TYPE_NONCE    (20) /* nonce for PRNG */
-#define SKEIN_BLK_TYPE_MSG      (48) /* message processing */
-#define SKEIN_BLK_TYPE_OUT      (63) /* output stage */
-#define SKEIN_BLK_TYPE_MASK     (63) /* bit field mask */
-
-#define SKEIN_T1_BLK_TYPE(T)   (((u64) (SKEIN_BLK_TYPE_##T)) << \
-					SKEIN_T1_POS_BLK_TYPE)
-#define SKEIN_T1_BLK_TYPE_KEY   SKEIN_T1_BLK_TYPE(KEY)  /* for MAC and KDF */
-#define SKEIN_T1_BLK_TYPE_CFG   SKEIN_T1_BLK_TYPE(CFG)  /* config block */
-#define SKEIN_T1_BLK_TYPE_PERS  SKEIN_T1_BLK_TYPE(PERS) /* personalization */
-#define SKEIN_T1_BLK_TYPE_PK    SKEIN_T1_BLK_TYPE(PK)   /* pubkey (for sigs) */
-#define SKEIN_T1_BLK_TYPE_KDF   SKEIN_T1_BLK_TYPE(KDF)  /* key ident for KDF */
-#define SKEIN_T1_BLK_TYPE_NONCE SKEIN_T1_BLK_TYPE(NONCE)/* nonce for PRNG */
-#define SKEIN_T1_BLK_TYPE_MSG   SKEIN_T1_BLK_TYPE(MSG)  /* message processing */
-#define SKEIN_T1_BLK_TYPE_OUT   SKEIN_T1_BLK_TYPE(OUT)  /* output stage */
-#define SKEIN_T1_BLK_TYPE_MASK  SKEIN_T1_BLK_TYPE(MASK) /* field bit mask */
-
-#define SKEIN_T1_BLK_TYPE_CFG_FINAL    (SKEIN_T1_BLK_TYPE_CFG | \
-					SKEIN_T1_FLAG_FINAL)
-#define SKEIN_T1_BLK_TYPE_OUT_FINAL    (SKEIN_T1_BLK_TYPE_OUT | \
-					SKEIN_T1_FLAG_FINAL)
-
-#define SKEIN_VERSION           (1)
-
-#ifndef SKEIN_ID_STRING_LE      /* allow compile-time personalization */
-#define SKEIN_ID_STRING_LE      (0x33414853) /* "SHA3" (little-endian)*/
-#endif
-
-#define SKEIN_MK_64(hi32, lo32)  ((lo32) + (((u64) (hi32)) << 32))
-#define SKEIN_SCHEMA_VER        SKEIN_MK_64(SKEIN_VERSION, SKEIN_ID_STRING_LE)
-#define SKEIN_KS_PARITY         SKEIN_MK_64(0x1BD11BDA, 0xA9FC1A22)
-
-#define SKEIN_CFG_STR_LEN       (4*8)
-
-/* bit field definitions in config block tree_info word */
-#define SKEIN_CFG_TREE_LEAF_SIZE_POS  (0)
-#define SKEIN_CFG_TREE_NODE_SIZE_POS  (8)
-#define SKEIN_CFG_TREE_MAX_LEVEL_POS  (16)
-
-#define SKEIN_CFG_TREE_LEAF_SIZE_MSK (((u64)0xFF) << \
-					SKEIN_CFG_TREE_LEAF_SIZE_POS)
-#define SKEIN_CFG_TREE_NODE_SIZE_MSK (((u64)0xFF) << \
-					SKEIN_CFG_TREE_NODE_SIZE_POS)
-#define SKEIN_CFG_TREE_MAX_LEVEL_MSK (((u64)0xFF) << \
-					SKEIN_CFG_TREE_MAX_LEVEL_POS)
-
-#define SKEIN_CFG_TREE_INFO(leaf, node, max_lvl)                   \
-	((((u64)(leaf))   << SKEIN_CFG_TREE_LEAF_SIZE_POS) |    \
-	 (((u64)(node))   << SKEIN_CFG_TREE_NODE_SIZE_POS) |    \
-	 (((u64)(max_lvl)) << SKEIN_CFG_TREE_MAX_LEVEL_POS))
-
-/* use as tree_info in InitExt() call for sequential processing */
-#define SKEIN_CFG_TREE_INFO_SEQUENTIAL SKEIN_CFG_TREE_INFO(0, 0, 0)
-
-/*
-**   Skein macros for getting/setting tweak words, etc.
-**   These are useful for partial input bytes, hash tree init/update, etc.
-**/
-#define skein_get_tweak(ctx_ptr, TWK_NUM)          ((ctx_ptr)->h.tweak[TWK_NUM])
-#define skein_set_tweak(ctx_ptr, TWK_NUM, t_val) { \
-		(ctx_ptr)->h.tweak[TWK_NUM] = (t_val); \
-	}
-
-#define skein_get_T0(ctx_ptr)     skein_get_tweak(ctx_ptr, 0)
-#define skein_get_T1(ctx_ptr)     skein_get_tweak(ctx_ptr, 1)
-#define skein_set_T0(ctx_ptr, T0) skein_set_tweak(ctx_ptr, 0, T0)
-#define skein_set_T1(ctx_ptr, T1) skein_set_tweak(ctx_ptr, 1, T1)
-
-/* set both tweak words at once */
-#define skein_set_T0_T1(ctx_ptr, T0, T1)           \
-	{                                          \
-	skein_set_T0(ctx_ptr, (T0));               \
-	skein_set_T1(ctx_ptr, (T1));               \
-	}
-
-#define skein_set_type(ctx_ptr, BLK_TYPE)         \
-	skein_set_T1(ctx_ptr, SKEIN_T1_BLK_TYPE_##BLK_TYPE)
-
-/*
- * setup for starting with a new type:
- * h.tweak[0]=0; h.tweak[1] = NEW_TYPE; h.b_cnt=0;
- */
-#define skein_start_new_type(ctx_ptr, BLK_TYPE) { \
-		skein_set_T0_T1(ctx_ptr, 0, SKEIN_T1_FLAG_FIRST | \
-				SKEIN_T1_BLK_TYPE_##BLK_TYPE); \
-		(ctx_ptr)->h.b_cnt = 0; \
-	}
-
-#define skein_clear_first_flag(hdr) { \
-		(hdr).tweak[1] &= ~SKEIN_T1_FLAG_FIRST; \
-	}
-#define skein_set_bit_pad_flag(hdr) { \
-		(hdr).tweak[1] |=  SKEIN_T1_FLAG_BIT_PAD; \
-	}
-
-#define skein_set_tree_level(hdr, height) { \
-		(hdr).tweak[1] |= SKEIN_T1_TREE_LEVEL(height); \
-	}
-
-/*****************************************************************
-** "Internal" Skein definitions for debugging and error checking
-******************************************************************/
-#ifdef SKEIN_DEBUG             /* examine/display intermediate values? */
-#include "skein_debug.h"
-#else                           /* default is no callouts */
-#define skein_show_block(bits, ctx, x, blk_ptr, w_ptr, ks_event_ptr, ks_odd_ptr)
-#define skein_show_round(bits, ctx, r, x)
-#define skein_show_r_ptr(bits, ctx, r, x_ptr)
-#define skein_show_final(bits, ctx, cnt, out_ptr)
-#define skein_show_key(bits, ctx, key, key_bytes)
-#endif
-
-/* ignore all asserts, for performance */
-#define skein_assert_ret(x, ret_code)
-#define skein_assert(x)
-
-/*****************************************************************
-** Skein block function constants (shared across Ref and Opt code)
-******************************************************************/
-enum {
-	    /* SKEIN_256 round rotation constants */
-	R_256_0_0 = 14, R_256_0_1 = 16,
-	R_256_1_0 = 52, R_256_1_1 = 57,
-	R_256_2_0 = 23, R_256_2_1 = 40,
-	R_256_3_0 =  5, R_256_3_1 = 37,
-	R_256_4_0 = 25, R_256_4_1 = 33,
-	R_256_5_0 = 46, R_256_5_1 = 12,
-	R_256_6_0 = 58, R_256_6_1 = 22,
-	R_256_7_0 = 32, R_256_7_1 = 32,
-
-	    /* SKEIN_512 round rotation constants */
-	R_512_0_0 = 46, R_512_0_1 = 36, R_512_0_2 = 19, R_512_0_3 = 37,
-	R_512_1_0 = 33, R_512_1_1 = 27, R_512_1_2 = 14, R_512_1_3 = 42,
-	R_512_2_0 = 17, R_512_2_1 = 49, R_512_2_2 = 36, R_512_2_3 = 39,
-	R_512_3_0 = 44, R_512_3_1 =  9, R_512_3_2 = 54, R_512_3_3 = 56,
-	R_512_4_0 = 39, R_512_4_1 = 30, R_512_4_2 = 34, R_512_4_3 = 24,
-	R_512_5_0 = 13, R_512_5_1 = 50, R_512_5_2 = 10, R_512_5_3 = 17,
-	R_512_6_0 = 25, R_512_6_1 = 29, R_512_6_2 = 39, R_512_6_3 = 43,
-	R_512_7_0 =  8, R_512_7_1 = 35, R_512_7_2 = 56, R_512_7_3 = 22,
-
-	    /* SKEIN_1024 round rotation constants */
-	R1024_0_0 = 24, R1024_0_1 = 13, R1024_0_2 =  8, R1024_0_3 = 47,
-	R1024_0_4 =  8, R1024_0_5 = 17, R1024_0_6 = 22, R1024_0_7 = 37,
-	R1024_1_0 = 38, R1024_1_1 = 19, R1024_1_2 = 10, R1024_1_3 = 55,
-	R1024_1_4 = 49, R1024_1_5 = 18, R1024_1_6 = 23, R1024_1_7 = 52,
-	R1024_2_0 = 33, R1024_2_1 =  4, R1024_2_2 = 51, R1024_2_3 = 13,
-	R1024_2_4 = 34, R1024_2_5 = 41, R1024_2_6 = 59, R1024_2_7 = 17,
-	R1024_3_0 =  5, R1024_3_1 = 20, R1024_3_2 = 48, R1024_3_3 = 41,
-	R1024_3_4 = 47, R1024_3_5 = 28, R1024_3_6 = 16, R1024_3_7 = 25,
-	R1024_4_0 = 41, R1024_4_1 =  9, R1024_4_2 = 37, R1024_4_3 = 31,
-	R1024_4_4 = 12, R1024_4_5 = 47, R1024_4_6 = 44, R1024_4_7 = 30,
-	R1024_5_0 = 16, R1024_5_1 = 34, R1024_5_2 = 56, R1024_5_3 = 51,
-	R1024_5_4 =  4, R1024_5_5 = 53, R1024_5_6 = 42, R1024_5_7 = 41,
-	R1024_6_0 = 31, R1024_6_1 = 44, R1024_6_2 = 47, R1024_6_3 = 46,
-	R1024_6_4 = 19, R1024_6_5 = 42, R1024_6_6 = 44, R1024_6_7 = 25,
-	R1024_7_0 =  9, R1024_7_1 = 48, R1024_7_2 = 35, R1024_7_3 = 52,
-	R1024_7_4 = 23, R1024_7_5 = 31, R1024_7_6 = 37, R1024_7_7 = 20
-};
-
-#ifndef SKEIN_ROUNDS
-#define SKEIN_256_ROUNDS_TOTAL (72)	/* # rounds for diff block sizes */
-#define SKEIN_512_ROUNDS_TOTAL (72)
-#define SKEIN_1024_ROUNDS_TOTAL (80)
-#else			/* allow command-line define in range 8*(5..14)   */
-#define SKEIN_256_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS/100) + 5) % 10) + 5))
-#define SKEIN_512_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS/10)  + 5) % 10) + 5))
-#define SKEIN_1024_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS)     + 5) % 10) + 5))
-#endif
-
-#endif  /* ifndef _SKEIN_H_ */
diff --git a/drivers/staging/skein/skein_api.h b/drivers/staging/skein/skein_api.h
index e02fa19..171b875 100644
--- a/drivers/staging/skein/skein_api.h
+++ b/drivers/staging/skein/skein_api.h
@@ -79,7 +79,7 @@ OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <linux/types.h>
-#include "skein.h"
+#include "skein_base.h"
 
 /**
  * Which Skein size to use
diff --git a/drivers/staging/skein/skein_base.c b/drivers/staging/skein/skein_base.c
new file mode 100644
index 0000000..e0994ea
--- /dev/null
+++ b/drivers/staging/skein/skein_base.c
@@ -0,0 +1,884 @@
+/***********************************************************************
+**
+** Implementation of the Skein hash function.
+**
+** Source code author: Doug Whiting, 2008.
+**
+** This algorithm and source code is released to the public domain.
+**
+************************************************************************/
+
+#define  SKEIN_PORT_CODE /* instantiate any code in skein_port.h */
+
+#include <linux/string.h>       /* get the memcpy/memset functions */
+#include <linux/export.h>
+#include "skein_base.h" /* get the Skein API definitions   */
+#include "skein_iv.h"    /* get precomputed IVs */
+#include "skein_block.h"
+
+/*****************************************************************/
+/*     256-bit Skein                                             */
+/*****************************************************************/
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* init the context for a straight hashing operation  */
+int skein_256_init(struct skein_256_ctx *ctx, size_t hash_bit_len)
+{
+	union {
+		u8 b[SKEIN_256_STATE_BYTES];
+		u64 w[SKEIN_256_STATE_WORDS];
+	} cfg;                              /* config block */
+
+	skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
+	ctx->h.hash_bit_len = hash_bit_len;         /* output hash bit count */
+
+	switch (hash_bit_len) { /* use pre-computed values, where available */
+	case  256:
+		memcpy(ctx->x, SKEIN_256_IV_256, sizeof(ctx->x));
+		break;
+	case  224:
+		memcpy(ctx->x, SKEIN_256_IV_224, sizeof(ctx->x));
+		break;
+	case  160:
+		memcpy(ctx->x, SKEIN_256_IV_160, sizeof(ctx->x));
+		break;
+	case  128:
+		memcpy(ctx->x, SKEIN_256_IV_128, sizeof(ctx->x));
+		break;
+	default:
+		/* here if there is no precomputed IV value available */
+		/*
+		 * build/process the config block, type == CONFIG (could be
+		 * precomputed)
+		 */
+		/* set tweaks: T0=0; T1=CFG | FINAL */
+		skein_start_new_type(ctx, CFG_FINAL);
+
+		/* set the schema, version */
+		cfg.w[0] = skein_swap64(SKEIN_SCHEMA_VER);
+		/* hash result length in bits */
+		cfg.w[1] = skein_swap64(hash_bit_len);
+		cfg.w[2] = skein_swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
+		/* zero pad config block */
+		memset(&cfg.w[3], 0, sizeof(cfg) - 3*sizeof(cfg.w[0]));
+
+		/* compute the initial chaining values from config block */
+		/* zero the chaining variables */
+		memset(ctx->x, 0, sizeof(ctx->x));
+		skein_256_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
+		break;
+	}
+	/* The chaining vars ctx->x are now initialized for hash_bit_len. */
+	/* Set up to process the data message portion of the hash (default) */
+	skein_start_new_type(ctx, MSG);              /* T0=0, T1= MSG type */
+
+	return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* init the context for a MAC and/or tree hash operation */
+/* [identical to skein_256_init() when key_bytes == 0 && \
+ *	tree_info == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
+int skein_256_init_ext(struct skein_256_ctx *ctx, size_t hash_bit_len,
+		       u64 tree_info, const u8 *key, size_t key_bytes)
+{
+	union {
+		u8  b[SKEIN_256_STATE_BYTES];
+		u64 w[SKEIN_256_STATE_WORDS];
+	} cfg; /* config block */
+
+	skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
+	skein_assert_ret(key_bytes == 0 || key != NULL, SKEIN_FAIL);
+
+	/* compute the initial chaining values ctx->x[], based on key */
+	if (key_bytes == 0) { /* is there a key? */
+		/* no key: use all zeroes as key for config block */
+		memset(ctx->x, 0, sizeof(ctx->x));
+	} else { /* here to pre-process a key */
+		skein_assert(sizeof(cfg.b) >= sizeof(ctx->x));
+		/* do a mini-Init right here */
+		/* set output hash bit count = state size */
+		ctx->h.hash_bit_len = 8*sizeof(ctx->x);
+		/* set tweaks: T0 = 0; T1 = KEY type */
+		skein_start_new_type(ctx, KEY);
+		/* zero the initial chaining variables */
+		memset(ctx->x, 0, sizeof(ctx->x));
+		/* hash the key */
+		skein_256_update(ctx, key, key_bytes);
+		/* put result into cfg.b[] */
+		skein_256_final_pad(ctx, cfg.b);
+		/* copy over into ctx->x[] */
+		memcpy(ctx->x, cfg.b, sizeof(cfg.b));
+	}
+	/*
+	 * build/process the config block, type == CONFIG (could be
+	 * precomputed for each key)
+	 */
+	/* output hash bit count */
+	ctx->h.hash_bit_len = hash_bit_len;
+	skein_start_new_type(ctx, CFG_FINAL);
+
+	/* pre-pad cfg.w[] with zeroes */
+	memset(&cfg.w, 0, sizeof(cfg.w));
+	cfg.w[0] = skein_swap64(SKEIN_SCHEMA_VER);
+	/* hash result length in bits */
+	cfg.w[1] = skein_swap64(hash_bit_len);
+	/* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
+	cfg.w[2] = skein_swap64(tree_info);
+
+	skein_show_key(256, &ctx->h, key, key_bytes);
+
+	/* compute the initial chaining values from config block */
+	skein_256_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
+
+	/* The chaining vars ctx->x are now initialized */
+	/* Set up to process the data message portion of the hash (default) */
+	skein_start_new_type(ctx, MSG);
+
+	return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* process the input bytes */
+int skein_256_update(struct skein_256_ctx *ctx, const u8 *msg,
+		     size_t msg_byte_cnt)
+{
+	size_t n;
+
+	/* catch uninitialized context */
+	skein_assert_ret(ctx->h.b_cnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
+
+	/* process full blocks, if any */
+	if (msg_byte_cnt + ctx->h.b_cnt > SKEIN_256_BLOCK_BYTES) {
+		/* finish up any buffered message data */
+		if (ctx->h.b_cnt) {
+			/* # bytes free in buffer b[] */
+			n = SKEIN_256_BLOCK_BYTES - ctx->h.b_cnt;
+			if (n) {
+				/* check on our logic here */
+				skein_assert(n < msg_byte_cnt);
+				memcpy(&ctx->b[ctx->h.b_cnt], msg, n);
+				msg_byte_cnt  -= n;
+				msg         += n;
+				ctx->h.b_cnt += n;
+			}
+			skein_assert(ctx->h.b_cnt == SKEIN_256_BLOCK_BYTES);
+			skein_256_process_block(ctx, ctx->b, 1,
+						SKEIN_256_BLOCK_BYTES);
+			ctx->h.b_cnt = 0;
+		}
+		/*
+		 * now process any remaining full blocks, directly from input
+		 * message data
+		 */
+		if (msg_byte_cnt > SKEIN_256_BLOCK_BYTES) {
+			/* number of full blocks to process */
+			n = (msg_byte_cnt-1) / SKEIN_256_BLOCK_BYTES;
+			skein_256_process_block(ctx, msg, n,
+						SKEIN_256_BLOCK_BYTES);
+			msg_byte_cnt -= n * SKEIN_256_BLOCK_BYTES;
+			msg        += n * SKEIN_256_BLOCK_BYTES;
+		}
+		skein_assert(ctx->h.b_cnt == 0);
+	}
+
+	/* copy any remaining source message data bytes into b[] */
+	if (msg_byte_cnt) {
+		skein_assert(msg_byte_cnt + ctx->h.b_cnt <=
+			     SKEIN_256_BLOCK_BYTES);
+		memcpy(&ctx->b[ctx->h.b_cnt], msg, msg_byte_cnt);
+		ctx->h.b_cnt += msg_byte_cnt;
+	}
+
+	return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* finalize the hash computation and output the result */
+int skein_256_final(struct skein_256_ctx *ctx, u8 *hash_val)
+{
+	size_t i, n, byte_cnt;
+	u64 x[SKEIN_256_STATE_WORDS];
+	/* catch uninitialized context */
+	skein_assert_ret(ctx->h.b_cnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
+
+	/* tag as the final block */
+	ctx->h.tweak[1] |= SKEIN_T1_FLAG_FINAL;
+	/* zero pad b[] if necessary */
+	if (ctx->h.b_cnt < SKEIN_256_BLOCK_BYTES)
+		memset(&ctx->b[ctx->h.b_cnt], 0,
+			SKEIN_256_BLOCK_BYTES - ctx->h.b_cnt);
+
+	/* process the final block */
+	skein_256_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
+
+	/* now output the result */
+	/* total number of output bytes */
+	byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
+
+	/* run Threefish in "counter mode" to generate output */
+	/* zero out b[], so it can hold the counter */
+	memset(ctx->b, 0, sizeof(ctx->b));
+	/* keep a local copy of counter mode "key" */
+	memcpy(x, ctx->x, sizeof(x));
+	for (i = 0; i*SKEIN_256_BLOCK_BYTES < byte_cnt; i++) {
+		/* build the counter block */
+		((u64 *)ctx->b)[0] = skein_swap64((u64) i);
+		skein_start_new_type(ctx, OUT_FINAL);
+		/* run "counter mode" */
+		skein_256_process_block(ctx, ctx->b, 1, sizeof(u64));
+		/* number of output bytes left to go */
+		n = byte_cnt - i*SKEIN_256_BLOCK_BYTES;
+		if (n >= SKEIN_256_BLOCK_BYTES)
+			n  = SKEIN_256_BLOCK_BYTES;
+		/* "output" the ctr mode bytes */
+		skein_put64_lsb_first(hash_val+i*SKEIN_256_BLOCK_BYTES, ctx->x,
+				      n);
+		skein_show_final(256, &ctx->h, n,
+				 hash_val+i*SKEIN_256_BLOCK_BYTES);
+		/* restore the counter mode key for next time */
+		memcpy(ctx->x, x, sizeof(x));
+	}
+	return SKEIN_SUCCESS;
+}
+
+/*****************************************************************/
+/*     512-bit Skein                                             */
+/*****************************************************************/
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* init the context for a straight hashing operation  */
+int skein_512_init(struct skein_512_ctx *ctx, size_t hash_bit_len)
+{
+	union {
+		u8 b[SKEIN_512_STATE_BYTES];
+		u64 w[SKEIN_512_STATE_WORDS];
+	} cfg;                              /* config block */
+
+	skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
+	ctx->h.hash_bit_len = hash_bit_len;         /* output hash bit count */
+
+	switch (hash_bit_len) { /* use pre-computed values, where available */
+	case  512:
+		memcpy(ctx->x, SKEIN_512_IV_512, sizeof(ctx->x));
+		break;
+	case  384:
+		memcpy(ctx->x, SKEIN_512_IV_384, sizeof(ctx->x));
+		break;
+	case  256:
+		memcpy(ctx->x, SKEIN_512_IV_256, sizeof(ctx->x));
+		break;
+	case  224:
+		memcpy(ctx->x, SKEIN_512_IV_224, sizeof(ctx->x));
+		break;
+	default:
+		/* here if there is no precomputed IV value available */
+		/*
+		 * build/process the config block, type == CONFIG (could be
+		 * precomputed)
+		 */
+		/* set tweaks: T0=0; T1=CFG | FINAL */
+		skein_start_new_type(ctx, CFG_FINAL);
+
+		/* set the schema, version */
+		cfg.w[0] = skein_swap64(SKEIN_SCHEMA_VER);
+		/* hash result length in bits */
+		cfg.w[1] = skein_swap64(hash_bit_len);
+		cfg.w[2] = skein_swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
+		/* zero pad config block */
+		memset(&cfg.w[3], 0, sizeof(cfg) - 3*sizeof(cfg.w[0]));
+
+		/* compute the initial chaining values from config block */
+		/* zero the chaining variables */
+		memset(ctx->x, 0, sizeof(ctx->x));
+		skein_512_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
+		break;
+	}
+
+	/*
+	 * The chaining vars ctx->x are now initialized for the given
+	 * hash_bit_len.
+	 */
+	/* Set up to process the data message portion of the hash (default) */
+	skein_start_new_type(ctx, MSG);              /* T0=0, T1= MSG type */
+
+	return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* init the context for a MAC and/or tree hash operation */
+/* [identical to skein_512_init() when key_bytes == 0 && \
+ *	tree_info == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
+int skein_512_init_ext(struct skein_512_ctx *ctx, size_t hash_bit_len,
+		       u64 tree_info, const u8 *key, size_t key_bytes)
+{
+	union {
+		u8 b[SKEIN_512_STATE_BYTES];
+		u64 w[SKEIN_512_STATE_WORDS];
+	} cfg;                              /* config block */
+
+	skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
+	skein_assert_ret(key_bytes == 0 || key != NULL, SKEIN_FAIL);
+
+	/* compute the initial chaining values ctx->x[], based on key */
+	if (key_bytes == 0) { /* is there a key? */
+		/* no key: use all zeroes as key for config block */
+		memset(ctx->x, 0, sizeof(ctx->x));
+	} else { /* here to pre-process a key */
+		skein_assert(sizeof(cfg.b) >= sizeof(ctx->x));
+		/* do a mini-Init right here */
+		/* set output hash bit count = state size */
+		ctx->h.hash_bit_len = 8*sizeof(ctx->x);
+		/* set tweaks: T0 = 0; T1 = KEY type */
+		skein_start_new_type(ctx, KEY);
+		/* zero the initial chaining variables */
+		memset(ctx->x, 0, sizeof(ctx->x));
+		/* hash the key */
+		skein_512_update(ctx, key, key_bytes);
+		/* put result into cfg.b[] */
+		skein_512_final_pad(ctx, cfg.b);
+		/* copy over into ctx->x[] */
+		memcpy(ctx->x, cfg.b, sizeof(cfg.b));
+	}
+	/*
+	 * build/process the config block, type == CONFIG (could be
+	 * precomputed for each key)
+	 */
+	ctx->h.hash_bit_len = hash_bit_len;          /* output hash bit count */
+	skein_start_new_type(ctx, CFG_FINAL);
+
+	/* pre-pad cfg.w[] with zeroes */
+	memset(&cfg.w, 0, sizeof(cfg.w));
+	cfg.w[0] = skein_swap64(SKEIN_SCHEMA_VER);
+	/* hash result length in bits */
+	cfg.w[1] = skein_swap64(hash_bit_len);
+	/* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
+	cfg.w[2] = skein_swap64(tree_info);
+
+	skein_show_key(512, &ctx->h, key, key_bytes);
+
+	/* compute the initial chaining values from config block */
+	skein_512_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
+
+	/* The chaining vars ctx->x are now initialized */
+	/* Set up to process the data message portion of the hash (default) */
+	skein_start_new_type(ctx, MSG);
+
+	return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* process the input bytes */
+int skein_512_update(struct skein_512_ctx *ctx, const u8 *msg,
+		     size_t msg_byte_cnt)
+{
+	size_t n;
+
+	/* catch uninitialized context */
+	skein_assert_ret(ctx->h.b_cnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
+
+	/* process full blocks, if any */
+	if (msg_byte_cnt + ctx->h.b_cnt > SKEIN_512_BLOCK_BYTES) {
+		/* finish up any buffered message data */
+		if (ctx->h.b_cnt) {
+			/* # bytes free in buffer b[] */
+			n = SKEIN_512_BLOCK_BYTES - ctx->h.b_cnt;
+			if (n) {
+				/* check on our logic here */
+				skein_assert(n < msg_byte_cnt);
+				memcpy(&ctx->b[ctx->h.b_cnt], msg, n);
+				msg_byte_cnt  -= n;
+				msg         += n;
+				ctx->h.b_cnt += n;
+			}
+			skein_assert(ctx->h.b_cnt == SKEIN_512_BLOCK_BYTES);
+			skein_512_process_block(ctx, ctx->b, 1,
+						SKEIN_512_BLOCK_BYTES);
+			ctx->h.b_cnt = 0;
+		}
+		/*
+		 * now process any remaining full blocks, directly from input
+		 * message data
+		 */
+		if (msg_byte_cnt > SKEIN_512_BLOCK_BYTES) {
+			/* number of full blocks to process */
+			n = (msg_byte_cnt-1) / SKEIN_512_BLOCK_BYTES;
+			skein_512_process_block(ctx, msg, n,
+						SKEIN_512_BLOCK_BYTES);
+			msg_byte_cnt -= n * SKEIN_512_BLOCK_BYTES;
+			msg        += n * SKEIN_512_BLOCK_BYTES;
+		}
+		skein_assert(ctx->h.b_cnt == 0);
+	}
+
+	/* copy any remaining source message data bytes into b[] */
+	if (msg_byte_cnt) {
+		skein_assert(msg_byte_cnt + ctx->h.b_cnt <=
+			     SKEIN_512_BLOCK_BYTES);
+		memcpy(&ctx->b[ctx->h.b_cnt], msg, msg_byte_cnt);
+		ctx->h.b_cnt += msg_byte_cnt;
+	}
+
+	return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* finalize the hash computation and output the result */
+int skein_512_final(struct skein_512_ctx *ctx, u8 *hash_val)
+{
+	size_t i, n, byte_cnt;
+	u64 x[SKEIN_512_STATE_WORDS];
+	/* catch uninitialized context */
+	skein_assert_ret(ctx->h.b_cnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
+
+	/* tag as the final block */
+	ctx->h.tweak[1] |= SKEIN_T1_FLAG_FINAL;
+	/* zero pad b[] if necessary */
+	if (ctx->h.b_cnt < SKEIN_512_BLOCK_BYTES)
+		memset(&ctx->b[ctx->h.b_cnt], 0,
+			SKEIN_512_BLOCK_BYTES - ctx->h.b_cnt);
+
+	/* process the final block */
+	skein_512_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
+
+	/* now output the result */
+	/* total number of output bytes */
+	byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
+
+	/* run Threefish in "counter mode" to generate output */
+	/* zero out b[], so it can hold the counter */
+	memset(ctx->b, 0, sizeof(ctx->b));
+	/* keep a local copy of counter mode "key" */
+	memcpy(x, ctx->x, sizeof(x));
+	for (i = 0; i*SKEIN_512_BLOCK_BYTES < byte_cnt; i++) {
+		/* build the counter block */
+		((u64 *)ctx->b)[0] = skein_swap64((u64) i);
+		skein_start_new_type(ctx, OUT_FINAL);
+		/* run "counter mode" */
+		skein_512_process_block(ctx, ctx->b, 1, sizeof(u64));
+		/* number of output bytes left to go */
+		n = byte_cnt - i*SKEIN_512_BLOCK_BYTES;
+		if (n >= SKEIN_512_BLOCK_BYTES)
+			n  = SKEIN_512_BLOCK_BYTES;
+		/* "output" the ctr mode bytes */
+		skein_put64_lsb_first(hash_val+i*SKEIN_512_BLOCK_BYTES, ctx->x,
+				      n);
+		skein_show_final(512, &ctx->h, n,
+				 hash_val+i*SKEIN_512_BLOCK_BYTES);
+		/* restore the counter mode key for next time */
+		memcpy(ctx->x, x, sizeof(x));
+	}
+	return SKEIN_SUCCESS;
+}
+
+/*****************************************************************/
+/*    1024-bit Skein                                             */
+/*****************************************************************/
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* init the context for a straight hashing operation  */
+int skein_1024_init(struct skein_1024_ctx *ctx, size_t hash_bit_len)
+{
+	union {
+		u8 b[SKEIN_1024_STATE_BYTES];
+		u64 w[SKEIN_1024_STATE_WORDS];
+	} cfg;                              /* config block */
+
+	skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
+	ctx->h.hash_bit_len = hash_bit_len;         /* output hash bit count */
+
+	switch (hash_bit_len) { /* use pre-computed values, where available */
+	case  512:
+		memcpy(ctx->x, SKEIN_1024_IV_512, sizeof(ctx->x));
+		break;
+	case  384:
+		memcpy(ctx->x, SKEIN_1024_IV_384, sizeof(ctx->x));
+		break;
+	case 1024:
+		memcpy(ctx->x, SKEIN_1024_IV_1024, sizeof(ctx->x));
+		break;
+	default:
+		/* here if there is no precomputed IV value available */
+		/*
+		 * build/process the config block, type == CONFIG
+		 * (could be precomputed)
+		 */
+		/* set tweaks: T0=0; T1=CFG | FINAL */
+		skein_start_new_type(ctx, CFG_FINAL);
+
+		/* set the schema, version */
+		cfg.w[0] = skein_swap64(SKEIN_SCHEMA_VER);
+		/* hash result length in bits */
+		cfg.w[1] = skein_swap64(hash_bit_len);
+		cfg.w[2] = skein_swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
+		/* zero pad config block */
+		memset(&cfg.w[3], 0, sizeof(cfg) - 3*sizeof(cfg.w[0]));
+
+		/* compute the initial chaining values from config block */
+		/* zero the chaining variables */
+		memset(ctx->x, 0, sizeof(ctx->x));
+		skein_1024_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
+		break;
+	}
+
+	/* The chaining vars ctx->x are now initialized for the hash_bit_len. */
+	/* Set up to process the data message portion of the hash (default) */
+	skein_start_new_type(ctx, MSG);              /* T0=0, T1= MSG type */
+
+	return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* init the context for a MAC and/or tree hash operation */
+/* [identical to skein_1024_init() when key_bytes == 0 && \
+ *	tree_info == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
+int skein_1024_init_ext(struct skein_1024_ctx *ctx, size_t hash_bit_len,
+			u64 tree_info, const u8 *key, size_t key_bytes)
+{
+	union {
+		u8 b[SKEIN_1024_STATE_BYTES];
+		u64 w[SKEIN_1024_STATE_WORDS];
+	} cfg;                              /* config block */
+
+	skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
+	skein_assert_ret(key_bytes == 0 || key != NULL, SKEIN_FAIL);
+
+	/* compute the initial chaining values ctx->x[], based on key */
+	if (key_bytes == 0) { /* is there a key? */
+		/* no key: use all zeroes as key for config block */
+		memset(ctx->x, 0, sizeof(ctx->x));
+	} else { /* here to pre-process a key */
+		skein_assert(sizeof(cfg.b) >= sizeof(ctx->x));
+		/* do a mini-Init right here */
+		/* set output hash bit count = state size */
+		ctx->h.hash_bit_len = 8*sizeof(ctx->x);
+		/* set tweaks: T0 = 0; T1 = KEY type */
+		skein_start_new_type(ctx, KEY);
+		/* zero the initial chaining variables */
+		memset(ctx->x, 0, sizeof(ctx->x));
+		/* hash the key */
+		skein_1024_update(ctx, key, key_bytes);
+		/* put result into cfg.b[] */
+		skein_1024_final_pad(ctx, cfg.b);
+		/* copy over into ctx->x[] */
+		memcpy(ctx->x, cfg.b, sizeof(cfg.b));
+	}
+	/*
+	 * build/process the config block, type == CONFIG (could be
+	 * precomputed for each key)
+	 */
+	/* output hash bit count */
+	ctx->h.hash_bit_len = hash_bit_len;
+	skein_start_new_type(ctx, CFG_FINAL);
+
+	/* pre-pad cfg.w[] with zeroes */
+	memset(&cfg.w, 0, sizeof(cfg.w));
+	cfg.w[0] = skein_swap64(SKEIN_SCHEMA_VER);
+	/* hash result length in bits */
+	cfg.w[1] = skein_swap64(hash_bit_len);
+	/* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
+	cfg.w[2] = skein_swap64(tree_info);
+
+	skein_show_key(1024, &ctx->h, key, key_bytes);
+
+	/* compute the initial chaining values from config block */
+	skein_1024_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
+
+	/* The chaining vars ctx->x are now initialized */
+	/* Set up to process the data message portion of the hash (default) */
+	skein_start_new_type(ctx, MSG);
+
+	return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* process the input bytes */
+int skein_1024_update(struct skein_1024_ctx *ctx, const u8 *msg,
+		      size_t msg_byte_cnt)
+{
+	size_t n;
+
+	/* catch uninitialized context */
+	skein_assert_ret(ctx->h.b_cnt <= SKEIN_1024_BLOCK_BYTES, SKEIN_FAIL);
+
+	/* process full blocks, if any */
+	if (msg_byte_cnt + ctx->h.b_cnt > SKEIN_1024_BLOCK_BYTES) {
+		/* finish up any buffered message data */
+		if (ctx->h.b_cnt) {
+			/* # bytes free in buffer b[] */
+			n = SKEIN_1024_BLOCK_BYTES - ctx->h.b_cnt;
+			if (n) {
+				/* check on our logic here */
+				skein_assert(n < msg_byte_cnt);
+				memcpy(&ctx->b[ctx->h.b_cnt], msg, n);
+				msg_byte_cnt  -= n;
+				msg         += n;
+				ctx->h.b_cnt += n;
+			}
+			skein_assert(ctx->h.b_cnt == SKEIN_1024_BLOCK_BYTES);
+			skein_1024_process_block(ctx, ctx->b, 1,
+						 SKEIN_1024_BLOCK_BYTES);
+			ctx->h.b_cnt = 0;
+		}
+		/*
+		 * now process any remaining full blocks, directly from input
+		 * message data
+		 */
+		if (msg_byte_cnt > SKEIN_1024_BLOCK_BYTES) {
+			/* number of full blocks to process */
+			n = (msg_byte_cnt-1) / SKEIN_1024_BLOCK_BYTES;
+			skein_1024_process_block(ctx, msg, n,
+						 SKEIN_1024_BLOCK_BYTES);
+			msg_byte_cnt -= n * SKEIN_1024_BLOCK_BYTES;
+			msg        += n * SKEIN_1024_BLOCK_BYTES;
+		}
+		skein_assert(ctx->h.b_cnt == 0);
+	}
+
+	/* copy any remaining source message data bytes into b[] */
+	if (msg_byte_cnt) {
+		skein_assert(msg_byte_cnt + ctx->h.b_cnt <=
+			     SKEIN_1024_BLOCK_BYTES);
+		memcpy(&ctx->b[ctx->h.b_cnt], msg, msg_byte_cnt);
+		ctx->h.b_cnt += msg_byte_cnt;
+	}
+
+	return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* finalize the hash computation and output the result */
+int skein_1024_final(struct skein_1024_ctx *ctx, u8 *hash_val)
+{
+	size_t i, n, byte_cnt;
+	u64 x[SKEIN_1024_STATE_WORDS];
+	/* catch uninitialized context */
+	skein_assert_ret(ctx->h.b_cnt <= SKEIN_1024_BLOCK_BYTES, SKEIN_FAIL);
+
+	/* tag as the final block */
+	ctx->h.tweak[1] |= SKEIN_T1_FLAG_FINAL;
+	/* zero pad b[] if necessary */
+	if (ctx->h.b_cnt < SKEIN_1024_BLOCK_BYTES)
+		memset(&ctx->b[ctx->h.b_cnt], 0,
+			SKEIN_1024_BLOCK_BYTES - ctx->h.b_cnt);
+
+	/* process the final block */
+	skein_1024_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
+
+	/* now output the result */
+	/* total number of output bytes */
+	byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
+
+	/* run Threefish in "counter mode" to generate output */
+	/* zero out b[], so it can hold the counter */
+	memset(ctx->b, 0, sizeof(ctx->b));
+	/* keep a local copy of counter mode "key" */
+	memcpy(x, ctx->x, sizeof(x));
+	for (i = 0; i*SKEIN_1024_BLOCK_BYTES < byte_cnt; i++) {
+		/* build the counter block */
+		((u64 *)ctx->b)[0] = skein_swap64((u64) i);
+		skein_start_new_type(ctx, OUT_FINAL);
+		/* run "counter mode" */
+		skein_1024_process_block(ctx, ctx->b, 1, sizeof(u64));
+		/* number of output bytes left to go */
+		n = byte_cnt - i*SKEIN_1024_BLOCK_BYTES;
+		if (n >= SKEIN_1024_BLOCK_BYTES)
+			n  = SKEIN_1024_BLOCK_BYTES;
+		/* "output" the ctr mode bytes */
+		skein_put64_lsb_first(hash_val+i*SKEIN_1024_BLOCK_BYTES, ctx->x,
+				      n);
+		skein_show_final(1024, &ctx->h, n,
+				 hash_val+i*SKEIN_1024_BLOCK_BYTES);
+		/* restore the counter mode key for next time */
+		memcpy(ctx->x, x, sizeof(x));
+	}
+	return SKEIN_SUCCESS;
+}
+
+/**************** Functions to support MAC/tree hashing ***************/
+/*   (this code is identical for Optimized and Reference versions)    */
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* finalize the hash computation and output the block, no OUTPUT stage */
+int skein_256_final_pad(struct skein_256_ctx *ctx, u8 *hash_val)
+{
+	/* catch uninitialized context */
+	skein_assert_ret(ctx->h.b_cnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
+
+	/* tag as the final block */
+	ctx->h.tweak[1] |= SKEIN_T1_FLAG_FINAL;
+	/* zero pad b[] if necessary */
+	if (ctx->h.b_cnt < SKEIN_256_BLOCK_BYTES)
+		memset(&ctx->b[ctx->h.b_cnt], 0,
+			SKEIN_256_BLOCK_BYTES - ctx->h.b_cnt);
+	/* process the final block */
+	skein_256_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
+
+	/* "output" the state bytes */
+	skein_put64_lsb_first(hash_val, ctx->x, SKEIN_256_BLOCK_BYTES);
+
+	return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* finalize the hash computation and output the block, no OUTPUT stage */
+int skein_512_final_pad(struct skein_512_ctx *ctx, u8 *hash_val)
+{
+	/* catch uninitialized context */
+	skein_assert_ret(ctx->h.b_cnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
+
+	/* tag as the final block */
+	ctx->h.tweak[1] |= SKEIN_T1_FLAG_FINAL;
+	/* zero pad b[] if necessary */
+	if (ctx->h.b_cnt < SKEIN_512_BLOCK_BYTES)
+		memset(&ctx->b[ctx->h.b_cnt], 0,
+			SKEIN_512_BLOCK_BYTES - ctx->h.b_cnt);
+	/* process the final block */
+	skein_512_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
+
+	/* "output" the state bytes */
+	skein_put64_lsb_first(hash_val, ctx->x, SKEIN_512_BLOCK_BYTES);
+
+	return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* finalize the hash computation and output the block, no OUTPUT stage */
+int skein_1024_final_pad(struct skein_1024_ctx *ctx, u8 *hash_val)
+{
+	/* catch uninitialized context */
+	skein_assert_ret(ctx->h.b_cnt <= SKEIN_1024_BLOCK_BYTES, SKEIN_FAIL);
+
+	/* tag as the final block */
+	ctx->h.tweak[1] |= SKEIN_T1_FLAG_FINAL;
+	/* zero pad b[] if necessary */
+	if (ctx->h.b_cnt < SKEIN_1024_BLOCK_BYTES)
+		memset(&ctx->b[ctx->h.b_cnt], 0,
+			SKEIN_1024_BLOCK_BYTES - ctx->h.b_cnt);
+	/* process the final block */
+	skein_1024_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
+
+	/* "output" the state bytes */
+	skein_put64_lsb_first(hash_val, ctx->x, SKEIN_1024_BLOCK_BYTES);
+
+	return SKEIN_SUCCESS;
+}
+
+#if SKEIN_TREE_HASH
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* just do the OUTPUT stage                                       */
+int skein_256_output(struct skein_256_ctx *ctx, u8 *hash_val)
+{
+	size_t i, n, byte_cnt;
+	u64 x[SKEIN_256_STATE_WORDS];
+	/* catch uninitialized context */
+	skein_assert_ret(ctx->h.b_cnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
+
+	/* now output the result */
+	/* total number of output bytes */
+	byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
+
+	/* run Threefish in "counter mode" to generate output */
+	/* zero out b[], so it can hold the counter */
+	memset(ctx->b, 0, sizeof(ctx->b));
+	/* keep a local copy of counter mode "key" */
+	memcpy(x, ctx->x, sizeof(x));
+	for (i = 0; i*SKEIN_256_BLOCK_BYTES < byte_cnt; i++) {
+		/* build the counter block */
+		((u64 *)ctx->b)[0] = skein_swap64((u64) i);
+		skein_start_new_type(ctx, OUT_FINAL);
+		/* run "counter mode" */
+		skein_256_process_block(ctx, ctx->b, 1, sizeof(u64));
+		/* number of output bytes left to go */
+		n = byte_cnt - i*SKEIN_256_BLOCK_BYTES;
+		if (n >= SKEIN_256_BLOCK_BYTES)
+			n  = SKEIN_256_BLOCK_BYTES;
+		/* "output" the ctr mode bytes */
+		skein_put64_lsb_first(hash_val+i*SKEIN_256_BLOCK_BYTES, ctx->x,
+				      n);
+		skein_show_final(256, &ctx->h, n,
+				 hash_val+i*SKEIN_256_BLOCK_BYTES);
+		/* restore the counter mode key for next time */
+		memcpy(ctx->x, x, sizeof(x));
+	}
+	return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* just do the OUTPUT stage                                       */
+int skein_512_output(struct skein_512_ctx *ctx, u8 *hash_val)
+{
+	size_t i, n, byte_cnt;
+	u64 x[SKEIN_512_STATE_WORDS];
+	/* catch uninitialized context */
+	skein_assert_ret(ctx->h.b_cnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
+
+	/* now output the result */
+	/* total number of output bytes */
+	byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
+
+	/* run Threefish in "counter mode" to generate output */
+	/* zero out b[], so it can hold the counter */
+	memset(ctx->b, 0, sizeof(ctx->b));
+	/* keep a local copy of counter mode "key" */
+	memcpy(x, ctx->x, sizeof(x));
+	for (i = 0; i*SKEIN_512_BLOCK_BYTES < byte_cnt; i++) {
+		/* build the counter block */
+		((u64 *)ctx->b)[0] = skein_swap64((u64) i);
+		skein_start_new_type(ctx, OUT_FINAL);
+		/* run "counter mode" */
+		skein_512_process_block(ctx, ctx->b, 1, sizeof(u64));
+		/* number of output bytes left to go */
+		n = byte_cnt - i*SKEIN_512_BLOCK_BYTES;
+		if (n >= SKEIN_512_BLOCK_BYTES)
+			n  = SKEIN_512_BLOCK_BYTES;
+		/* "output" the ctr mode bytes */
+		skein_put64_lsb_first(hash_val+i*SKEIN_512_BLOCK_BYTES, ctx->x,
+				      n);
+		skein_show_final(256, &ctx->h, n,
+				 hash_val+i*SKEIN_512_BLOCK_BYTES);
+		/* restore the counter mode key for next time */
+		memcpy(ctx->x, x, sizeof(x));
+	}
+	return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* just do the OUTPUT stage                                       */
+int skein_1024_output(struct skein_1024_ctx *ctx, u8 *hash_val)
+{
+	size_t i, n, byte_cnt;
+	u64 x[SKEIN_1024_STATE_WORDS];
+	/* catch uninitialized context */
+	skein_assert_ret(ctx->h.b_cnt <= SKEIN_1024_BLOCK_BYTES, SKEIN_FAIL);
+
+	/* now output the result */
+	/* total number of output bytes */
+	byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
+
+	/* run Threefish in "counter mode" to generate output */
+	/* zero out b[], so it can hold the counter */
+	memset(ctx->b, 0, sizeof(ctx->b));
+	/* keep a local copy of counter mode "key" */
+	memcpy(x, ctx->x, sizeof(x));
+	for (i = 0; i*SKEIN_1024_BLOCK_BYTES < byte_cnt; i++) {
+		/* build the counter block */
+		((u64 *)ctx->b)[0] = skein_swap64((u64) i);
+		skein_start_new_type(ctx, OUT_FINAL);
+		/* run "counter mode" */
+		skein_1024_process_block(ctx, ctx->b, 1, sizeof(u64));
+		/* number of output bytes left to go */
+		n = byte_cnt - i*SKEIN_1024_BLOCK_BYTES;
+		if (n >= SKEIN_1024_BLOCK_BYTES)
+			n  = SKEIN_1024_BLOCK_BYTES;
+		/* "output" the ctr mode bytes */
+		skein_put64_lsb_first(hash_val+i*SKEIN_1024_BLOCK_BYTES, ctx->x,
+				      n);
+		skein_show_final(256, &ctx->h, n,
+				 hash_val+i*SKEIN_1024_BLOCK_BYTES);
+		/* restore the counter mode key for next time */
+		memcpy(ctx->x, x, sizeof(x));
+	}
+	return SKEIN_SUCCESS;
+}
+#endif
diff --git a/drivers/staging/skein/skein_base.h b/drivers/staging/skein/skein_base.h
new file mode 100644
index 0000000..9f10af9
--- /dev/null
+++ b/drivers/staging/skein/skein_base.h
@@ -0,0 +1,351 @@
+#ifndef _SKEIN_H_
+#define _SKEIN_H_     1
+/**************************************************************************
+**
+** Interface declarations and internal definitions for Skein hashing.
+**
+** Source code author: Doug Whiting, 2008.
+**
+** This algorithm and source code is released to the public domain.
+**
+***************************************************************************
+**
+** The following compile-time switches may be defined to control some
+** tradeoffs between speed, code size, error checking, and security.
+**
+** The "default" note explains what happens when the switch is not defined.
+**
+**  SKEIN_DEBUG            -- make callouts from inside Skein code
+**                            to examine/display intermediate values.
+**                            [default: no callouts (no overhead)]
+**
+**  SKEIN_ERR_CHECK        -- how error checking is handled inside Skein
+**                            code. If not defined, most error checking
+**                            is disabled (for performance). Otherwise,
+**                            the switch value is interpreted as:
+**                                0: use assert()      to flag errors
+**                                1: return SKEIN_FAIL to flag errors
+**
+***************************************************************************/
+
+/*Skein digest sizes for crypto api*/
+#define SKEIN256_DIGEST_BIT_SIZE 256
+#define SKEIN512_DIGEST_BIT_SIZE 512
+#define SKEIN1024_DIGEST_BIT_SIZE 1024
+
+#ifndef rotl_64
+#define rotl_64(x, N)    (((x) << (N)) | ((x) >> (64-(N))))
+#endif
+
+/* below two prototype assume we are handed aligned data */
+#define skein_put64_lsb_first(dst08, src64, b_cnt) memcpy(dst08, src64, b_cnt)
+#define skein_get64_lsb_first(dst64, src08, w_cnt) \
+		memcpy(dst64, src08, 8*(w_cnt))
+#define skein_swap64(w64)  (w64)
+
+enum {
+	SKEIN_SUCCESS         =      0, /* return codes from Skein calls */
+	SKEIN_FAIL            =      1,
+	SKEIN_BAD_HASHLEN     =      2
+};
+
+#define  SKEIN_MODIFIER_WORDS   (2) /* number of modifier (tweak) words */
+
+#define  SKEIN_256_STATE_WORDS  (4)
+#define  SKEIN_512_STATE_WORDS  (8)
+#define  SKEIN_1024_STATE_WORDS (16)
+#define  SKEIN_MAX_STATE_WORDS (16)
+
+#define  SKEIN_256_STATE_BYTES  (8*SKEIN_256_STATE_WORDS)
+#define  SKEIN_512_STATE_BYTES  (8*SKEIN_512_STATE_WORDS)
+#define  SKEIN_1024_STATE_BYTES  (8*SKEIN_1024_STATE_WORDS)
+
+#define  SKEIN_256_STATE_BITS  (64*SKEIN_256_STATE_WORDS)
+#define  SKEIN_512_STATE_BITS  (64*SKEIN_512_STATE_WORDS)
+#define  SKEIN_1024_STATE_BITS  (64*SKEIN_1024_STATE_WORDS)
+
+#define  SKEIN_256_BLOCK_BYTES  (8*SKEIN_256_STATE_WORDS)
+#define  SKEIN_512_BLOCK_BYTES  (8*SKEIN_512_STATE_WORDS)
+#define  SKEIN_1024_BLOCK_BYTES  (8*SKEIN_1024_STATE_WORDS)
+
+struct skein_ctx_hdr {
+	size_t hash_bit_len;		/* size of hash result, in bits */
+	size_t b_cnt;			/* current byte count in buffer b[] */
+	u64 tweak[SKEIN_MODIFIER_WORDS]; /* tweak[0]=byte cnt, tweak[1]=flags */
+};
+
+struct skein_256_ctx { /* 256-bit Skein hash context structure */
+	struct skein_ctx_hdr h;		/* common header context variables */
+	u64 x[SKEIN_256_STATE_WORDS];	/* chaining variables */
+	u8 b[SKEIN_256_BLOCK_BYTES];	/* partial block buf (8-byte aligned) */
+};
+
+struct skein_512_ctx { /* 512-bit Skein hash context structure */
+	struct skein_ctx_hdr h;		/* common header context variables */
+	u64 x[SKEIN_512_STATE_WORDS];	/* chaining variables */
+	u8 b[SKEIN_512_BLOCK_BYTES];	/* partial block buf (8-byte aligned) */
+};
+
+struct skein_1024_ctx { /* 1024-bit Skein hash context structure */
+	struct skein_ctx_hdr h;		/* common header context variables */
+	u64 x[SKEIN_1024_STATE_WORDS];	/* chaining variables */
+	u8 b[SKEIN_1024_BLOCK_BYTES];	/* partial block buf (8-byte aligned) */
+};
+
+/* Skein APIs for (incremental) "straight hashing" */
+int skein_256_init(struct skein_256_ctx *ctx, size_t hash_bit_len);
+int skein_512_init(struct skein_512_ctx *ctx, size_t hash_bit_len);
+int skein_1024_init(struct skein_1024_ctx *ctx, size_t hash_bit_len);
+
+int skein_256_update(struct skein_256_ctx *ctx, const u8 *msg,
+		     size_t msg_byte_cnt);
+int skein_512_update(struct skein_512_ctx *ctx, const u8 *msg,
+		     size_t msg_byte_cnt);
+int skein_1024_update(struct skein_1024_ctx *ctx, const u8 *msg,
+		      size_t msg_byte_cnt);
+
+int skein_256_final(struct skein_256_ctx *ctx, u8 *hash_val);
+int skein_512_final(struct skein_512_ctx *ctx, u8 *hash_val);
+int skein_1024_final(struct skein_1024_ctx *ctx, u8 *hash_val);
+
+/*
+**   Skein APIs for "extended" initialization: MAC keys, tree hashing.
+**   After an init_ext() call, just use update/final calls as with init().
+**
+**   Notes: Same parameters as _init() calls, plus tree_info/key/key_bytes.
+**          When key_bytes == 0 and tree_info == SKEIN_SEQUENTIAL,
+**              the results of init_ext() are identical to calling init().
+**          The function init() may be called once to "precompute" the IV for
+**              a given hash_bit_len value, then by saving a copy of the context
+**              the IV computation may be avoided in later calls.
+**          Similarly, the function init_ext() may be called once per MAC key
+**              to precompute the MAC IV, then a copy of the context saved and
+**              reused for each new MAC computation.
+**/
+int skein_256_init_ext(struct skein_256_ctx *ctx, size_t hash_bit_len,
+		       u64 tree_info, const u8 *key, size_t key_bytes);
+int skein_512_init_ext(struct skein_512_ctx *ctx, size_t hash_bit_len,
+		       u64 tree_info, const u8 *key, size_t key_bytes);
+int skein_1024_init_ext(struct skein_1024_ctx *ctx, size_t hash_bit_len,
+			u64 tree_info, const u8 *key, size_t key_bytes);
+
+/*
+**   Skein APIs for MAC and tree hash:
+**      final_pad:  pad, do final block, but no OUTPUT type
+**      output:     do just the output stage
+*/
+int skein_256_final_pad(struct skein_256_ctx *ctx, u8 *hash_val);
+int skein_512_final_pad(struct skein_512_ctx *ctx, u8 *hash_val);
+int skein_1024_final_pad(struct skein_1024_ctx *ctx, u8 *hash_val);
+
+#ifndef SKEIN_TREE_HASH
+#define SKEIN_TREE_HASH (1)
+#endif
+#if  SKEIN_TREE_HASH
+int skein_256_output(struct skein_256_ctx *ctx, u8 *hash_val);
+int skein_512_output(struct skein_512_ctx *ctx, u8 *hash_val);
+int skein_1024_output(struct skein_1024_ctx *ctx, u8 *hash_val);
+#endif
+
+/*****************************************************************
+** "Internal" Skein definitions
+**    -- not needed for sequential hashing API, but will be
+**           helpful for other uses of Skein (e.g., tree hash mode).
+**    -- included here so that they can be shared between
+**           reference and optimized code.
+******************************************************************/
+
+/* tweak word tweak[1]: bit field starting positions */
+#define SKEIN_T1_BIT(BIT)       ((BIT) - 64)      /* second word  */
+
+#define SKEIN_T1_POS_TREE_LVL   SKEIN_T1_BIT(112) /* 112..118 hash tree level */
+#define SKEIN_T1_POS_BIT_PAD    SKEIN_T1_BIT(119) /* 119 part. final in byte */
+#define SKEIN_T1_POS_BLK_TYPE   SKEIN_T1_BIT(120) /* 120..125 type field `*/
+#define SKEIN_T1_POS_FIRST      SKEIN_T1_BIT(126) /* 126      first blk flag */
+#define SKEIN_T1_POS_FINAL      SKEIN_T1_BIT(127) /* 127      final blk flag */
+
+/* tweak word tweak[1]: flag bit definition(s) */
+#define SKEIN_T1_FLAG_FIRST     (((u64)  1) << SKEIN_T1_POS_FIRST)
+#define SKEIN_T1_FLAG_FINAL     (((u64)  1) << SKEIN_T1_POS_FINAL)
+#define SKEIN_T1_FLAG_BIT_PAD   (((u64)  1) << SKEIN_T1_POS_BIT_PAD)
+
+/* tweak word tweak[1]: tree level bit field mask */
+#define SKEIN_T1_TREE_LVL_MASK  (((u64)0x7F) << SKEIN_T1_POS_TREE_LVL)
+#define SKEIN_T1_TREE_LEVEL(n)  (((u64) (n)) << SKEIN_T1_POS_TREE_LVL)
+
+/* tweak word tweak[1]: block type field */
+#define SKEIN_BLK_TYPE_KEY       (0) /* key, for MAC and KDF */
+#define SKEIN_BLK_TYPE_CFG       (4) /* configuration block */
+#define SKEIN_BLK_TYPE_PERS      (8) /* personalization string */
+#define SKEIN_BLK_TYPE_PK       (12) /* pubkey (for digital sigs) */
+#define SKEIN_BLK_TYPE_KDF      (16) /* key identifier for KDF */
+#define SKEIN_BLK_TYPE_NONCE    (20) /* nonce for PRNG */
+#define SKEIN_BLK_TYPE_MSG      (48) /* message processing */
+#define SKEIN_BLK_TYPE_OUT      (63) /* output stage */
+#define SKEIN_BLK_TYPE_MASK     (63) /* bit field mask */
+
+#define SKEIN_T1_BLK_TYPE(T)   (((u64) (SKEIN_BLK_TYPE_##T)) << \
+					SKEIN_T1_POS_BLK_TYPE)
+#define SKEIN_T1_BLK_TYPE_KEY   SKEIN_T1_BLK_TYPE(KEY)  /* for MAC and KDF */
+#define SKEIN_T1_BLK_TYPE_CFG   SKEIN_T1_BLK_TYPE(CFG)  /* config block */
+#define SKEIN_T1_BLK_TYPE_PERS  SKEIN_T1_BLK_TYPE(PERS) /* personalization */
+#define SKEIN_T1_BLK_TYPE_PK    SKEIN_T1_BLK_TYPE(PK)   /* pubkey (for sigs) */
+#define SKEIN_T1_BLK_TYPE_KDF   SKEIN_T1_BLK_TYPE(KDF)  /* key ident for KDF */
+#define SKEIN_T1_BLK_TYPE_NONCE SKEIN_T1_BLK_TYPE(NONCE)/* nonce for PRNG */
+#define SKEIN_T1_BLK_TYPE_MSG   SKEIN_T1_BLK_TYPE(MSG)  /* message processing */
+#define SKEIN_T1_BLK_TYPE_OUT   SKEIN_T1_BLK_TYPE(OUT)  /* output stage */
+#define SKEIN_T1_BLK_TYPE_MASK  SKEIN_T1_BLK_TYPE(MASK) /* field bit mask */
+
+#define SKEIN_T1_BLK_TYPE_CFG_FINAL    (SKEIN_T1_BLK_TYPE_CFG | \
+					SKEIN_T1_FLAG_FINAL)
+#define SKEIN_T1_BLK_TYPE_OUT_FINAL    (SKEIN_T1_BLK_TYPE_OUT | \
+					SKEIN_T1_FLAG_FINAL)
+
+#define SKEIN_VERSION           (1)
+
+#ifndef SKEIN_ID_STRING_LE      /* allow compile-time personalization */
+#define SKEIN_ID_STRING_LE      (0x33414853) /* "SHA3" (little-endian)*/
+#endif
+
+#define SKEIN_MK_64(hi32, lo32)  ((lo32) + (((u64) (hi32)) << 32))
+#define SKEIN_SCHEMA_VER        SKEIN_MK_64(SKEIN_VERSION, SKEIN_ID_STRING_LE)
+#define SKEIN_KS_PARITY         SKEIN_MK_64(0x1BD11BDA, 0xA9FC1A22)
+
+#define SKEIN_CFG_STR_LEN       (4*8)
+
+/* bit field definitions in config block tree_info word */
+#define SKEIN_CFG_TREE_LEAF_SIZE_POS  (0)
+#define SKEIN_CFG_TREE_NODE_SIZE_POS  (8)
+#define SKEIN_CFG_TREE_MAX_LEVEL_POS  (16)
+
+#define SKEIN_CFG_TREE_LEAF_SIZE_MSK (((u64)0xFF) << \
+					SKEIN_CFG_TREE_LEAF_SIZE_POS)
+#define SKEIN_CFG_TREE_NODE_SIZE_MSK (((u64)0xFF) << \
+					SKEIN_CFG_TREE_NODE_SIZE_POS)
+#define SKEIN_CFG_TREE_MAX_LEVEL_MSK (((u64)0xFF) << \
+					SKEIN_CFG_TREE_MAX_LEVEL_POS)
+
+#define SKEIN_CFG_TREE_INFO(leaf, node, max_lvl)                   \
+	((((u64)(leaf))   << SKEIN_CFG_TREE_LEAF_SIZE_POS) |    \
+	 (((u64)(node))   << SKEIN_CFG_TREE_NODE_SIZE_POS) |    \
+	 (((u64)(max_lvl)) << SKEIN_CFG_TREE_MAX_LEVEL_POS))
+
+/* use as tree_info in InitExt() call for sequential processing */
+#define SKEIN_CFG_TREE_INFO_SEQUENTIAL SKEIN_CFG_TREE_INFO(0, 0, 0)
+
+/*
+**   Skein macros for getting/setting tweak words, etc.
+**   These are useful for partial input bytes, hash tree init/update, etc.
+**/
+#define skein_get_tweak(ctx_ptr, TWK_NUM)          ((ctx_ptr)->h.tweak[TWK_NUM])
+#define skein_set_tweak(ctx_ptr, TWK_NUM, t_val) { \
+		(ctx_ptr)->h.tweak[TWK_NUM] = (t_val); \
+	}
+
+#define skein_get_T0(ctx_ptr)     skein_get_tweak(ctx_ptr, 0)
+#define skein_get_T1(ctx_ptr)     skein_get_tweak(ctx_ptr, 1)
+#define skein_set_T0(ctx_ptr, T0) skein_set_tweak(ctx_ptr, 0, T0)
+#define skein_set_T1(ctx_ptr, T1) skein_set_tweak(ctx_ptr, 1, T1)
+
+/* set both tweak words at once */
+#define skein_set_T0_T1(ctx_ptr, T0, T1)           \
+	{                                          \
+	skein_set_T0(ctx_ptr, (T0));               \
+	skein_set_T1(ctx_ptr, (T1));               \
+	}
+
+#define skein_set_type(ctx_ptr, BLK_TYPE)         \
+	skein_set_T1(ctx_ptr, SKEIN_T1_BLK_TYPE_##BLK_TYPE)
+
+/*
+ * setup for starting with a new type:
+ * h.tweak[0]=0; h.tweak[1] = NEW_TYPE; h.b_cnt=0;
+ */
+#define skein_start_new_type(ctx_ptr, BLK_TYPE) { \
+		skein_set_T0_T1(ctx_ptr, 0, SKEIN_T1_FLAG_FIRST | \
+				SKEIN_T1_BLK_TYPE_##BLK_TYPE); \
+		(ctx_ptr)->h.b_cnt = 0; \
+	}
+
+#define skein_clear_first_flag(hdr) { \
+		(hdr).tweak[1] &= ~SKEIN_T1_FLAG_FIRST; \
+	}
+#define skein_set_bit_pad_flag(hdr) { \
+		(hdr).tweak[1] |=  SKEIN_T1_FLAG_BIT_PAD; \
+	}
+
+#define skein_set_tree_level(hdr, height) { \
+		(hdr).tweak[1] |= SKEIN_T1_TREE_LEVEL(height); \
+	}
+
+/*****************************************************************
+** "Internal" Skein definitions for debugging and error checking
+******************************************************************/
+#ifdef SKEIN_DEBUG             /* examine/display intermediate values? */
+#include "skein_debug.h"
+#else                           /* default is no callouts */
+#define skein_show_block(bits, ctx, x, blk_ptr, w_ptr, ks_event_ptr, ks_odd_ptr)
+#define skein_show_round(bits, ctx, r, x)
+#define skein_show_r_ptr(bits, ctx, r, x_ptr)
+#define skein_show_final(bits, ctx, cnt, out_ptr)
+#define skein_show_key(bits, ctx, key, key_bytes)
+#endif
+
+/* ignore all asserts, for performance */
+#define skein_assert_ret(x, ret_code)
+#define skein_assert(x)
+
+/*****************************************************************
+** Skein block function constants (shared across Ref and Opt code)
+******************************************************************/
+enum {
+	    /* SKEIN_256 round rotation constants */
+	R_256_0_0 = 14, R_256_0_1 = 16,
+	R_256_1_0 = 52, R_256_1_1 = 57,
+	R_256_2_0 = 23, R_256_2_1 = 40,
+	R_256_3_0 =  5, R_256_3_1 = 37,
+	R_256_4_0 = 25, R_256_4_1 = 33,
+	R_256_5_0 = 46, R_256_5_1 = 12,
+	R_256_6_0 = 58, R_256_6_1 = 22,
+	R_256_7_0 = 32, R_256_7_1 = 32,
+
+	    /* SKEIN_512 round rotation constants */
+	R_512_0_0 = 46, R_512_0_1 = 36, R_512_0_2 = 19, R_512_0_3 = 37,
+	R_512_1_0 = 33, R_512_1_1 = 27, R_512_1_2 = 14, R_512_1_3 = 42,
+	R_512_2_0 = 17, R_512_2_1 = 49, R_512_2_2 = 36, R_512_2_3 = 39,
+	R_512_3_0 = 44, R_512_3_1 =  9, R_512_3_2 = 54, R_512_3_3 = 56,
+	R_512_4_0 = 39, R_512_4_1 = 30, R_512_4_2 = 34, R_512_4_3 = 24,
+	R_512_5_0 = 13, R_512_5_1 = 50, R_512_5_2 = 10, R_512_5_3 = 17,
+	R_512_6_0 = 25, R_512_6_1 = 29, R_512_6_2 = 39, R_512_6_3 = 43,
+	R_512_7_0 =  8, R_512_7_1 = 35, R_512_7_2 = 56, R_512_7_3 = 22,
+
+	    /* SKEIN_1024 round rotation constants */
+	R1024_0_0 = 24, R1024_0_1 = 13, R1024_0_2 =  8, R1024_0_3 = 47,
+	R1024_0_4 =  8, R1024_0_5 = 17, R1024_0_6 = 22, R1024_0_7 = 37,
+	R1024_1_0 = 38, R1024_1_1 = 19, R1024_1_2 = 10, R1024_1_3 = 55,
+	R1024_1_4 = 49, R1024_1_5 = 18, R1024_1_6 = 23, R1024_1_7 = 52,
+	R1024_2_0 = 33, R1024_2_1 =  4, R1024_2_2 = 51, R1024_2_3 = 13,
+	R1024_2_4 = 34, R1024_2_5 = 41, R1024_2_6 = 59, R1024_2_7 = 17,
+	R1024_3_0 =  5, R1024_3_1 = 20, R1024_3_2 = 48, R1024_3_3 = 41,
+	R1024_3_4 = 47, R1024_3_5 = 28, R1024_3_6 = 16, R1024_3_7 = 25,
+	R1024_4_0 = 41, R1024_4_1 =  9, R1024_4_2 = 37, R1024_4_3 = 31,
+	R1024_4_4 = 12, R1024_4_5 = 47, R1024_4_6 = 44, R1024_4_7 = 30,
+	R1024_5_0 = 16, R1024_5_1 = 34, R1024_5_2 = 56, R1024_5_3 = 51,
+	R1024_5_4 =  4, R1024_5_5 = 53, R1024_5_6 = 42, R1024_5_7 = 41,
+	R1024_6_0 = 31, R1024_6_1 = 44, R1024_6_2 = 47, R1024_6_3 = 46,
+	R1024_6_4 = 19, R1024_6_5 = 42, R1024_6_6 = 44, R1024_6_7 = 25,
+	R1024_7_0 =  9, R1024_7_1 = 48, R1024_7_2 = 35, R1024_7_3 = 52,
+	R1024_7_4 = 23, R1024_7_5 = 31, R1024_7_6 = 37, R1024_7_7 = 20
+};
+
+#ifndef SKEIN_ROUNDS
+#define SKEIN_256_ROUNDS_TOTAL (72)	/* # rounds for diff block sizes */
+#define SKEIN_512_ROUNDS_TOTAL (72)
+#define SKEIN_1024_ROUNDS_TOTAL (80)
+#else			/* allow command-line define in range 8*(5..14)   */
+#define SKEIN_256_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS/100) + 5) % 10) + 5))
+#define SKEIN_512_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS/10)  + 5) % 10) + 5))
+#define SKEIN_1024_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS)     + 5) % 10) + 5))
+#endif
+
+#endif  /* ifndef _SKEIN_H_ */
diff --git a/drivers/staging/skein/skein_block.c b/drivers/staging/skein/skein_block.c
index 88bc718..36b0b40 100644
--- a/drivers/staging/skein/skein_block.c
+++ b/drivers/staging/skein/skein_block.c
@@ -15,7 +15,7 @@
 ************************************************************************/
 
 #include <linux/string.h>
-#include "skein.h"
+#include "skein_base.h"
 #include "skein_block.h"
 
 #ifndef SKEIN_USE_ASM
diff --git a/drivers/staging/skein/skein_block.h b/drivers/staging/skein/skein_block.h
index bd7bdc3..9d40f4a 100644
--- a/drivers/staging/skein/skein_block.h
+++ b/drivers/staging/skein/skein_block.h
@@ -10,7 +10,7 @@
 #ifndef _SKEIN_BLOCK_H_
 #define _SKEIN_BLOCK_H_
 
-#include "skein.h" /* get the Skein API definitions   */
+#include "skein_base.h" /* get the Skein API definitions   */
 
 void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr,
 			     size_t blk_cnt, size_t byte_cnt_add);
diff --git a/drivers/staging/skein/skein_generic.c b/drivers/staging/skein/skein_generic.c
new file mode 100644
index 0000000..815f9a4
--- /dev/null
+++ b/drivers/staging/skein/skein_generic.c
@@ -0,0 +1,194 @@
+/*
+ * Cryptographic API.
+ *
+ * Skein256 Hash Algorithm.
+ *
+ * Derived from cryptoapi implementation, adapted for in-place
+ * scatterlist interface.
+ *
+ * Copyright (c) Eric Rost <eric.rost@mybabylon.net>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <crypto/internal/hash.h>
+#include "skein_base.h"
+
+
+static int skein256_init(struct shash_desc *desc)
+{
+	return skein_256_init((struct skein_256_ctx *) shash_desc_ctx(desc),
+			SKEIN256_DIGEST_BIT_SIZE);
+}
+
+int skein256_update(struct shash_desc *desc, const u8 *data,
+			unsigned int len)
+{
+	return skein_256_update((struct skein_256_ctx *) shash_desc_ctx(desc),
+			data, (size_t) len);
+}
+
+/* Add padding and return the message digest. */
+static int skein256_final(struct shash_desc *desc, u8 *out)
+{
+	return skein_256_final((struct skein_256_ctx *) shash_desc_ctx(desc),
+			out);
+}
+
+static int skein256_export(struct shash_desc *desc, void *out)
+{
+	struct skein_256_ctx *sctx = shash_desc_ctx(desc);
+
+	memcpy(out, sctx, sizeof(*sctx));
+	return 0;
+}
+
+static int skein256_import(struct shash_desc *desc, const void *in)
+{
+	struct skein_256_ctx *sctx = shash_desc_ctx(desc);
+
+	memcpy(sctx, in, sizeof(*sctx));
+	return 0;
+}
+
+static int skein512_init(struct shash_desc *desc)
+{
+	return skein_512_init((struct skein_512_ctx *) shash_desc_ctx(desc),
+			SKEIN512_DIGEST_BIT_SIZE);
+}
+
+int skein512_update(struct shash_desc *desc, const u8 *data,
+			unsigned int len)
+{
+	return skein_512_update((struct skein_512_ctx *) shash_desc_ctx(desc),
+			data, (size_t) len);
+}
+
+/* Add padding and return the message digest. */
+static int skein512_final(struct shash_desc *desc, u8 *out)
+{
+	return skein_512_final((struct skein_512_ctx *)
+			shash_desc_ctx(desc), out);
+}
+
+static int skein512_export(struct shash_desc *desc, void *out)
+{
+	struct skein_512_ctx *sctx = shash_desc_ctx(desc);
+
+	memcpy(out, sctx, sizeof(*sctx));
+	return 0;
+}
+
+static int skein512_import(struct shash_desc *desc, const void *in)
+{
+	struct skein_512_ctx *sctx = shash_desc_ctx(desc);
+
+	memcpy(sctx, in, sizeof(*sctx));
+	return 0;
+}
+
+static int skein1024_init(struct shash_desc *desc)
+{
+	return skein_1024_init((struct skein_1024_ctx *) shash_desc_ctx(desc),
+			SKEIN1024_DIGEST_BIT_SIZE);
+}
+
+int skein1024_update(struct shash_desc *desc, const u8 *data,
+			unsigned int len)
+{
+	return skein_1024_update((struct skein_1024_ctx *) shash_desc_ctx(desc),
+			data, (size_t) len);
+}
+
+/* Add padding and return the message digest. */
+static int skein1024_final(struct shash_desc *desc, u8 *out)
+{
+	return skein_1024_final((struct skein_1024_ctx *) shash_desc_ctx(desc),
+			out);
+}
+
+static int skein1024_export(struct shash_desc *desc, void *out)
+{
+	struct skein_1024_ctx *sctx = shash_desc_ctx(desc);
+
+	memcpy(out, sctx, sizeof(*sctx));
+	return 0;
+}
+
+static int skein1024_import(struct shash_desc *desc, const void *in)
+{
+	struct skein_1024_ctx *sctx = shash_desc_ctx(desc);
+
+	memcpy(sctx, in, sizeof(*sctx));
+	return 0;
+}
+
+static struct shash_alg alg256 = {
+	.digestsize	=	(SKEIN256_DIGEST_BIT_SIZE / 8),
+	.init		=	skein256_init,
+	.update		=	skein256_update,
+	.final		=	skein256_final,
+	.export		=	skein256_export,
+	.import		=	skein256_import,
+	.descsize	=	sizeof(struct skein_256_ctx),
+	.statesize	=	sizeof(struct skein_256_ctx),
+	.base		=	{
+		.cra_name		=	"skein256",
+		.cra_driver_name	=	"skein",
+		.cra_flags		=	CRYPTO_ALG_TYPE_SHASH,
+		.cra_blocksize		=	SKEIN_256_BLOCK_BYTES,
+	}
+};
+
+static struct shash_alg alg512 = {
+	.digestsize	=	(SKEIN512_DIGEST_BIT_SIZE / 8),
+	.init		=	skein512_init,
+	.update		=	skein512_update,
+	.final		=	skein512_final,
+	.export		=	skein512_export,
+	.import		=	skein512_import,
+	.descsize	=	sizeof(struct skein_512_ctx),
+	.statesize	=	sizeof(struct skein_512_ctx),
+	.base		=	{
+		.cra_name		=	"skein512",
+		.cra_driver_name	=	"skein",
+		.cra_flags		=	CRYPTO_ALG_TYPE_SHASH,
+		.cra_blocksize		=	SKEIN_512_BLOCK_BYTES,
+	}
+};
+
+static struct shash_alg alg1024 = {
+	.digestsize	=	(SKEIN1024_DIGEST_BIT_SIZE / 8),
+	.init		=	skein1024_init,
+	.update		=	skein1024_update,
+	.final		=	skein1024_final,
+	.export		=	skein1024_export,
+	.import		=	skein1024_import,
+	.descsize	=	sizeof(struct skein_1024_ctx),
+	.statesize	=	sizeof(struct skein_1024_ctx),
+	.base		=	{
+		.cra_name		=	"skein1024",
+		.cra_driver_name	=	"skein",
+		.cra_flags		=	CRYPTO_ALG_TYPE_SHASH,
+		.cra_blocksize		=	SKEIN_1024_BLOCK_BYTES,
+	}
+};
+
+static int __init skein_generic_init(void)
+{
+	if (crypto_register_shash(&alg256) || crypto_register_shash(&alg512)
+		|| crypto_register_shash(&alg1024)) {
+		crypto_unregister_shash(&alg256);
+		crypto_unregister_shash(&alg512);
+		crypto_unregister_shash(&alg1024);
+		return -1;
+	}
+	return 0;
+}
+
+device_initcall(skein_generic_init);
diff --git a/drivers/staging/skein/skein_iv.h b/drivers/staging/skein/skein_iv.h
index d9dc1d5..8a06314 100644
--- a/drivers/staging/skein/skein_iv.h
+++ b/drivers/staging/skein/skein_iv.h
@@ -1,7 +1,7 @@
 #ifndef _SKEIN_IV_H_
 #define _SKEIN_IV_H_
 
-#include "skein.h"    /* get Skein macros and types */
+#include "skein_base.h"    /* get Skein macros and types */
 
 /*
 ***************** Pre-computed Skein IVs *******************
diff --git a/drivers/staging/skein/threefish_api.h b/drivers/staging/skein/threefish_api.h
index 8d5ddf8..8e0a0b7 100644
--- a/drivers/staging/skein/threefish_api.h
+++ b/drivers/staging/skein/threefish_api.h
@@ -29,7 +29,7 @@
  */
 
 #include <linux/types.h>
-#include "skein.h"
+#include "skein_base.h"
 
 #define KEY_SCHEDULE_CONST 0x1BD11BDAA9FC1A22L
 
-- 
2.1.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v3 2/2] staging: skein: Adds Loadable Module Support
  2014-10-23 22:11 [PATCH v3 0/2] staging: skein: Adds CryptoAPI and Module Support Eric Rost
  2014-10-23 22:12 ` [PATCH v3 1/2] staging: skein: Adds CryptoAPI Support Eric Rost
@ 2014-10-23 22:12 ` Eric Rost
  1 sibling, 0 replies; 4+ messages in thread
From: Eric Rost @ 2014-10-23 22:12 UTC (permalink / raw)
  To: gregkh, jason, jake, antonysaraev; +Cc: devel, linux-kernel

Adds loadable module support for the Skein Hashing Algorithm.

Signed-off-by: Eric Rost <eric.rost@mybabylon.net>
---
 drivers/staging/skein/Kconfig         |  2 +-
 drivers/staging/skein/skein_generic.c | 19 ++++++++++++++++++-
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/skein/Kconfig b/drivers/staging/skein/Kconfig
index de8bdd7..012a823 100644
--- a/drivers/staging/skein/Kconfig
+++ b/drivers/staging/skein/Kconfig
@@ -1,5 +1,5 @@
 config CRYPTO_SKEIN
-	bool "Skein digest algorithm"
+	tristate "Skein digest algorithm"
 	depends on (X86 || UML_X86) && 64BIT && CRYPTO
 	select CRYPTO_HASH
 	select CRYPTO_ALGAPI
diff --git a/drivers/staging/skein/skein_generic.c b/drivers/staging/skein/skein_generic.c
index 815f9a4..3c9c6d0 100644
--- a/drivers/staging/skein/skein_generic.c
+++ b/drivers/staging/skein/skein_generic.c
@@ -16,6 +16,7 @@
  */
 #include <linux/types.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <crypto/internal/hash.h>
 #include "skein_base.h"
 
@@ -142,6 +143,7 @@ static struct shash_alg alg256 = {
 		.cra_driver_name	=	"skein",
 		.cra_flags		=	CRYPTO_ALG_TYPE_SHASH,
 		.cra_blocksize		=	SKEIN_256_BLOCK_BYTES,
+		.cra_module		=	THIS_MODULE,
 	}
 };
 
@@ -159,6 +161,7 @@ static struct shash_alg alg512 = {
 		.cra_driver_name	=	"skein",
 		.cra_flags		=	CRYPTO_ALG_TYPE_SHASH,
 		.cra_blocksize		=	SKEIN_512_BLOCK_BYTES,
+		.cra_module		=	THIS_MODULE,
 	}
 };
 
@@ -176,6 +179,7 @@ static struct shash_alg alg1024 = {
 		.cra_driver_name	=	"skein",
 		.cra_flags		=	CRYPTO_ALG_TYPE_SHASH,
 		.cra_blocksize		=	SKEIN_1024_BLOCK_BYTES,
+		.cra_module		=	THIS_MODULE,
 	}
 };
 
@@ -191,4 +195,17 @@ static int __init skein_generic_init(void)
 	return 0;
 }
 
-device_initcall(skein_generic_init);
+static void __exit skein_generic_fini(void)
+{
+	crypto_unregister_shash(&alg256);
+	crypto_unregister_shash(&alg512);
+	crypto_unregister_shash(&alg1024);
+}
+
+module_init(skein_generic_init);
+module_exit(skein_generic_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Skein Hash Algorithm");
+
+MODULE_ALIAS("skein");
-- 
2.1.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v3 1/2] staging: skein: Adds CryptoAPI Support
  2014-10-23 22:12 ` [PATCH v3 1/2] staging: skein: Adds CryptoAPI Support Eric Rost
@ 2014-10-24  4:51   ` Dan Carpenter
  0 siblings, 0 replies; 4+ messages in thread
From: Dan Carpenter @ 2014-10-24  4:51 UTC (permalink / raw)
  To: Eric Rost; +Cc: gregkh, jason, jake, antonysaraev, devel, linux-kernel

First of all this patch does too many things at once.  Collapsing files
and deleting them needs to be done in separate patches from adding them.
There is the "one thing per patch" and each one of those is a separate
thing.

On Thu, Oct 23, 2014 at 05:12:10PM -0500, Eric Rost wrote:
> +int skein256_update(struct shash_desc *desc, const u8 *data,
> +			unsigned int len)
> +{
> +	return skein_256_update((struct skein_256_ctx *) shash_desc_ctx(desc),
> +			data, (size_t) len);
> +}

The two line version of this cast was prettier.  Also if you run
checkpatch.pl --strict over this it will hopefully warn about the
space in the middle of the cast and the alignment of data.  Also the
cast to size_t is superflous.

The checkpatch --strict version of this looks like:

int skein256_update(struct shash_desc *desc, const u8 *data,
			unsigned int len)
{
	return skein_256_update((struct skein_256_ctx *)shash_desc_ctx(desc),
				data, len);
}

Eventually, I feel like we would wave skein_256_update() to just take
a shash_desc pointer?  We'd have to shuffle the skein_ctx struct a bit
to make that work.  (I haven't looked at this carefully).

regards,
dan carpenter


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-10-24  4:52 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-10-23 22:11 [PATCH v3 0/2] staging: skein: Adds CryptoAPI and Module Support Eric Rost
2014-10-23 22:12 ` [PATCH v3 1/2] staging: skein: Adds CryptoAPI Support Eric Rost
2014-10-24  4:51   ` Dan Carpenter
2014-10-23 22:12 ` [PATCH v3 2/2] staging: skein: Adds Loadable Module Support Eric Rost

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox