Changeset View
Changeset View
Standalone View
Standalone View
sys/crypto/skein/skein_block.c
/*********************************************************************** | /*********************************************************************** | ||||
** | ** | ||||
** Implementation of the Skein block functions. | ** Implementation of the Skein block functions. | ||||
** | ** | ||||
** Source code author: Doug Whiting, 2008. | ** Source code author: Doug Whiting, 2008. | ||||
** | ** | ||||
** This algorithm and source code is released to the public domain. | ** This algorithm and source code is released to the public domain. | ||||
** | ** | ||||
** Compile-time switches: | ** Compile-time switches: | ||||
** | ** | ||||
** SKEIN_USE_ASM -- set bits (256/512/1024) to select which | ** SKEIN_USE_ASM -- set bits (256/512/1024) to select which | ||||
** versions use ASM code for block processing | ** versions use ASM code for block processing | ||||
** [default: use C for all block sizes] | ** [default: use C for all block sizes] | ||||
** | ** | ||||
************************************************************************/ | ************************************************************************/ | ||||
#include <sys/cdefs.h> | |||||
__FBSDID("$FreeBSD$"); | |||||
#include <sys/endian.h> | |||||
#include <sys/types.h> | |||||
#ifdef _KERNEL | |||||
#include <sys/systm.h> | |||||
#else | |||||
#include <string.h> | #include <string.h> | ||||
#endif | |||||
#include "skein.h" | #include "skein.h" | ||||
#ifndef SKEIN_USE_ASM | #ifndef SKEIN_USE_ASM | ||||
#define SKEIN_USE_ASM (0) /* default is all C code (no ASM) */ | #define SKEIN_USE_ASM (0) /* default is all C code (no ASM) */ | ||||
#endif | #endif | ||||
#ifndef SKEIN_LOOP | #ifndef SKEIN_LOOP | ||||
#define SKEIN_LOOP 001 /* default: unroll 256 and 512, but not 1024 */ | #define SKEIN_LOOP 001 /* default: unroll 256 and 512, but not 1024 */ | ||||
#endif | #endif | ||||
#define BLK_BITS (WCNT*64) /* some useful definitions for code here */ | #define BLK_BITS (WCNT*64) /* some useful definitions for code here */ | ||||
#define KW_TWK_BASE (0) | #define KW_TWK_BASE (0) | ||||
#define KW_KEY_BASE (3) | #define KW_KEY_BASE (3) | ||||
#define ks (kw + KW_KEY_BASE) | #define ks (kw + KW_KEY_BASE) | ||||
#define ts (kw + KW_TWK_BASE) | #define ts (kw + KW_TWK_BASE) | ||||
#ifdef SKEIN_DEBUG | #ifdef SKEIN_DEBUG | ||||
#define DebugSaveTweak(ctx) { ctx->h.T[0] = ts[0]; ctx->h.T[1] = ts[1]; } | #define DebugSaveTweak(ctx) { ctx->h.T[0] = ts[0]; ctx->h.T[1] = ts[1]; } | ||||
#else | #else | ||||
#define DebugSaveTweak(ctx) | #define DebugSaveTweak(ctx) | ||||
#endif | #endif | ||||
/*****************************************************************/ | |||||
/* functions to process blkCnt (nonzero) full block(s) of data. */ | |||||
void Skein_256_Process_Block(Skein_256_Ctxt_t *ctx, const u_int8_t *blkPtr, | |||||
size_t blkCnt, size_t byteCntAdd); | |||||
void Skein_512_Process_Block(Skein_512_Ctxt_t *ctx, const u_int8_t *blkPtr, | |||||
size_t blkCnt, size_t byteCntAdd); | |||||
void Skein1024_Process_Block(Skein1024_Ctxt_t *ctx, const u_int8_t *blkPtr, | |||||
size_t blkCnt, size_t byteCntAdd); | |||||
/***************************** Skein_256 ******************************/ | /***************************** Skein_256 ******************************/ | ||||
#if !(SKEIN_USE_ASM & 256) | #if !(SKEIN_USE_ASM & 256) | ||||
void Skein_256_Process_Block(Skein_256_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd) | void Skein_256_Process_Block(Skein_256_Ctxt_t *ctx, const u_int8_t *blkPtr, size_t blkCnt, size_t byteCntAdd) | ||||
{ /* do it in C */ | { /* do it in C */ | ||||
enum | enum | ||||
{ | { | ||||
WCNT = SKEIN_256_STATE_WORDS | WCNT = SKEIN_256_STATE_WORDS | ||||
}; | }; | ||||
#undef RCNT | #undef RCNT | ||||
#define RCNT (SKEIN_256_ROUNDS_TOTAL/8) | #define RCNT (SKEIN_256_ROUNDS_TOTAL/8) | ||||
#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ | #ifdef SKEIN_LOOP /* configure how much to unroll the loop */ | ||||
#define SKEIN_UNROLL_256 (((SKEIN_LOOP)/100)%10) | #define SKEIN_UNROLL_256 (((SKEIN_LOOP)/100)%10) | ||||
#else | #else | ||||
#define SKEIN_UNROLL_256 (0) | #define SKEIN_UNROLL_256 (0) | ||||
#endif | #endif | ||||
#if SKEIN_UNROLL_256 | #if SKEIN_UNROLL_256 | ||||
#if (RCNT % SKEIN_UNROLL_256) | #if (RCNT % SKEIN_UNROLL_256) | ||||
#error "Invalid SKEIN_UNROLL_256" /* sanity check on unroll count */ | #error "Invalid SKEIN_UNROLL_256" /* sanity check on unroll count */ | ||||
#endif | #endif | ||||
size_t r; | size_t r; | ||||
u64b_t kw[WCNT+4+RCNT*2]; /* key schedule words : chaining vars + tweak + "rotation"*/ | u_int64_t kw[WCNT+4+RCNT*2]; /* key schedule words : chaining vars + tweak + "rotation"*/ | ||||
#else | #else | ||||
u64b_t kw[WCNT+4]; /* key schedule words : chaining vars + tweak */ | u_int64_t kw[WCNT+4]; /* key schedule words : chaining vars + tweak */ | ||||
#endif | #endif | ||||
u64b_t X0,X1,X2,X3; /* local copy of context vars, for speed */ | u_int64_t X0,X1,X2,X3; /* local copy of context vars, for speed */ | ||||
u64b_t w [WCNT]; /* local copy of input block */ | u_int64_t w [WCNT]; /* local copy of input block */ | ||||
#ifdef SKEIN_DEBUG | #ifdef SKEIN_DEBUG | ||||
const u64b_t *Xptr[4]; /* use for debugging (help compiler put Xn in registers) */ | const u_int64_t *Xptr[4]; /* use for debugging (help compiler put Xn in registers) */ | ||||
Xptr[0] = &X0; Xptr[1] = &X1; Xptr[2] = &X2; Xptr[3] = &X3; | Xptr[0] = &X0; Xptr[1] = &X1; Xptr[2] = &X2; Xptr[3] = &X3; | ||||
#endif | #endif | ||||
Skein_assert(blkCnt != 0); /* never call with blkCnt == 0! */ | Skein_assert(blkCnt != 0); /* never call with blkCnt == 0! */ | ||||
ts[0] = ctx->h.T[0]; | ts[0] = ctx->h.T[0]; | ||||
ts[1] = ctx->h.T[1]; | ts[1] = ctx->h.T[1]; | ||||
do { | do { | ||||
/* this implementation only supports 2**64 input bytes (no carry out here) */ | /* this implementation only supports 2**64 input bytes (no carry out here) */ | ||||
ts[0] += byteCntAdd; /* update processed length */ | ts[0] += byteCntAdd; /* update processed length */ | ||||
▲ Show 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | #endif | ||||
while (--blkCnt); | while (--blkCnt); | ||||
ctx->h.T[0] = ts[0]; | ctx->h.T[0] = ts[0]; | ||||
ctx->h.T[1] = ts[1]; | ctx->h.T[1] = ts[1]; | ||||
} | } | ||||
#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF) | #if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF) | ||||
size_t Skein_256_Process_Block_CodeSize(void) | size_t Skein_256_Process_Block_CodeSize(void) | ||||
{ | { | ||||
return ((u08b_t *) Skein_256_Process_Block_CodeSize) - | return ((u_int8_t *) Skein_256_Process_Block_CodeSize) - | ||||
((u08b_t *) Skein_256_Process_Block); | ((u_int8_t *) Skein_256_Process_Block); | ||||
} | } | ||||
uint_t Skein_256_Unroll_Cnt(void) | u_int Skein_256_Unroll_Cnt(void) | ||||
{ | { | ||||
return SKEIN_UNROLL_256; | return SKEIN_UNROLL_256; | ||||
} | } | ||||
#endif | #endif | ||||
#endif | #endif | ||||
/***************************** Skein_512 ******************************/ | /***************************** Skein_512 ******************************/ | ||||
#if !(SKEIN_USE_ASM & 512) | #if !(SKEIN_USE_ASM & 512) | ||||
void Skein_512_Process_Block(Skein_512_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd) | void Skein_512_Process_Block(Skein_512_Ctxt_t *ctx,const u_int8_t *blkPtr,size_t blkCnt,size_t byteCntAdd) | ||||
{ /* do it in C */ | { /* do it in C */ | ||||
enum | enum | ||||
{ | { | ||||
WCNT = SKEIN_512_STATE_WORDS | WCNT = SKEIN_512_STATE_WORDS | ||||
}; | }; | ||||
#undef RCNT | #undef RCNT | ||||
#define RCNT (SKEIN_512_ROUNDS_TOTAL/8) | #define RCNT (SKEIN_512_ROUNDS_TOTAL/8) | ||||
#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ | #ifdef SKEIN_LOOP /* configure how much to unroll the loop */ | ||||
#define SKEIN_UNROLL_512 (((SKEIN_LOOP)/10)%10) | #define SKEIN_UNROLL_512 (((SKEIN_LOOP)/10)%10) | ||||
#else | #else | ||||
#define SKEIN_UNROLL_512 (0) | #define SKEIN_UNROLL_512 (0) | ||||
#endif | #endif | ||||
#if SKEIN_UNROLL_512 | #if SKEIN_UNROLL_512 | ||||
#if (RCNT % SKEIN_UNROLL_512) | #if (RCNT % SKEIN_UNROLL_512) | ||||
#error "Invalid SKEIN_UNROLL_512" /* sanity check on unroll count */ | #error "Invalid SKEIN_UNROLL_512" /* sanity check on unroll count */ | ||||
#endif | #endif | ||||
size_t r; | size_t r; | ||||
u64b_t kw[WCNT+4+RCNT*2]; /* key schedule words : chaining vars + tweak + "rotation"*/ | u_int64_t kw[WCNT+4+RCNT*2]; /* key schedule words : chaining vars + tweak + "rotation"*/ | ||||
#else | #else | ||||
u64b_t kw[WCNT+4]; /* key schedule words : chaining vars + tweak */ | u_int64_t kw[WCNT+4]; /* key schedule words : chaining vars + tweak */ | ||||
#endif | #endif | ||||
u64b_t X0,X1,X2,X3,X4,X5,X6,X7; /* local copy of vars, for speed */ | u_int64_t X0,X1,X2,X3,X4,X5,X6,X7; /* local copy of vars, for speed */ | ||||
u64b_t w [WCNT]; /* local copy of input block */ | u_int64_t w [WCNT]; /* local copy of input block */ | ||||
#ifdef SKEIN_DEBUG | #ifdef SKEIN_DEBUG | ||||
const u64b_t *Xptr[8]; /* use for debugging (help compiler put Xn in registers) */ | const u_int64_t *Xptr[8]; /* use for debugging (help compiler put Xn in registers) */ | ||||
Xptr[0] = &X0; Xptr[1] = &X1; Xptr[2] = &X2; Xptr[3] = &X3; | Xptr[0] = &X0; Xptr[1] = &X1; Xptr[2] = &X2; Xptr[3] = &X3; | ||||
Xptr[4] = &X4; Xptr[5] = &X5; Xptr[6] = &X6; Xptr[7] = &X7; | Xptr[4] = &X4; Xptr[5] = &X5; Xptr[6] = &X6; Xptr[7] = &X7; | ||||
#endif | #endif | ||||
Skein_assert(blkCnt != 0); /* never call with blkCnt == 0! */ | Skein_assert(blkCnt != 0); /* never call with blkCnt == 0! */ | ||||
ts[0] = ctx->h.T[0]; | ts[0] = ctx->h.T[0]; | ||||
ts[1] = ctx->h.T[1]; | ts[1] = ctx->h.T[1]; | ||||
do { | do { | ||||
▲ Show 20 Lines • Show All 152 Lines • ▼ Show 20 Lines | #endif | ||||
while (--blkCnt); | while (--blkCnt); | ||||
ctx->h.T[0] = ts[0]; | ctx->h.T[0] = ts[0]; | ||||
ctx->h.T[1] = ts[1]; | ctx->h.T[1] = ts[1]; | ||||
} | } | ||||
#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF) | #if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF) | ||||
size_t Skein_512_Process_Block_CodeSize(void) | size_t Skein_512_Process_Block_CodeSize(void) | ||||
{ | { | ||||
return ((u08b_t *) Skein_512_Process_Block_CodeSize) - | return ((u_int8_t *) Skein_512_Process_Block_CodeSize) - | ||||
((u08b_t *) Skein_512_Process_Block); | ((u_int8_t *) Skein_512_Process_Block); | ||||
} | } | ||||
uint_t Skein_512_Unroll_Cnt(void) | u_int Skein_512_Unroll_Cnt(void) | ||||
{ | { | ||||
return SKEIN_UNROLL_512; | return SKEIN_UNROLL_512; | ||||
} | } | ||||
#endif | #endif | ||||
#endif | #endif | ||||
/***************************** Skein1024 ******************************/ | /***************************** Skein1024 ******************************/ | ||||
#if !(SKEIN_USE_ASM & 1024) | #if !(SKEIN_USE_ASM & 1024) | ||||
void Skein1024_Process_Block(Skein1024_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd) | void Skein1024_Process_Block(Skein1024_Ctxt_t *ctx,const u_int8_t *blkPtr,size_t blkCnt,size_t byteCntAdd) | ||||
{ /* do it in C, always looping (unrolled is bigger AND slower!) */ | { /* do it in C, always looping (unrolled is bigger AND slower!) */ | ||||
enum | enum | ||||
{ | { | ||||
WCNT = SKEIN1024_STATE_WORDS | WCNT = SKEIN1024_STATE_WORDS | ||||
}; | }; | ||||
#undef RCNT | #undef RCNT | ||||
#define RCNT (SKEIN1024_ROUNDS_TOTAL/8) | #define RCNT (SKEIN1024_ROUNDS_TOTAL/8) | ||||
#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ | #ifdef SKEIN_LOOP /* configure how much to unroll the loop */ | ||||
#define SKEIN_UNROLL_1024 ((SKEIN_LOOP)%10) | #define SKEIN_UNROLL_1024 ((SKEIN_LOOP)%10) | ||||
#else | #else | ||||
#define SKEIN_UNROLL_1024 (0) | #define SKEIN_UNROLL_1024 (0) | ||||
#endif | #endif | ||||
#if (SKEIN_UNROLL_1024 != 0) | #if (SKEIN_UNROLL_1024 != 0) | ||||
#if (RCNT % SKEIN_UNROLL_1024) | #if (RCNT % SKEIN_UNROLL_1024) | ||||
#error "Invalid SKEIN_UNROLL_1024" /* sanity check on unroll count */ | #error "Invalid SKEIN_UNROLL_1024" /* sanity check on unroll count */ | ||||
#endif | #endif | ||||
size_t r; | size_t r; | ||||
u64b_t kw[WCNT+4+RCNT*2]; /* key schedule words : chaining vars + tweak + "rotation"*/ | u_int64_t kw[WCNT+4+RCNT*2]; /* key schedule words : chaining vars + tweak + "rotation"*/ | ||||
#else | #else | ||||
u64b_t kw[WCNT+4]; /* key schedule words : chaining vars + tweak */ | u_int64_t kw[WCNT+4]; /* key schedule words : chaining vars + tweak */ | ||||
#endif | #endif | ||||
u64b_t X00,X01,X02,X03,X04,X05,X06,X07, /* local copy of vars, for speed */ | u_int64_t X00,X01,X02,X03,X04,X05,X06,X07, /* local copy of vars, for speed */ | ||||
X08,X09,X10,X11,X12,X13,X14,X15; | X08,X09,X10,X11,X12,X13,X14,X15; | ||||
u64b_t w [WCNT]; /* local copy of input block */ | u_int64_t w [WCNT]; /* local copy of input block */ | ||||
#ifdef SKEIN_DEBUG | #ifdef SKEIN_DEBUG | ||||
const u64b_t *Xptr[16]; /* use for debugging (help compiler put Xn in registers) */ | const u_int64_t *Xptr[16]; /* use for debugging (help compiler put Xn in registers) */ | ||||
Xptr[ 0] = &X00; Xptr[ 1] = &X01; Xptr[ 2] = &X02; Xptr[ 3] = &X03; | Xptr[ 0] = &X00; Xptr[ 1] = &X01; Xptr[ 2] = &X02; Xptr[ 3] = &X03; | ||||
Xptr[ 4] = &X04; Xptr[ 5] = &X05; Xptr[ 6] = &X06; Xptr[ 7] = &X07; | Xptr[ 4] = &X04; Xptr[ 5] = &X05; Xptr[ 6] = &X06; Xptr[ 7] = &X07; | ||||
Xptr[ 8] = &X08; Xptr[ 9] = &X09; Xptr[10] = &X10; Xptr[11] = &X11; | Xptr[ 8] = &X08; Xptr[ 9] = &X09; Xptr[10] = &X10; Xptr[11] = &X11; | ||||
Xptr[12] = &X12; Xptr[13] = &X13; Xptr[14] = &X14; Xptr[15] = &X15; | Xptr[12] = &X12; Xptr[13] = &X13; Xptr[14] = &X14; Xptr[15] = &X15; | ||||
#endif | #endif | ||||
Skein_assert(blkCnt != 0); /* never call with blkCnt == 0! */ | Skein_assert(blkCnt != 0); /* never call with blkCnt == 0! */ | ||||
ts[0] = ctx->h.T[0]; | ts[0] = ctx->h.T[0]; | ||||
▲ Show 20 Lines • Show All 200 Lines • ▼ Show 20 Lines | #endif | ||||
while (--blkCnt); | while (--blkCnt); | ||||
ctx->h.T[0] = ts[0]; | ctx->h.T[0] = ts[0]; | ||||
ctx->h.T[1] = ts[1]; | ctx->h.T[1] = ts[1]; | ||||
} | } | ||||
#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF) | #if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF) | ||||
size_t Skein1024_Process_Block_CodeSize(void) | size_t Skein1024_Process_Block_CodeSize(void) | ||||
{ | { | ||||
return ((u08b_t *) Skein1024_Process_Block_CodeSize) - | return ((u_int8_t *) Skein1024_Process_Block_CodeSize) - | ||||
((u08b_t *) Skein1024_Process_Block); | ((u_int8_t *) Skein1024_Process_Block); | ||||
} | } | ||||
uint_t Skein1024_Unroll_Cnt(void) | u_int Skein1024_Unroll_Cnt(void) | ||||
{ | { | ||||
return SKEIN_UNROLL_1024; | return SKEIN_UNROLL_1024; | ||||
} | } | ||||
#endif | #endif | ||||
#endif | #endif |