Commit 449bb812 authored by Jason Cooper's avatar Jason Cooper Committed by Greg Kroah-Hartman

staging: crypto: skein: import code from Skein3Fish.git

This is a byte-for-byte copy of the skein implementation found at:

  https://github.com/wernerd/Skein3Fish.git

Specifically, from the master branch at commit:

  00e925444c2c Merge pull request #4 from csm/master

The next commit will do the minimum necessary to build this code as a
module.

I've generated the sha256 sums of the files by:

$ (cd drivers/staging/skein; find . -type f | sort | xargs sha256sum)
bcd73168e5805b1b157dbf08863e6a8c217a7b270b6be1a361540591b00624e3  ./CMakeLists.txt
e1adb97dd9e87bc7c05892ed7863a66d1d9fde6728a97a8b7b092709da664d29  ./include/brg_endian.h
240329b4ca4d829ac4d1490e96e83118e161e719e448c7e8dbf15735ab8a8e87  ./include/brg_types.h
0d8f16438f641fa365844a5991220eb04969f0a19c60dff08e10f521e74db5c3  ./include/skein.h
8f7362796e9e43f7619d51020d6faeedce786492b65bebd2ff6a833b621051cb  ./include/skeinApi.h
90510d8a9f686c3bfbf6cf7737237e3fa263c1ed5046b0f19727ba55b9bffeb9  ./include/skein_iv.h
42c6c8eff8f364ee2f0de3177d468dbceba9c6a73222fea473fe6d603213806a  ./include/skein_port.h
0154a4b8d54f5aa424b39a7ee668b31f2522b907bf3a8536fe46440b584531a1  ./include/threefishApi.h
ac0fc0f95a48a716d30cf02e5adad77af17725a938f939cf94f6dfba42badeca  ./skein.c
7af70b177bc63690f68eebceca2dbfef8a4473dcc847ae3525508c65c7d7bcc1  ./skeinApi.c
d7ef7330be8253f7f061de3c36880dbc83b0f5d90c8f2b72d3478766f54fbff0  ./skeinBlockNo3F.c
8bb3d7864afc9eab5569949fb2799cb6f14e583ba00641313cf877a5aea1c763  ./skein_block.c
438e6cb59a0090166e8f1e39418c0a2d0036737a32c5e2822c2ed8b803e2132f  ./threefish1024Block.c
e812ec6f2881300e90c803cfd9d044e954f1ca64faa2fc17a709f56a2f122ff8  ./threefish256Block.c
926f680057e128cdd1feba4a8544c177a74420137af480267b949ae79f3d02b8  ./threefish512Block.c
19357f5d47e7183bc8558a8d0949a3f5a80a931848917d26f36eebb7d205f003  ./threefishApi.c
Signed-off-by: default avatarJason Cooper <jason@lakedaemon.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 5565c59e
cmake_minimum_required (VERSION 2.6)
include_directories (${CMAKE_CURRENT_SOURCE_DIR}/include)
# set(skeinBlock_src skein_block.c)
set(skeinBlock_src skeinBlockNo3F.c)
set(skein_src
${skeinBlock_src}
skein.c
skeinApi.c
)
set(threefish_src
threefishApi.c
threefish256Block.c
threefish512Block.c
threefish1024Block.c
)
set(s3f_src ${skein_src} ${threefish_src})
add_library(skein3fish SHARED ${s3f_src})
set_target_properties(skein3fish PROPERTIES VERSION ${VERSION} SOVERSION ${SOVERSION})
target_link_libraries(skein3fish ${LIBS})
install(TARGETS skein3fish DESTINATION ${LIBDIRNAME})
/*
---------------------------------------------------------------------------
Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved.
LICENSE TERMS
The free distribution and use of this software in both source and binary
form is allowed (with or without changes) provided that:
1. distributions of this source code include the above copyright
notice, this list of conditions and the following disclaimer;
2. distributions in binary form include the above copyright
notice, this list of conditions and the following disclaimer
in the documentation and/or other associated materials;
3. the copyright holder's name is not used to endorse products
built using this software without specific written permission.
ALTERNATIVELY, provided that this notice is retained in full, this product
may be distributed under the terms of the GNU General Public License (GPL),
in which case the provisions of the GPL apply INSTEAD OF those given above.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue 20/10/2006
*/
#ifndef BRG_ENDIAN_H
#define BRG_ENDIAN_H
#define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
/* Include files where endian defines and byteswap functions may reside */
#if defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )
# include <sys/endian.h>
#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \
defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ )
# include <machine/endian.h>
#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
# if !defined( __MINGW32__ ) && !defined(AVR)
# include <endian.h>
# if !defined( __BEOS__ )
# include <byteswap.h>
# endif
# endif
#endif
/* Now attempt to set the define for platform byte order using any */
/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */
/* seem to encompass most endian symbol definitions */
#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN )
# if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
# elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
# endif
#elif defined( BIG_ENDIAN )
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#elif defined( LITTLE_ENDIAN )
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#endif
#if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN )
# if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
# elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
# endif
#elif defined( _BIG_ENDIAN )
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#elif defined( _LITTLE_ENDIAN )
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#endif
#if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN )
# if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
# elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
# endif
#elif defined( __BIG_ENDIAN )
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#elif defined( __LITTLE_ENDIAN )
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#endif
#if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ )
# if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
# elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
# endif
#elif defined( __BIG_ENDIAN__ )
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#elif defined( __LITTLE_ENDIAN__ )
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#endif
/* if the platform byte order could not be determined, then try to */
/* set this define using common machine defines */
#if !defined(PLATFORM_BYTE_ORDER)
#if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \
defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \
defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \
defined( vax ) || defined( vms ) || defined( VMS ) || \
defined( __VMS ) || defined( _M_X64 ) || defined( AVR )
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \
defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \
defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \
defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \
defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \
defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \
defined( THINK_C ) || defined( __VMCMS__ )
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#elif 0 /* **** EDIT HERE IF NECESSARY **** */
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#elif 0 /* **** EDIT HERE IF NECESSARY **** */
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#else
# error Please edit lines 126 or 128 in brg_endian.h to set the platform byte order
#endif
#endif
/* special handler for IA64, which may be either endianness (?) */
/* here we assume little-endian, but this may need to be changed */
#if defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
# define PLATFORM_MUST_ALIGN (1)
#ifndef PLATFORM_BYTE_ORDER
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#endif
#endif
#ifndef PLATFORM_MUST_ALIGN
# define PLATFORM_MUST_ALIGN (0)
#endif
#endif /* ifndef BRG_ENDIAN_H */
/*
---------------------------------------------------------------------------
Copyright (c) 1998-2006, Brian Gladman, Worcester, UK. All rights reserved.
LICENSE TERMS
The free distribution and use of this software in both source and binary
form is allowed (with or without changes) provided that:
1. distributions of this source code include the above copyright
notice, this list of conditions and the following disclaimer;
2. distributions in binary form include the above copyright
notice, this list of conditions and the following disclaimer
in the documentation and/or other associated materials;
3. the copyright holder's name is not used to endorse products
built using this software without specific written permission.
ALTERNATIVELY, provided that this notice is retained in full, this product
may be distributed under the terms of the GNU General Public License (GPL),
in which case the provisions of the GPL apply INSTEAD OF those given above.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue 09/09/2006
The unsigned integer types defined here are of the form uint_<nn>t where
<nn> is the length of the type; for example, the unsigned 32-bit type is
'uint_32t'. These are NOT the same as the 'C99 integer types' that are
defined in the inttypes.h and stdint.h headers since attempts to use these
types have shown that support for them is still highly variable. However,
since the latter are of the form uint<nn>_t, a regular expression search
and replace (in VC++ search on 'uint_{:z}t' and replace with 'uint\1_t')
can be used to convert the types used here to the C99 standard types.
*/
#ifndef BRG_TYPES_H
#define BRG_TYPES_H
#if defined(__cplusplus)
extern "C" {
#endif
#include <limits.h>
#ifndef BRG_UI8
# define BRG_UI8
# if UCHAR_MAX == 255u
typedef unsigned char uint_8t;
# else
# error Please define uint_8t as an 8-bit unsigned integer type in brg_types.h
# endif
#endif
#ifndef BRG_UI16
# define BRG_UI16
# if USHRT_MAX == 65535u
typedef unsigned short uint_16t;
# else
# error Please define uint_16t as a 16-bit unsigned short type in brg_types.h
# endif
#endif
#ifndef BRG_UI32
# define BRG_UI32
# if UINT_MAX == 4294967295u
# define li_32(h) 0x##h##u
typedef unsigned int uint_32t;
# elif ULONG_MAX == 4294967295u
# define li_32(h) 0x##h##ul
typedef unsigned long uint_32t;
# elif defined( _CRAY )
# error This code needs 32-bit data types, which Cray machines do not provide
# else
# error Please define uint_32t as a 32-bit unsigned integer type in brg_types.h
# endif
#endif
#ifndef BRG_UI64
# if defined( __BORLANDC__ ) && !defined( __MSDOS__ )
# define BRG_UI64
# define li_64(h) 0x##h##ui64
typedef unsigned __int64 uint_64t;
# elif defined( _MSC_VER ) && ( _MSC_VER < 1300 ) /* 1300 == VC++ 7.0 */
# define BRG_UI64
# define li_64(h) 0x##h##ui64
typedef unsigned __int64 uint_64t;
# elif defined( __sun ) && defined(ULONG_MAX) && ULONG_MAX == 0xfffffffful
# define BRG_UI64
# define li_64(h) 0x##h##ull
typedef unsigned long long uint_64t;
# elif defined( UINT_MAX ) && UINT_MAX > 4294967295u
# if UINT_MAX == 18446744073709551615u
# define BRG_UI64
# define li_64(h) 0x##h##u
typedef unsigned int uint_64t;
# endif
# elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u
# if ULONG_MAX == 18446744073709551615ul
# define BRG_UI64
# define li_64(h) 0x##h##ul
typedef unsigned long uint_64t;
# endif
# elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u
# if ULLONG_MAX == 18446744073709551615ull
# define BRG_UI64
# define li_64(h) 0x##h##ull
typedef unsigned long long uint_64t;
# endif
# elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u
# if ULONG_LONG_MAX == 18446744073709551615ull
# define BRG_UI64
# define li_64(h) 0x##h##ull
typedef unsigned long long uint_64t;
# endif
# elif defined(__GNUC__) /* DLW: avoid mingw problem with -ansi */
# define BRG_UI64
# define li_64(h) 0x##h##ull
typedef unsigned long long uint_64t;
# endif
#endif
#if defined( NEED_UINT_64T ) && !defined( BRG_UI64 )
# error Please define uint_64t as an unsigned 64 bit type in brg_types.h
#endif
#ifndef RETURN_VALUES
# define RETURN_VALUES
# if defined( DLL_EXPORT )
# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )
# define VOID_RETURN __declspec( dllexport ) void __stdcall
# define INT_RETURN __declspec( dllexport ) int __stdcall
# elif defined( __GNUC__ )
# define VOID_RETURN __declspec( __dllexport__ ) void
# define INT_RETURN __declspec( __dllexport__ ) int
# else
# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers
# endif
# elif defined( DLL_IMPORT )
# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )
# define VOID_RETURN __declspec( dllimport ) void __stdcall
# define INT_RETURN __declspec( dllimport ) int __stdcall
# elif defined( __GNUC__ )
# define VOID_RETURN __declspec( __dllimport__ ) void
# define INT_RETURN __declspec( __dllimport__ ) int
# else
# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers
# endif
# elif defined( __WATCOMC__ )
# define VOID_RETURN void __cdecl
# define INT_RETURN int __cdecl
# else
# define VOID_RETURN void
# define INT_RETURN int
# endif
#endif
/* These defines are used to declare buffers in a way that allows
faster operations on longer variables to be used. In all these
defines 'size' must be a power of 2 and >= 8
dec_unit_type(size,x) declares a variable 'x' of length
'size' bits
dec_bufr_type(size,bsize,x) declares a buffer 'x' of length 'bsize'
bytes defined as an array of variables
each of 'size' bits (bsize must be a
multiple of size / 8)
ptr_cast(x,size) casts a pointer to a pointer to a
varaiable of length 'size' bits
*/
#define ui_type(size) uint_##size##t
#define dec_unit_type(size,x) typedef ui_type(size) x
#define dec_bufr_type(size,bsize,x) typedef ui_type(size) x[bsize / (size >> 3)]
#define ptr_cast(x,size) ((ui_type(size)*)(x))
#if defined(__cplusplus)
}
#endif
#endif
This diff is collapsed.
/*
Copyright (c) 2010 Werner Dittmann
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef SKEINAPI_H
#define SKEINAPI_H
/**
* @file skeinApi.h
* @brief A Skein API and its functions.
* @{
*
* This API and the functions that implement this API simplify the usage
* of Skein. The design and the way to use the functions follow the openSSL
* design but at the same time take care of some Skein specific behaviour
* and possibilities.
*
* The functions enable applications to create a normal Skein hashes and
* message authentication codes (MAC).
*
* Using these functions is simple and straight forward:
*
* @code
*
* #include <skeinApi.h>
*
* ...
* SkeinCtx_t ctx; // a Skein hash or MAC context
*
* // prepare context, here for a Skein with a state size of 512 bits.
* skeinCtxPrepare(&ctx, Skein512);
*
* // Initialize the context to set the requested hash length in bits
* // here request a output hash size of 31 bits (Skein supports variable
* // output sizes even very strange sizes)
* skeinInit(&ctx, 31);
*
* // Now update Skein with any number of message bits. A function that
* // takes a number of bytes is also available.
* skeinUpdateBits(&ctx, message, msgLength);
*
* // Now get the result of the Skein hash. The output buffer must be
* // large enough to hold the request number of output bits. The application
* // may now extract the bits.
* skeinFinal(&ctx, result);
* ...
* @endcode
*
* An application may use @c skeinReset to reset a Skein context and use
* it for creation of another hash with the same Skein state size and output
* bit length. In this case the API implementation restores some internal
* internal state data and saves a full Skein initialization round.
*
* To create a MAC the application just uses @c skeinMacInit instead of
* @c skeinInit. All other functions calls remain the same.
*
*/
#include <skein.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif
/**
* Which Skein size to use
*/
typedef enum SkeinSize {
Skein256 = 256, /*!< Skein with 256 bit state */
Skein512 = 512, /*!< Skein with 512 bit state */
Skein1024 = 1024 /*!< Skein with 1024 bit state */
} SkeinSize_t;
/**
* Context for Skein.
*
* This structure was setup with some know-how of the internal
* Skein structures, in particular ordering of header and size dependent
* variables. If Skein implementation changes this, then adapt these
* structures as well.
*/
typedef struct SkeinCtx {
u64b_t skeinSize;
u64b_t XSave[SKEIN_MAX_STATE_WORDS]; /* save area for state variables */
union {
Skein_Ctxt_Hdr_t h;
Skein_256_Ctxt_t s256;
Skein_512_Ctxt_t s512;
Skein1024_Ctxt_t s1024;
} m;
} SkeinCtx_t;
/**
* Prepare a Skein context.
*
* An application must call this function before it can use the Skein
* context. The functions clears memory and initializes size dependent
* variables.
*
* @param ctx
* Pointer to a Skein context.
* @param size
* Which Skein size to use.
* @return
* SKEIN_SUCESS of SKEIN_FAIL
*/
int skeinCtxPrepare(SkeinCtx_t* ctx, SkeinSize_t size);
/**
* Initialize a Skein context.
*
* Initializes the context with this data and saves the resulting Skein
* state variables for further use.
*
* @param ctx
* Pointer to a Skein context.
* @param hashBitLen
* Number of MAC hash bits to compute
* @return
* SKEIN_SUCESS of SKEIN_FAIL
* @see skeinReset
*/
int skeinInit(SkeinCtx_t* ctx, size_t hashBitLen);
/**
* Resets a Skein context for further use.
*
* Restores the saved chaining variables to reset the Skein context.
* Thus applications can reuse the same setup to process several
* messages. This saves a complete Skein initialization cycle.
*
* @param ctx
* Pointer to a pre-initialized Skein MAC context
*/
void skeinReset(SkeinCtx_t* ctx);
/**
* Initializes a Skein context for MAC usage.
*
* Initializes the context with this data and saves the resulting Skein
* state variables for further use.
*
* Applications call the normal Skein functions to update the MAC and
* get the final result.
*
* @param ctx
* Pointer to an empty or preinitialized Skein MAC context
* @param key
* Pointer to key bytes or NULL
* @param keyLen
* Length of the key in bytes or zero
* @param hashBitLen
* Number of MAC hash bits to compute
* @return
* SKEIN_SUCESS of SKEIN_FAIL
*/
int skeinMacInit(SkeinCtx_t* ctx, const uint8_t *key, size_t keyLen,
size_t hashBitLen);
/**
* Update Skein with the next part of the message.
*
* @param ctx
* Pointer to initialized Skein context
* @param msg
* Pointer to the message.
* @param msgByteCnt
* Length of the message in @b bytes
* @return
* Success or error code.
*/
int skeinUpdate(SkeinCtx_t *ctx, const uint8_t *msg,
size_t msgByteCnt);
/**
* Update the hash with a message bit string.
*
* Skein can handle data not only as bytes but also as bit strings of
* arbitrary length (up to its maximum design size).
*
* @param ctx
* Pointer to initialized Skein context
* @param msg
* Pointer to the message.
* @param msgBitCnt
* Length of the message in @b bits.
*/
int skeinUpdateBits(SkeinCtx_t *ctx, const uint8_t *msg,
size_t msgBitCnt);
/**
* Finalize Skein and return the hash.
*
* Before an application can reuse a Skein setup the application must
* reset the Skein context.
*
* @param ctx
* Pointer to initialized Skein context
* @param hash
* Pointer to buffer that receives the hash. The buffer must be large
* enough to store @c hashBitLen bits.
* @return
* Success or error code.
* @see skeinReset
*/
int skeinFinal(SkeinCtx_t* ctx, uint8_t* hash);
#ifdef __cplusplus
}
#endif
/**
* @}
*/
#endif
#ifndef _SKEIN_IV_H_
#define _SKEIN_IV_H_
#include <skein.h> /* get Skein macros and types */
/*
***************** Pre-computed Skein IVs *******************
**
** NOTE: these values are not "magic" constants, but
** are generated using the Threefish block function.
** They are pre-computed here only for speed; i.e., to
** avoid the need for a Threefish call during Init().
**
** The IV for any fixed hash length may be pre-computed.
** Only the most common values are included here.
**
************************************************************
**/
#define MK_64 SKEIN_MK_64
/* blkSize = 256 bits. hashSize = 128 bits */
const u64b_t SKEIN_256_IV_128[] =
{
MK_64(0xE1111906,0x964D7260),
MK_64(0x883DAAA7,0x7C8D811C),
MK_64(0x10080DF4,0x91960F7A),
MK_64(0xCCF7DDE5,0xB45BC1C2)
};
/* blkSize = 256 bits. hashSize = 160 bits */
const u64b_t SKEIN_256_IV_160[] =
{
MK_64(0x14202314,0x72825E98),
MK_64(0x2AC4E9A2,0x5A77E590),
MK_64(0xD47A5856,0x8838D63E),
MK_64(0x2DD2E496,0x8586AB7D)
};
/* blkSize = 256 bits. hashSize = 224 bits */
const u64b_t SKEIN_256_IV_224[] =
{
MK_64(0xC6098A8C,0x9AE5EA0B),
MK_64(0x876D5686,0x08C5191C),
MK_64(0x99CB88D7,0xD7F53884),
MK_64(0x384BDDB1,0xAEDDB5DE)
};
/* blkSize = 256 bits. hashSize = 256 bits */
const u64b_t SKEIN_256_IV_256[] =
{
MK_64(0xFC9DA860,0xD048B449),
MK_64(0x2FCA6647,0x9FA7D833),
MK_64(0xB33BC389,0x6656840F),
MK_64(0x6A54E920,0xFDE8DA69)
};
/* blkSize = 512 bits. hashSize = 128 bits */
const u64b_t SKEIN_512_IV_128[] =
{
MK_64(0xA8BC7BF3,0x6FBF9F52),
MK_64(0x1E9872CE,0xBD1AF0AA),
MK_64(0x309B1790,0xB32190D3),
MK_64(0xBCFBB854,0x3F94805C),
MK_64(0x0DA61BCD,0x6E31B11B),
MK_64(0x1A18EBEA,0xD46A32E3),
MK_64(0xA2CC5B18,0xCE84AA82),
MK_64(0x6982AB28,0x9D46982D)
};
/* blkSize = 512 bits. hashSize = 160 bits */
const u64b_t SKEIN_512_IV_160[] =
{
MK_64(0x28B81A2A,0xE013BD91),
MK_64(0xC2F11668,0xB5BDF78F),
MK_64(0x1760D8F3,0xF6A56F12),
MK_64(0x4FB74758,0x8239904F),
MK_64(0x21EDE07F,0x7EAF5056),
MK_64(0xD908922E,0x63ED70B8),
MK_64(0xB8EC76FF,0xECCB52FA),
MK_64(0x01A47BB8,0xA3F27A6E)
};
/* blkSize = 512 bits. hashSize = 224 bits */
const u64b_t SKEIN_512_IV_224[] =
{
MK_64(0xCCD06162,0x48677224),
MK_64(0xCBA65CF3,0xA92339EF),
MK_64(0x8CCD69D6,0x52FF4B64),
MK_64(0x398AED7B,0x3AB890B4),
MK_64(0x0F59D1B1,0x457D2BD0),
MK_64(0x6776FE65,0x75D4EB3D),
MK_64(0x99FBC70E,0x997413E9),
MK_64(0x9E2CFCCF,0xE1C41EF7)
};
/* blkSize = 512 bits. hashSize = 256 bits */
const u64b_t SKEIN_512_IV_256[] =
{
MK_64(0xCCD044A1,0x2FDB3E13),
MK_64(0xE8359030,0x1A79A9EB),
MK_64(0x55AEA061,0x4F816E6F),
MK_64(0x2A2767A4,0xAE9B94DB),
MK_64(0xEC06025E,0x74DD7683),
MK_64(0xE7A436CD,0xC4746251),
MK_64(0xC36FBAF9,0x393AD185),
MK_64(0x3EEDBA18,0x33EDFC13)
};
/* blkSize = 512 bits. hashSize = 384 bits */
const u64b_t SKEIN_512_IV_384[] =
{
MK_64(0xA3F6C6BF,0x3A75EF5F),
MK_64(0xB0FEF9CC,0xFD84FAA4),
MK_64(0x9D77DD66,0x3D770CFE),
MK_64(0xD798CBF3,0xB468FDDA),
MK_64(0x1BC4A666,0x8A0E4465),
MK_64(0x7ED7D434,0xE5807407),
MK_64(0x548FC1AC,0xD4EC44D6),
MK_64(0x266E1754,0x6AA18FF8)
};
/* blkSize = 512 bits. hashSize = 512 bits */
const u64b_t SKEIN_512_IV_512[] =
{
MK_64(0x4903ADFF,0x749C51CE),
MK_64(0x0D95DE39,0x9746DF03),
MK_64(0x8FD19341,0x27C79BCE),
MK_64(0x9A255629,0xFF352CB1),
MK_64(0x5DB62599,0xDF6CA7B0),
MK_64(0xEABE394C,0xA9D5C3F4),
MK_64(0x991112C7,0x1A75B523),
MK_64(0xAE18A40B,0x660FCC33)
};
/* blkSize = 1024 bits. hashSize = 384 bits */
const u64b_t SKEIN1024_IV_384[] =
{
MK_64(0x5102B6B8,0xC1894A35),
MK_64(0xFEEBC9E3,0xFE8AF11A),
MK_64(0x0C807F06,0xE32BED71),
MK_64(0x60C13A52,0xB41A91F6),
MK_64(0x9716D35D,0xD4917C38),
MK_64(0xE780DF12,0x6FD31D3A),
MK_64(0x797846B6,0xC898303A),
MK_64(0xB172C2A8,0xB3572A3B),
MK_64(0xC9BC8203,0xA6104A6C),
MK_64(0x65909338,0xD75624F4),
MK_64(0x94BCC568,0x4B3F81A0),
MK_64(0x3EBBF51E,0x10ECFD46),
MK_64(0x2DF50F0B,0xEEB08542),
MK_64(0x3B5A6530,0x0DBC6516),
MK_64(0x484B9CD2,0x167BBCE1),
MK_64(0x2D136947,0xD4CBAFEA)
};
/* blkSize = 1024 bits. hashSize = 512 bits */
const u64b_t SKEIN1024_IV_512[] =
{
MK_64(0xCAEC0E5D,0x7C1B1B18),
MK_64(0xA01B0E04,0x5F03E802),
MK_64(0x33840451,0xED912885),
MK_64(0x374AFB04,0xEAEC2E1C),
MK_64(0xDF25A0E2,0x813581F7),
MK_64(0xE4004093,0x8B12F9D2),
MK_64(0xA662D539,0xC2ED39B6),
MK_64(0xFA8B85CF,0x45D8C75A),
MK_64(0x8316ED8E,0x29EDE796),
MK_64(0x053289C0,0x2E9F91B8),
MK_64(0xC3F8EF1D,0x6D518B73),
MK_64(0xBDCEC3C4,0xD5EF332E),
MK_64(0x549A7E52,0x22974487),
MK_64(0x67070872,0x5B749816),
MK_64(0xB9CD28FB,0xF0581BD1),
MK_64(0x0E2940B8,0x15804974)
};
/* blkSize = 1024 bits. hashSize = 1024 bits */
const u64b_t SKEIN1024_IV_1024[] =
{
MK_64(0xD593DA07,0x41E72355),
MK_64(0x15B5E511,0xAC73E00C),
MK_64(0x5180E5AE,0xBAF2C4F0),
MK_64(0x03BD41D3,0xFCBCAFAF),
MK_64(0x1CAEC6FD,0x1983A898),
MK_64(0x6E510B8B,0xCDD0589F),
MK_64(0x77E2BDFD,0xC6394ADA),
MK_64(0xC11E1DB5,0x24DCB0A3),
MK_64(0xD6D14AF9,0xC6329AB5),
MK_64(0x6A9B0BFC,0x6EB67E0D),
MK_64(0x9243C60D,0xCCFF1332),
MK_64(0x1A1F1DDE,0x743F02D4),
MK_64(0x0996753C,0x10ED0BB8),
MK_64(0x6572DD22,0xF2B4969A),
MK_64(0x61FD3062,0xD00A579A),
MK_64(0x1DE0536E,0x8682E539)
};
#endif /* _SKEIN_IV_H_ */
#ifndef _SKEIN_PORT_H_
#define _SKEIN_PORT_H_
/*******************************************************************
**
** Platform-specific definitions for Skein hash function.
**
** Source code author: Doug Whiting, 2008.
**
** This algorithm and source code is released to the public domain.
**
** Many thanks to Brian Gladman for his portable header files.
**
** To port Skein to an "unsupported" platform, change the definitions
** in this file appropriately.
**
********************************************************************/
#include <brg_types.h> /* get integer type definitions */
typedef unsigned int uint_t; /* native unsigned integer */
typedef uint_8t u08b_t; /* 8-bit unsigned integer */
typedef uint_64t u64b_t; /* 64-bit unsigned integer */
#ifndef RotL_64
#define RotL_64(x,N) (((x) << (N)) | ((x) >> (64-(N))))
#endif
/*
* Skein is "natively" little-endian (unlike SHA-xxx), for optimal
* performance on x86 CPUs. The Skein code requires the following
* definitions for dealing with endianness:
*
* SKEIN_NEED_SWAP: 0 for little-endian, 1 for big-endian
* Skein_Put64_LSB_First
* Skein_Get64_LSB_First
* Skein_Swap64
*
* If SKEIN_NEED_SWAP is defined at compile time, it is used here
* along with the portable versions of Put64/Get64/Swap64, which
* are slow in general.
*
* Otherwise, an "auto-detect" of endianness is attempted below.
* If the default handling doesn't work well, the user may insert
* platform-specific code instead (e.g., for big-endian CPUs).
*
*/
#ifndef SKEIN_NEED_SWAP /* compile-time "override" for endianness? */
#include <brg_endian.h> /* get endianness selection */
#if PLATFORM_BYTE_ORDER == IS_BIG_ENDIAN
/* here for big-endian CPUs */
#define SKEIN_NEED_SWAP (1)
#elif PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN
/* here for x86 and x86-64 CPUs (and other detected little-endian CPUs) */
#define SKEIN_NEED_SWAP (0)
#if PLATFORM_MUST_ALIGN == 0 /* ok to use "fast" versions? */
#define Skein_Put64_LSB_First(dst08,src64,bCnt) memcpy(dst08,src64,bCnt)
#define Skein_Get64_LSB_First(dst64,src08,wCnt) memcpy(dst64,src08,8*(wCnt))
#endif
#else
#error "Skein needs endianness setting!"
#endif
#endif /* ifndef SKEIN_NEED_SWAP */
/*
******************************************************************
* Provide any definitions still needed.
******************************************************************
*/
#ifndef Skein_Swap64 /* swap for big-endian, nop for little-endian */
#if SKEIN_NEED_SWAP
#define Skein_Swap64(w64) \
( (( ((u64b_t)(w64)) & 0xFF) << 56) | \
(((((u64b_t)(w64)) >> 8) & 0xFF) << 48) | \
(((((u64b_t)(w64)) >>16) & 0xFF) << 40) | \
(((((u64b_t)(w64)) >>24) & 0xFF) << 32) | \
(((((u64b_t)(w64)) >>32) & 0xFF) << 24) | \
(((((u64b_t)(w64)) >>40) & 0xFF) << 16) | \
(((((u64b_t)(w64)) >>48) & 0xFF) << 8) | \
(((((u64b_t)(w64)) >>56) & 0xFF) ) )
#else
#define Skein_Swap64(w64) (w64)
#endif
#endif /* ifndef Skein_Swap64 */
#ifndef Skein_Put64_LSB_First
void Skein_Put64_LSB_First(u08b_t *dst,const u64b_t *src,size_t bCnt)
#ifdef SKEIN_PORT_CODE /* instantiate the function code here? */
{ /* this version is fully portable (big-endian or little-endian), but slow */
size_t n;
for (n=0;n<bCnt;n++)
dst[n] = (u08b_t) (src[n>>3] >> (8*(n&7)));
}
#else
; /* output only the function prototype */
#endif
#endif /* ifndef Skein_Put64_LSB_First */
#ifndef Skein_Get64_LSB_First
void Skein_Get64_LSB_First(u64b_t *dst,const u08b_t *src,size_t wCnt)
#ifdef SKEIN_PORT_CODE /* instantiate the function code here? */
{ /* this version is fully portable (big-endian or little-endian), but slow */
size_t n;
for (n=0;n<8*wCnt;n+=8)
dst[n/8] = (((u64b_t) src[n ]) ) +
(((u64b_t) src[n+1]) << 8) +
(((u64b_t) src[n+2]) << 16) +
(((u64b_t) src[n+3]) << 24) +
(((u64b_t) src[n+4]) << 32) +
(((u64b_t) src[n+5]) << 40) +
(((u64b_t) src[n+6]) << 48) +
(((u64b_t) src[n+7]) << 56) ;
}
#else
; /* output only the function prototype */
#endif
#endif /* ifndef Skein_Get64_LSB_First */
#endif /* ifndef _SKEIN_PORT_H_ */
#ifndef THREEFISHAPI_H
#define THREEFISHAPI_H
/**
* @file threefishApi.h
* @brief A Threefish cipher API and its functions.
* @{
*
* This API and the functions that implement this API simplify the usage
* of the Threefish cipher. The design and the way to use the functions
* follow the openSSL design but at the same time take care of some Threefish
* specific behaviour and possibilities.
*
* These are the low level functions that deal with Threefisch blocks only.
* Implementations for cipher modes such as ECB, CFB, or CBC may use these
* functions.
*
@code
// Threefish cipher context data
ThreefishKey_t keyCtx;
// Initialize the context
threefishSetKey(&keyCtx, Threefish512, key, tweak);
// Encrypt
threefishEncryptBlockBytes(&keyCtx, input, cipher);
@endcode
*/
#include <skein.h>
#include <stdint.h>
#define KeyScheduleConst 0x1BD11BDAA9FC1A22L
#ifdef __cplusplus
extern "C"
{
#endif
/**
* Which Threefish size to use
*/
typedef enum ThreefishSize {
Threefish256 = 256, /*!< Skein with 256 bit state */
Threefish512 = 512, /*!< Skein with 512 bit state */
Threefish1024 = 1024 /*!< Skein with 1024 bit state */
} ThreefishSize_t;
/**
* Context for Threefish key and tweak words.
*
* This structure was setup with some know-how of the internal
* Skein structures, in particular ordering of header and size dependent
* variables. If Skein implementation changes this, the adapt these
* structures as well.
*/
typedef struct ThreefishKey {
u64b_t stateSize;
u64b_t key[SKEIN_MAX_STATE_WORDS+1]; /* max number of key words*/
u64b_t tweak[3];
} ThreefishKey_t;
/**
* Set Threefish key and tweak data.
*
* This function sets the key and tweak data for the Threefish cipher of
* the given size. The key data must have the same length (number of bits)
* as the state size
*
* @param keyCtx
* Pointer to a Threefish key structure.
* @param size
* Which Skein size to use.
* @param keyData
* Pointer to the key words (word has 64 bits).
* @param tweak
* Pointer to the two tweak words (word has 64 bits).
*/
void threefishSetKey(ThreefishKey_t* keyCtx, ThreefishSize_t stateSize, uint64_t* keyData, uint64_t* tweak);
/**
* Encrypt Threefisch block (bytes).
*
* The buffer must have at least the same length (number of bits) aas the
* state size for this key. The function uses the first @c stateSize bits
* of the input buffer, encrypts them and stores the result in the output
* buffer.
*
* @param keyCtx
* Pointer to a Threefish key structure.
* @param in
* Poionter to plaintext data buffer.
* @param out
* Pointer to cipher buffer.
*/
void threefishEncryptBlockBytes(ThreefishKey_t* keyCtx, uint8_t* in, uint8_t* out);
/**
* Encrypt Threefisch block (words).
*
* The buffer must have at least the same length (number of bits) aas the
* state size for this key. The function uses the first @c stateSize bits
* of the input buffer, encrypts them and stores the result in the output
* buffer.
*
* The wordsize ist set to 64 bits.
*
* @param keyCtx
* Pointer to a Threefish key structure.
* @param in
* Poionter to plaintext data buffer.
* @param out
* Pointer to cipher buffer.
*/
void threefishEncryptBlockWords(ThreefishKey_t* keyCtx, uint64_t* in, uint64_t* out);
/**
* Decrypt Threefisch block (bytes).
*
* The buffer must have at least the same length (number of bits) aas the
* state size for this key. The function uses the first @c stateSize bits
* of the input buffer, decrypts them and stores the result in the output
* buffer
*
* @param keyCtx
* Pointer to a Threefish key structure.
* @param in
* Poionter to cipher data buffer.
* @param out
* Pointer to plaintext buffer.
*/
void threefishDecryptBlockBytes(ThreefishKey_t* keyCtx, uint8_t* in, uint8_t* out);
/**
* Decrypt Threefisch block (words).
*
* The buffer must have at least the same length (number of bits) aas the
* state size for this key. The function uses the first @c stateSize bits
* of the input buffer, encrypts them and stores the result in the output
* buffer.
*
* The wordsize ist set to 64 bits.
*
* @param keyCtx
* Pointer to a Threefish key structure.
* @param in
* Poionter to cipher data buffer.
* @param out
* Pointer to plaintext buffer.
*/
void threefishDecryptBlockWords(ThreefishKey_t* keyCtx, uint64_t* in, uint64_t* out);
void threefishEncrypt256(ThreefishKey_t* keyCtx, uint64_t* input, uint64_t* output);
void threefishEncrypt512(ThreefishKey_t* keyCtx, uint64_t* input, uint64_t* output);
void threefishEncrypt1024(ThreefishKey_t* keyCtx, uint64_t* input, uint64_t* output);
void threefishDecrypt256(ThreefishKey_t* keyCtx, uint64_t* input, uint64_t* output);
void threefishDecrypt512(ThreefishKey_t* keyCtx, uint64_t* input, uint64_t* output);
void threefishDecrypt1024(ThreefishKey_t* keyCtx, uint64_t* input, uint64_t* output);
#ifdef __cplusplus
}
#endif
/**
* @}
*/
#endif
This diff is collapsed.
/*
Copyright (c) 2010 Werner Dittmann
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#define SKEIN_ERR_CHECK 1
#include <skeinApi.h>
#include <string.h>
#include <stdio.h>
int skeinCtxPrepare(SkeinCtx_t* ctx, SkeinSize_t size)
{
Skein_Assert(ctx && size, SKEIN_FAIL);
memset(ctx ,0, sizeof(SkeinCtx_t));
ctx->skeinSize = size;
return SKEIN_SUCCESS;
}
int skeinInit(SkeinCtx_t* ctx, size_t hashBitLen)
{
int ret = SKEIN_FAIL;
size_t Xlen = 0;
u64b_t* X = NULL;
uint64_t treeInfo = SKEIN_CFG_TREE_INFO_SEQUENTIAL;
Skein_Assert(ctx, SKEIN_FAIL);
/*
* The following two lines rely of the fact that the real Skein contexts are
* a union in out context and thus have tha maximum memory available.
* The beauty of C :-) .
*/
X = ctx->m.s256.X;
Xlen = ctx->skeinSize/8;
/*
* If size is the same and hash bit length is zero then reuse
* the save chaining variables.
*/
switch (ctx->skeinSize) {
case Skein256:
ret = Skein_256_InitExt(&ctx->m.s256, hashBitLen,
treeInfo, NULL, 0);
break;
case Skein512:
ret = Skein_512_InitExt(&ctx->m.s512, hashBitLen,
treeInfo, NULL, 0);
break;
case Skein1024:
ret = Skein1024_InitExt(&ctx->m.s1024, hashBitLen,
treeInfo, NULL, 0);
break;
}
if (ret == SKEIN_SUCCESS) {
/* Save chaining variables for this combination of size and hashBitLen */
memcpy(ctx->XSave, X, Xlen);
}
return ret;
}
int skeinMacInit(SkeinCtx_t* ctx, const uint8_t *key, size_t keyLen,
size_t hashBitLen)
{
int ret = SKEIN_FAIL;
u64b_t* X = NULL;
size_t Xlen = 0;
uint64_t treeInfo = SKEIN_CFG_TREE_INFO_SEQUENTIAL;
Skein_Assert(ctx, SKEIN_FAIL);
X = ctx->m.s256.X;
Xlen = ctx->skeinSize/8;
Skein_Assert(hashBitLen, SKEIN_BAD_HASHLEN);
switch (ctx->skeinSize) {
case Skein256:
ret = Skein_256_InitExt(&ctx->m.s256, hashBitLen,
treeInfo,
(const u08b_t*)key, keyLen);
break;
case Skein512:
ret = Skein_512_InitExt(&ctx->m.s512, hashBitLen,
treeInfo,
(const u08b_t*)key, keyLen);
break;
case Skein1024:
ret = Skein1024_InitExt(&ctx->m.s1024, hashBitLen,
treeInfo,
(const u08b_t*)key, keyLen);
break;
}
if (ret == SKEIN_SUCCESS) {
/* Save chaining variables for this combination of key, keyLen, hashBitLen */
memcpy(ctx->XSave, X, Xlen);
}
return ret;
}
void skeinReset(SkeinCtx_t* ctx)
{
size_t Xlen = 0;
u64b_t* X = NULL;
/*
* The following two lines rely of the fact that the real Skein contexts are
* a union in out context and thus have tha maximum memory available.
* The beautiy of C :-) .
*/
X = ctx->m.s256.X;
Xlen = ctx->skeinSize/8;
/* Restore the chaing variable, reset byte counter */
memcpy(X, ctx->XSave, Xlen);
/* Setup context to process the message */
Skein_Start_New_Type(&ctx->m, MSG);
}
int skeinUpdate(SkeinCtx_t *ctx, const uint8_t *msg,
size_t msgByteCnt)
{
int ret = SKEIN_FAIL;
Skein_Assert(ctx, SKEIN_FAIL);
switch (ctx->skeinSize) {
case Skein256:
ret = Skein_256_Update(&ctx->m.s256, (const u08b_t*)msg, msgByteCnt);
break;
case Skein512:
ret = Skein_512_Update(&ctx->m.s512, (const u08b_t*)msg, msgByteCnt);
break;
case Skein1024:
ret = Skein1024_Update(&ctx->m.s1024, (const u08b_t*)msg, msgByteCnt);
break;
}
return ret;
}
int skeinUpdateBits(SkeinCtx_t *ctx, const uint8_t *msg,
size_t msgBitCnt)
{
/*
* I've used the bit pad implementation from skein_test.c (see NIST CD)
* and modified it to use the convenience functions and added some pointer
* arithmetic.
*/
size_t length;
uint8_t mask;
uint8_t* up;
/* only the final Update() call is allowed do partial bytes, else assert an error */
Skein_Assert((ctx->m.h.T[1] & SKEIN_T1_FLAG_BIT_PAD) == 0 || msgBitCnt == 0, SKEIN_FAIL);
/* if number of bits is a multiple of bytes - that's easy */
if ((msgBitCnt & 0x7) == 0) {
return skeinUpdate(ctx, msg, msgBitCnt >> 3);
}
skeinUpdate(ctx, msg, (msgBitCnt >> 3) + 1);
/*
* The next line rely on the fact that the real Skein contexts
* are a union in our context. After the addition the pointer points to
* Skein's real partial block buffer.
* If this layout ever changes we have to adapt this as well.
*/
up = (uint8_t*)ctx->m.s256.X + ctx->skeinSize / 8;
Skein_Set_Bit_Pad_Flag(ctx->m.h); /* set tweak flag for the skeinFinal call */
/* now "pad" the final partial byte the way NIST likes */
length = ctx->m.h.bCnt; /* get the bCnt value (same location for all block sizes) */
Skein_assert(length != 0); /* internal sanity check: there IS a partial byte in the buffer! */
mask = (uint8_t) (1u << (7 - (msgBitCnt & 7))); /* partial byte bit mask */
up[length-1] = (uint8_t)((up[length-1] & (0-mask))|mask); /* apply bit padding on final byte (in the buffer) */
return SKEIN_SUCCESS;
}
int skeinFinal(SkeinCtx_t* ctx, uint8_t* hash)
{
int ret = SKEIN_FAIL;
Skein_Assert(ctx, SKEIN_FAIL);
switch (ctx->skeinSize) {
case Skein256:
ret = Skein_256_Final(&ctx->m.s256, (u08b_t*)hash);
break;
case Skein512:
ret = Skein_512_Final(&ctx->m.s512, (u08b_t*)hash);
break;
case Skein1024:
ret = Skein1024_Final(&ctx->m.s1024, (u08b_t*)hash);
break;
}
return ret;
}
#include <string.h>
#include <skein.h>
#include <threefishApi.h>
/***************************** Skein_256 ******************************/
void Skein_256_Process_Block(Skein_256_Ctxt_t *ctx, const u08b_t *blkPtr,
size_t blkCnt, size_t byteCntAdd)
{
ThreefishKey_t key;
u64b_t tweak[2];
int i;
u64b_t w[SKEIN_256_STATE_WORDS]; /* local copy of input block */
u64b_t words[3];
Skein_assert(blkCnt != 0); /* never call with blkCnt == 0! */
tweak[0] = ctx->h.T[0];
tweak[1] = ctx->h.T[1];
do {
u64b_t carry = byteCntAdd;
words[0] = tweak[0] & 0xffffffffL;
words[1] = ((tweak[0] >> 32) & 0xffffffffL);
words[2] = (tweak[1] & 0xffffffffL);
for (i = 0; i < 3; i++) {
carry += words[i];
words[i] = carry;
carry >>= 32;
}
tweak[0] = words[0] & 0xffffffffL;
tweak[0] |= (words[1] & 0xffffffffL) << 32;
tweak[1] |= words[2] & 0xffffffffL;
threefishSetKey(&key, Threefish256, ctx->X, tweak);
Skein_Get64_LSB_First(w, blkPtr, SKEIN_256_STATE_WORDS); /* get input block in little-endian format */
threefishEncryptBlockWords(&key, w, ctx->X);
blkPtr += SKEIN_256_BLOCK_BYTES;
/* do the final "feedforward" xor, update context chaining vars */
ctx->X[0] = ctx->X[0] ^ w[0];
ctx->X[1] = ctx->X[1] ^ w[1];
ctx->X[2] = ctx->X[2] ^ w[2];
ctx->X[3] = ctx->X[3] ^ w[3];
tweak[1] &= ~SKEIN_T1_FLAG_FIRST;
} while (--blkCnt);
ctx->h.T[0] = tweak[0];
ctx->h.T[1] = tweak[1];
}
void Skein_512_Process_Block(Skein_512_Ctxt_t *ctx, const u08b_t *blkPtr,
size_t blkCnt, size_t byteCntAdd)
{
ThreefishKey_t key;
u64b_t tweak[2];
int i;
u64b_t words[3];
u64b_t w[SKEIN_512_STATE_WORDS]; /* local copy of input block */
Skein_assert(blkCnt != 0); /* never call with blkCnt == 0! */
tweak[0] = ctx->h.T[0];
tweak[1] = ctx->h.T[1];
do {
u64b_t carry = byteCntAdd;
words[0] = tweak[0] & 0xffffffffL;
words[1] = ((tweak[0] >> 32) & 0xffffffffL);
words[2] = (tweak[1] & 0xffffffffL);
for (i = 0; i < 3; i++) {
carry += words[i];
words[i] = carry;
carry >>= 32;
}
tweak[0] = words[0] & 0xffffffffL;
tweak[0] |= (words[1] & 0xffffffffL) << 32;
tweak[1] |= words[2] & 0xffffffffL;
threefishSetKey(&key, Threefish512, ctx->X, tweak);
Skein_Get64_LSB_First(w, blkPtr, SKEIN_512_STATE_WORDS); /* get input block in little-endian format */
threefishEncryptBlockWords(&key, w, ctx->X);
blkPtr += SKEIN_512_BLOCK_BYTES;
/* do the final "feedforward" xor, update context chaining vars */
ctx->X[0] = ctx->X[0] ^ w[0];
ctx->X[1] = ctx->X[1] ^ w[1];
ctx->X[2] = ctx->X[2] ^ w[2];
ctx->X[3] = ctx->X[3] ^ w[3];
ctx->X[4] = ctx->X[4] ^ w[4];
ctx->X[5] = ctx->X[5] ^ w[5];
ctx->X[6] = ctx->X[6] ^ w[6];
ctx->X[7] = ctx->X[7] ^ w[7];
tweak[1] &= ~SKEIN_T1_FLAG_FIRST;
} while (--blkCnt);
ctx->h.T[0] = tweak[0];
ctx->h.T[1] = tweak[1];
}
void Skein1024_Process_Block(Skein1024_Ctxt_t *ctx, const u08b_t *blkPtr,
size_t blkCnt, size_t byteCntAdd)
{
ThreefishKey_t key;
u64b_t tweak[2];
int i;
u64b_t words[3];
u64b_t w[SKEIN1024_STATE_WORDS]; /* local copy of input block */
Skein_assert(blkCnt != 0); /* never call with blkCnt == 0! */
tweak[0] = ctx->h.T[0];
tweak[1] = ctx->h.T[1];
do {
u64b_t carry = byteCntAdd;
words[0] = tweak[0] & 0xffffffffL;
words[1] = ((tweak[0] >> 32) & 0xffffffffL);
words[2] = (tweak[1] & 0xffffffffL);
for (i = 0; i < 3; i++) {
carry += words[i];
words[i] = carry;
carry >>= 32;
}
tweak[0] = words[0] & 0xffffffffL;
tweak[0] |= (words[1] & 0xffffffffL) << 32;
tweak[1] |= words[2] & 0xffffffffL;
threefishSetKey(&key, Threefish1024, ctx->X, tweak);
Skein_Get64_LSB_First(w, blkPtr, SKEIN1024_STATE_WORDS); /* get input block in little-endian format */
threefishEncryptBlockWords(&key, w, ctx->X);
blkPtr += SKEIN1024_BLOCK_BYTES;
/* do the final "feedforward" xor, update context chaining vars */
ctx->X[ 0] = ctx->X[ 0] ^ w[ 0];
ctx->X[ 1] = ctx->X[ 1] ^ w[ 1];
ctx->X[ 2] = ctx->X[ 2] ^ w[ 2];
ctx->X[ 3] = ctx->X[ 3] ^ w[ 3];
ctx->X[ 4] = ctx->X[ 4] ^ w[ 4];
ctx->X[ 5] = ctx->X[ 5] ^ w[ 5];
ctx->X[ 6] = ctx->X[ 6] ^ w[ 6];
ctx->X[ 7] = ctx->X[ 7] ^ w[ 7];
ctx->X[ 8] = ctx->X[ 8] ^ w[ 8];
ctx->X[ 9] = ctx->X[ 9] ^ w[ 9];
ctx->X[10] = ctx->X[10] ^ w[10];
ctx->X[11] = ctx->X[11] ^ w[11];
ctx->X[12] = ctx->X[12] ^ w[12];
ctx->X[13] = ctx->X[13] ^ w[13];
ctx->X[14] = ctx->X[14] ^ w[14];
ctx->X[15] = ctx->X[15] ^ w[15];
tweak[1] &= ~SKEIN_T1_FLAG_FIRST;
} while (--blkCnt);
ctx->h.T[0] = tweak[0];
ctx->h.T[1] = tweak[1];
}
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
#include <threefishApi.h>
#include <stdlib.h>
#include <string.h>
void threefishSetKey(ThreefishKey_t* keyCtx, ThreefishSize_t stateSize,
uint64_t* keyData, uint64_t* tweak)
{
int keyWords = stateSize / 64;
int i;
uint64_t parity = KeyScheduleConst;
keyCtx->tweak[0] = tweak[0];
keyCtx->tweak[1] = tweak[1];
keyCtx->tweak[2] = tweak[0] ^ tweak[1];
for (i = 0; i < keyWords; i++) {
keyCtx->key[i] = keyData[i];
parity ^= keyData[i];
}
keyCtx->key[i] = parity;
keyCtx->stateSize = stateSize;
}
void threefishEncryptBlockBytes(ThreefishKey_t* keyCtx, uint8_t* in,
uint8_t* out)
{
u64b_t plain[SKEIN_MAX_STATE_WORDS]; /* max number of words*/
u64b_t cipher[SKEIN_MAX_STATE_WORDS];
Skein_Get64_LSB_First(plain, in, keyCtx->stateSize / 64); /* bytes to words */
threefishEncryptBlockWords(keyCtx, plain, cipher);
Skein_Put64_LSB_First(out, cipher, keyCtx->stateSize / 8); /* words to bytes */
}
void threefishEncryptBlockWords(ThreefishKey_t* keyCtx, uint64_t* in,
uint64_t* out)
{
switch (keyCtx->stateSize) {
case Threefish256:
threefishEncrypt256(keyCtx, in, out);
break;
case Threefish512:
threefishEncrypt512(keyCtx, in, out);
break;
case Threefish1024:
threefishEncrypt1024(keyCtx, in, out);
break;
}
}
void threefishDecryptBlockBytes(ThreefishKey_t* keyCtx, uint8_t* in,
uint8_t* out)
{
u64b_t plain[SKEIN_MAX_STATE_WORDS]; /* max number of words*/
u64b_t cipher[SKEIN_MAX_STATE_WORDS];
Skein_Get64_LSB_First(cipher, in, keyCtx->stateSize / 64); /* bytes to words */
threefishDecryptBlockWords(keyCtx, cipher, plain);
Skein_Put64_LSB_First(out, plain, keyCtx->stateSize / 8); /* words to bytes */
}
void threefishDecryptBlockWords(ThreefishKey_t* keyCtx, uint64_t* in,
uint64_t* out)
{
switch (keyCtx->stateSize) {
case Threefish256:
threefishDecrypt256(keyCtx, in, out);
break;
case Threefish512:
threefishDecrypt512(keyCtx, in, out);
break;
case Threefish1024:
threefishDecrypt1024(keyCtx, in, out);
break;
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment