mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Update AES and SHA libs
This commit is contained in:
@@ -1,28 +1,21 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
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 Date: 20/12/2007
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 02/09/2018
|
||||
|
||||
This file contains the definitions required to use AES in C. See aesopt.h
|
||||
for optimisation details.
|
||||
@@ -33,7 +26,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* This include is used to find 8 & 32 bit unsigned integer types */
|
||||
/* This include is used to find 8 & 32 bit unsigned integer types */
|
||||
#include "brg_types.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
@@ -41,24 +34,30 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define AES_128 /* if a fast 128 bit key scheduler is needed */
|
||||
#define AES_192 /* if a fast 192 bit key scheduler is needed */
|
||||
#define AES_256 /* if a fast 256 bit key scheduler is needed */
|
||||
#define AES_VAR /* if variable key size scheduler is needed */
|
||||
#define AES_MODES /* if support is needed for modes */
|
||||
#define AES_128 /* if a fast 128 bit key scheduler is needed */
|
||||
#define AES_192 /* if a fast 192 bit key scheduler is needed */
|
||||
#define AES_256 /* if a fast 256 bit key scheduler is needed */
|
||||
#define AES_VAR /* if variable key size scheduler is needed */
|
||||
#if 1
|
||||
# define AES_MODES /* if support is needed for modes in the C code */
|
||||
#endif /* (these will use AES_NI if it is present) */
|
||||
#if 0 /* add this to make direct calls to the AES_NI */
|
||||
# /* implemented CBC and CTR modes available */
|
||||
# define ADD_AESNI_MODE_CALLS
|
||||
#endif
|
||||
|
||||
/* The following must also be set in assembler files if being used */
|
||||
/* The following must also be set in assembler files if being used */
|
||||
|
||||
#define AES_ENCRYPT /* if support for encryption is needed */
|
||||
#define AES_DECRYPT /* if support for decryption is needed */
|
||||
#define AES_REV_DKS /* define to reverse decryption key schedule */
|
||||
#define AES_ENCRYPT /* if support for encryption is needed */
|
||||
#define AES_DECRYPT /* if support for decryption is needed */
|
||||
|
||||
#define AES_BLOCK_SIZE 16 /* the AES block size in bytes */
|
||||
#define N_COLS 4 /* the number of columns in the state */
|
||||
#define AES_BLOCK_SIZE_P2 4 /* AES block size as a power of 2 */
|
||||
#define AES_BLOCK_SIZE (1 << AES_BLOCK_SIZE_P2) /* AES block size */
|
||||
#define N_COLS 4 /* the number of columns in the state */
|
||||
|
||||
/* The key schedule length is 11, 13 or 15 16-byte blocks for 128, */
|
||||
/* 192 or 256-bit keys respectively. That is 176, 208 or 240 bytes */
|
||||
/* or 44, 52 or 60 32-bit words. */
|
||||
/* The key schedule length is 11, 13 or 15 16-byte blocks for 128, */
|
||||
/* 192 or 256-bit keys respectively. That is 176, 208 or 240 bytes */
|
||||
/* or 44, 52 or 60 32-bit words. */
|
||||
|
||||
#if defined( AES_VAR ) || defined( AES_256 )
|
||||
#define KS_LENGTH 60
|
||||
@@ -70,25 +69,46 @@ extern "C"
|
||||
|
||||
#define AES_RETURN INT_RETURN
|
||||
|
||||
/* the character array 'inf' in the following structures is used */
|
||||
/* to hold AES context information. This AES code uses cx->inf.b[0] */
|
||||
/* to hold the number of rounds multiplied by 16. The other three */
|
||||
/* elements can be used by code that implements additional modes */
|
||||
/* the character array 'inf' in the following structures is used */
|
||||
/* to hold AES context information. This AES code uses cx->inf.b[0] */
|
||||
/* to hold the number of rounds multiplied by 16. The other three */
|
||||
/* elements can be used by code that implements additional modes */
|
||||
|
||||
typedef union
|
||||
{ uint_32t l;
|
||||
uint_8t b[4];
|
||||
{ uint32_t l;
|
||||
uint8_t b[4];
|
||||
} aes_inf;
|
||||
|
||||
typedef struct
|
||||
{ uint_32t ks[KS_LENGTH];
|
||||
aes_inf inf;
|
||||
} aes_encrypt_ctx;
|
||||
/* Macros for detecting whether a given context was initialized for */
|
||||
/* use with encryption or decryption code. These should only be used */
|
||||
/* by e.g. language bindings which lose type information when the */
|
||||
/* context pointer is passed to the calling language's runtime. */
|
||||
#define IS_ENCRYPTION_CTX(cx) (((cx)->inf.b[2] & (uint8_t)0x01) == 1)
|
||||
#define IS_DECRYPTION_CTX(cx) (((cx)->inf.b[2] & (uint8_t)0x01) == 0)
|
||||
|
||||
typedef struct
|
||||
{ uint_32t ks[KS_LENGTH];
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning( disable : 4324 )
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && defined(_WIN64)
|
||||
#define ALIGNED_(x) __declspec(align(x))
|
||||
#elif defined(__GNUC__) && defined(__x86_64__)
|
||||
#define ALIGNED_(x) __attribute__ ((aligned(x)))
|
||||
#else
|
||||
#define ALIGNED_(x)
|
||||
#endif
|
||||
|
||||
typedef struct ALIGNED_(16)
|
||||
{ uint32_t ks[KS_LENGTH];
|
||||
aes_inf inf;
|
||||
} aes_decrypt_ctx;
|
||||
} aes_crypt_ctx;
|
||||
|
||||
typedef aes_crypt_ctx aes_encrypt_ctx;
|
||||
typedef aes_crypt_ctx aes_decrypt_ctx;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning( default : 4324 )
|
||||
#endif
|
||||
|
||||
/* This routine must be called before first use if non-static */
|
||||
/* tables are being used */
|
||||
@@ -146,14 +166,14 @@ AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_de
|
||||
|
||||
/* Multiple calls to the following subroutines for multiple block */
|
||||
/* ECB, CBC, CFB, OFB and CTR mode encryption can be used to handle */
|
||||
/* long messages incremantally provided that the context AND the iv */
|
||||
/* long messages incrementally provided that the context AND the iv */
|
||||
/* are preserved between all such calls. For the ECB and CBC modes */
|
||||
/* each individual call within a series of incremental calls must */
|
||||
/* process only full blocks (i.e. len must be a multiple of 16) but */
|
||||
/* the CFB, OFB and CTR mode calls can handle multiple incremental */
|
||||
/* calls of any length. Each mode is reset when a new AES key is */
|
||||
/* set but ECB and CBC operations can be reset without setting a */
|
||||
/* new key by setting a new IV value. To reset CFB, OFB and CTR */
|
||||
/* calls of any length. Each mode is reset when a new AES key is */
|
||||
/* set but ECB needs no reset and CBC can be reset without setting */
|
||||
/* a new key by setting a new IV value. To reset CFB, OFB and CTR */
|
||||
/* without setting the key, aes_mode_reset() must be called and the */
|
||||
/* IV must be set. NOTE: All these calls update the IV on exit so */
|
||||
/* this has to be reset if a new operation with the same IV as the */
|
||||
@@ -198,6 +218,59 @@ AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
|
||||
#endif
|
||||
|
||||
#if 0 && defined( ADD_AESNI_MODE_CALLS )
|
||||
# define USE_AES_CONTEXT
|
||||
#endif
|
||||
|
||||
#ifdef ADD_AESNI_MODE_CALLS
|
||||
# ifdef USE_AES_CONTEXT
|
||||
|
||||
AES_RETURN aes_CBC_encrypt(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
unsigned char ivec[16],
|
||||
unsigned long length,
|
||||
const aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_CBC_decrypt(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
unsigned char ivec[16],
|
||||
unsigned long length,
|
||||
const aes_decrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN AES_CTR_encrypt(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
const unsigned char ivec[8],
|
||||
const unsigned char nonce[4],
|
||||
unsigned long length,
|
||||
const aes_encrypt_ctx cx[1]);
|
||||
|
||||
# else
|
||||
|
||||
void aes_CBC_encrypt(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
unsigned char ivec[16],
|
||||
unsigned long length,
|
||||
unsigned char *key,
|
||||
int number_of_rounds);
|
||||
|
||||
void aes_CBC_decrypt(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
unsigned char ivec[16],
|
||||
unsigned long length,
|
||||
unsigned char *key,
|
||||
int number_of_rounds);
|
||||
|
||||
void aes_CTR_encrypt(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
const unsigned char ivec[8],
|
||||
const unsigned char nonce[4],
|
||||
unsigned long length,
|
||||
const unsigned char *key,
|
||||
int number_of_rounds);
|
||||
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2,8 +2,67 @@
|
||||
An AES (Rijndael) Implementation in C/C++ (as specified in FIPS-197)
|
||||
====================================================================
|
||||
|
||||
Changes in this Version (16/04/2007)
|
||||
====================================
|
||||
Change (26/09/2018)
|
||||
===================
|
||||
|
||||
1. Changes to test programs to allow them to be built on Linux/GCC
|
||||
(with thanks to Michael Mohr).
|
||||
|
||||
2. Rationalisation of the defines DLL_IMPORT, DYNAMIC_DLL and USE_DLL
|
||||
in the test code - now DLL_IMPORT and DLL_DYNAMIC_LOAD
|
||||
|
||||
3. Update the test_avs test to allow the testing of static, DLL and
|
||||
dynamically loaded DLL libraries.
|
||||
|
||||
Change (21/05/2018)
|
||||
===================
|
||||
|
||||
1. Properly dectect presence of AESNI when using GCC (my thanks to
|
||||
Peter Gutmann for this fix)
|
||||
|
||||
Changes (6/12/2016)
|
||||
====================
|
||||
|
||||
1. Changed function definition of has_aes_ni() to has_aes_ni(void),
|
||||
suggested by Peter Gutmann
|
||||
|
||||
2. Changed the default location for the vsyasm assembler to:
|
||||
C:\Program Files\yasm
|
||||
|
||||
Changes (27/09/2015)
|
||||
====================
|
||||
|
||||
1. Added automatic dynamic table initialisation (my thanks to
|
||||
Henrik S. Ga<47>mann who proposed this addition).
|
||||
|
||||
Changes (09/09/2014)
|
||||
====================
|
||||
|
||||
1. Added the ability to use Intel's hardware support for AES
|
||||
with GCC on Windows and Linux
|
||||
|
||||
Changes (01/09/2014)
|
||||
====================
|
||||
|
||||
1. Clarify some user choices in the file aes_amd64.asm
|
||||
|
||||
2. Change the detection of the x86 and x86_64 processors
|
||||
in aesopt.h to allow assembler code use with GCC
|
||||
|
||||
Changes (14/11/2013)
|
||||
====================
|
||||
|
||||
1. Added the ability to use Intel's hardware support for AES
|
||||
on Windows using Microsoft Visual Studio.
|
||||
|
||||
2. Added the include 'stdint.h' and used the uint<xx>_t instead
|
||||
of the old uint_<xx>t (e.g. uint_32t is now uint32_t).
|
||||
|
||||
3. Added a missing .text directive in aes_x86_v2.asm that caused
|
||||
runtime errors in one build configuration.
|
||||
|
||||
Changes (16/04/2007)
|
||||
====================
|
||||
|
||||
These changes remove errors in the VC++ build files and add some
|
||||
improvements in file naming consitency and portability. There are
|
||||
@@ -59,6 +118,11 @@ In addition AES modes are implemented in the files:
|
||||
aes_modes.c AES modes with optional support for VIA ACE detection and use
|
||||
aes_via_ace.h the header file for VIA ACE support
|
||||
|
||||
and Intel hardware support for AES (AES_NI) is implemented in the files
|
||||
|
||||
aes_ni.h defines for AES_NI implementation
|
||||
aes_ni.c the AES_NI implementation
|
||||
|
||||
Other associated files for testing and support are:
|
||||
|
||||
aesaux.h header for auxilliary routines for testsing
|
||||
@@ -88,104 +152,105 @@ A. Versions
|
||||
The code can be used to build static and dynamic libraries, each in five
|
||||
versions:
|
||||
|
||||
C uses C source code only
|
||||
ASM_X86_V1C large table x86 assembler code for encrypt/decrypt
|
||||
ASM_X86_V2 compressed table x86 assembler for encrypt/decrypt and keying
|
||||
ASM_X86_V2C compressed table x86 assembler code for encrypt/decrypt
|
||||
ASM_AMD64 compressed table x86 assembler code for encrypt/decrypt
|
||||
Key scheduling code in C, encrypt/decrypt in:
|
||||
|
||||
The C version can be compiled for Win32 or x64, the x86 assembler versions
|
||||
are for Win32 only and the AMD64 version for x64 only.
|
||||
C C source code (win32 and x64)
|
||||
ASM_X86_V1C large table x86 assembler code (win32)
|
||||
ASM_X86_V2C compressed table x86 assembler code (win32)
|
||||
ASM_AMD64 compressed table x64 assembler code (x64)
|
||||
|
||||
B. Types
|
||||
--------
|
||||
Key scheduling and encrypt/decrypt code in assembler:
|
||||
|
||||
The code makes use of types defined as 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 fixed width integer types in C99, inttypes.h and stdint.h
|
||||
since several attempts to use these types have shown that support for them is
|
||||
still highly variable. But a regular expression search and replace in VC++
|
||||
with search on 'uint_{:z}t' and a replace with 'uint\1_t' will convert these
|
||||
types to C99 types (there should be similar search/replace facilities on other
|
||||
systems).
|
||||
ASM_X86_V2 compressed table x86 assembler (win32)
|
||||
|
||||
C. YASM
|
||||
The C version can be compiled for Win32 or x64 whereas the x86 and x64
|
||||
assembler versions are for Win32 and x64 respectively.
|
||||
|
||||
If Intel's hardware support for AES (AES_NI) is available, it can be used
|
||||
with either the C or the ASM_AMD64 version. If ASM_AMD64 is to be used, it
|
||||
is important that the define USE_INTEL_AES_IF_PRESENT in asm_amd64.asm is
|
||||
set to the same value as it has in aesopt.h
|
||||
|
||||
B. YASM
|
||||
-------
|
||||
|
||||
If you wish to use the x86 assembler files you will also need the YASM open
|
||||
source x86 assembler (r1331 or later) for Windows which can be obtained from:
|
||||
|
||||
http://www.tortall.net/projects/yasm/
|
||||
http://www.tortall.net/projects/yasm/
|
||||
|
||||
This assembler should be placed in the bin directory used by VC++, which, for
|
||||
Visual Stduio 2005, is typically:
|
||||
This assembler (vsyasm.exe) should be placed in the directory:
|
||||
|
||||
C:\Program Files (x86)\Microsoft Visual Studio 8\VC\bin
|
||||
C:\Program Files\yasm
|
||||
|
||||
You will also need to move the yasm.rules file from this distribution into
|
||||
the directory where Visual Studio 2005 expects to find it, which is typically:
|
||||
|
||||
C:\Program Files (x86)\Microsoft Visual Studio 8\VC\VCProjectDefaults
|
||||
|
||||
Alternatively you can configure the path for rules files within Visual Studio.
|
||||
|
||||
D. Configuration
|
||||
C. Configuration
|
||||
----------------
|
||||
|
||||
The following configurations are available as projects for Visual Studio 2005
|
||||
The following configurations are available as projects for Visual Studio
|
||||
but the following descriptions should allow them to be built in other x86
|
||||
environments:
|
||||
environments
|
||||
|
||||
lib_generic_c Win32 and x64
|
||||
headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs,h
|
||||
headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
|
||||
(+ aes_ni.h for AES_NI)
|
||||
C source: aescrypt.c, aeskey.c, aestab.c, aes_modes.c
|
||||
(+ aes_ni.c for AES_NI)
|
||||
defines
|
||||
|
||||
dll_generic_c Win32 and x64
|
||||
headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs,h
|
||||
headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
|
||||
(+ aes_ni.h for AES_NI)
|
||||
C source: aescrypt.c, aeskey.c, aestab.c, aes_modes.c
|
||||
(+ aes_ni.c for AES_NI)
|
||||
defines DLL_EXPORT
|
||||
|
||||
lib_asm_x86_v1c Win32
|
||||
headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs,h
|
||||
headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
|
||||
C source: aeskey.c, aestab.c, aes_modes.c
|
||||
x86 assembler: aes_x86_v1.asm
|
||||
defines ASM_X86_V1C (set for C and assembler files)
|
||||
dll_asm_x86_v1c Win32
|
||||
headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs,h
|
||||
|
||||
dll_asm_x86_v1c Win32
|
||||
headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
|
||||
C source: aeskey.c, aestab.c, aes_modes.c
|
||||
x86 assembler: aes_x86_v1.asm
|
||||
defines DLL_EXPORT, ASM_X86_V1C (set for C and assembler files)
|
||||
|
||||
lib_asm_x86_v2c Win32
|
||||
headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs,h
|
||||
headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
|
||||
C source: aeskey.c, aestab.c, aes_modes.c
|
||||
x86 assembler: aes_x86_v2.asm
|
||||
defines ASM_X86_V2C (set for C and assembler files)
|
||||
dll_asm_x86_v2c Win32
|
||||
headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs,h
|
||||
|
||||
dll_asm_x86_v2c Win32
|
||||
headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
|
||||
C source: aeskey.c, aestab.c, aes_modes.c
|
||||
x86 assembler: aes_x86_v1.asm
|
||||
defines DLL_EXPORT, ASM_X86_V2C (set for C and assembler files)
|
||||
|
||||
lib_asm_x86_v2 Win32
|
||||
headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs,h
|
||||
headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
|
||||
C source: aes_modes.c
|
||||
x86 assembler: aes_x86_v1.asm
|
||||
defines ASM_X86_V2 (set for C and assembler files)
|
||||
dll_asm_x86_v2 Win32
|
||||
headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs,h
|
||||
|
||||
dll_asm_x86_v2 Win32
|
||||
headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
|
||||
C source: aes_modes.c
|
||||
x86 assembler: aes_x86_v1.asm
|
||||
defines DLL_EXPORT, ASM_AMD64_C (set for C and assembler files)
|
||||
|
||||
lib_asm_amd64_c x64
|
||||
headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs,h
|
||||
C source: aes_modes.c
|
||||
headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
|
||||
(+ aes_ni.h for AES_NI)
|
||||
C source: aes_modes.c (+ aes_ni.c for AES_NI)
|
||||
x86 assembler: aes_amd64.asm
|
||||
defines ASM_X86_V2 (set for C and assembler files)
|
||||
dll_asm_amd64_c x64
|
||||
headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs,h
|
||||
C source: aes_modes.c
|
||||
defines ASM_AMD64_C (set for C and assembler files)
|
||||
|
||||
dll_asm_amd64_c x64
|
||||
headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
|
||||
(+ aes_ni.h for AES_NI)
|
||||
C source: aes_modes.c (+ aes_ni.c for AES_NI)
|
||||
x86 assembler: aes_amd64.asm
|
||||
defines DLL_EXPORT, ASM_AMD64_C (set for C and assembler files)
|
||||
|
||||
@@ -195,28 +260,27 @@ ASM_X86_V1C is defined if using the version 1 assembler code (aescrypt1.asm).
|
||||
The defines in the assember file must match those in aes.h and
|
||||
aesopt.h). Also remember to include/exclude the right assembler
|
||||
and C files in the build to avoid undefined or multiply defined
|
||||
symbols - include aescrypt1.asm and exclude aescrypt.c and
|
||||
aescrypt2.asm.
|
||||
symbols - include aes_x86_v1.asm and exclude aescrypt.c
|
||||
|
||||
ASM_X86_V2 is defined if using the version 2 assembler code (aescrypt2.asm).
|
||||
ASM_X86_V2 is defined if using the version 2 assembler code (aes_x86_v2.asm).
|
||||
This version provides a full, self contained assembler version
|
||||
and does not use any C source code files except for the mutiple
|
||||
block encryption modes that are provided by aes_modes.c. The define
|
||||
ASM_X86_V2 must be set on the YASM command line (or in aescrypt2.asm)
|
||||
to use this version and all C files except aec_modes.c and. for the
|
||||
ASM_X86_V2 must be set on the YASM command line (or in aes_x86_v2.asm)
|
||||
to use this version and all C files except aec_modes.c and, for the
|
||||
DLL build, aestab.c must be excluded from the build.
|
||||
|
||||
ASM_X86_V2C is defined when using the version 2 assembler code (aescrypt2.asm)
|
||||
ASM_X86_V2C is defined when using the version 2 assembler code (aes_x86_v2.asm)
|
||||
with faster key scheduling provided by the in C code (the options in
|
||||
the assember file must match those in aes.h and aesopt.h). In this
|
||||
case aeskey.c and aestab.c are needed with aescrypt2.asm and the
|
||||
case aeskey.c and aestab.c are needed with aes_x86_v2.asm and the
|
||||
define ASM_X86_V2C must be set for both the C files and for
|
||||
asecrypt2.asm command lines (or in aesopt.h and aescrypt2.asm).
|
||||
Include aescrypt2.asm aeskey.c and aestab.c, exclude aescrypt.c for
|
||||
aes_x86_v2.asm in the build commands(or in aesopt.h and aes_x86_v2.asm).
|
||||
Include aes_x86_v2.asm, aeskey.c and aestab.c, exclude aescrypt.c for
|
||||
this option.
|
||||
|
||||
ASM_AMD64_C is defined when using the AMD64 assembly code because the C key
|
||||
scheduling is sued in this case.
|
||||
scheduling is used in this case.
|
||||
|
||||
DLL_EXPORT must be defined to generate the DLL version of the code and
|
||||
to run tests on it
|
||||
@@ -246,11 +310,11 @@ Libraries
|
||||
|
||||
in the aes root directory depending on the platform(win32 or
|
||||
x64) and the build (release or debug). After any of these is
|
||||
built it is then copied into aes.lib, which is the library
|
||||
that is subsequently used for testing. Hence testing is for
|
||||
the last static library built.
|
||||
built it is then copied into the aes\lib directory, which is
|
||||
the library location that is subsequently used for testing.
|
||||
Hence testing is always for the last static library built.
|
||||
|
||||
Dynamic The static libraries are named:
|
||||
Dynamic These libraries are named:
|
||||
Libraries
|
||||
aes_lib_generic_c.dll
|
||||
aes_lib_asm_x86_v1c.dll
|
||||
@@ -277,18 +341,31 @@ Libraries
|
||||
aes_dll_<ext>.pdb the symbol file
|
||||
|
||||
After any DLL is built it and its three related files are then
|
||||
copied into aes.lib, aes.lib, aes,exp and aes.pdb, which are
|
||||
the libraries used for testing. Hence testing is for the last
|
||||
static library or DLL built.
|
||||
copied to the aes\dll directory, which is the library location
|
||||
used in subsequent testing. Hence testing is always for the
|
||||
last DLL built.
|
||||
|
||||
E. Testing
|
||||
D. Testing
|
||||
----------
|
||||
|
||||
These tests require that the test vector files are placed in the 'testvals'
|
||||
subdirectory. If the AES Algorithm Validation Suite tests will be use3d then
|
||||
subdirectory. If the AES Algorithm Validation Suite tests are used then
|
||||
the *.fax files need to be put in the 'testvals\fax' subdirectory. This is
|
||||
covered in more detail below.
|
||||
|
||||
The projects test_lib and time_lib are used to test and time the last static
|
||||
library built. They use the files:
|
||||
|
||||
test_lib: Win32 (x64 for the C and AMD64 versions)
|
||||
headers: aes.h, aescpp.h, brg_types.h, aesaux.h and aestst.h
|
||||
C source: aesaux.c, aesrav.c
|
||||
defines:
|
||||
|
||||
time_lib: Win32 (x64 for the C and AMD64 versions)
|
||||
headers: aes.h, aescpp.h, brg_types.h, aesaux.h, aestst.h and rdtsc.h
|
||||
C source: aesaux.c, aestmr.c
|
||||
defines:
|
||||
|
||||
The projects test_dll and time_dll are used to test and time the last DLL
|
||||
built. These use the files:
|
||||
|
||||
@@ -302,26 +379,15 @@ built. These use the files:
|
||||
C source: aesaux.c, aestmr.c
|
||||
defines: DLL_IMPORT
|
||||
|
||||
and link to the DLL using explicit linking. However, if the lib file associated
|
||||
with the DLL is linked into this project and the symbol DYNAMIC_LINK in aestst.h
|
||||
is left undefined, then implicit linking will be used
|
||||
and default to linkingto with the AES DLL using dynamic (run-time) linking. Implicit
|
||||
linking can be used by adding the lib file associated with the AES DLL (in the aes\dll
|
||||
sub-directory) to the build (under project Properties|Linker in Visual Studio) and
|
||||
removing the DLL_DYNAMIC_LOAD define (under project Properties|C/C++|Preprocessor).
|
||||
|
||||
The projects test_lib and time_lib are used to test and time the last static LIB
|
||||
built. They use the files:
|
||||
0 Link is linked into this project and the symbol
|
||||
DLL_DYNAMIC_LOAD is left undefined, then implicit linking will be used
|
||||
|
||||
test_lib: Win32 (x64 for the C and AMD64 versions)
|
||||
headers: aes.h, aescpp.h, brg_types.h, aesaux.h and aestst.h
|
||||
C source: aesaux.c, aesrav.c
|
||||
defines:
|
||||
|
||||
time_lib: Win32 (x64 for the C and AMD64 versions)
|
||||
headers: aes.h, aescpp.h, brg_types.h, aesaux.h, aestst.h and rdtsc.h
|
||||
C source: aesaux.c, aestmr.c
|
||||
defines:
|
||||
|
||||
and link to the last static library built.
|
||||
|
||||
The above test take command line arguments that determine which test are run
|
||||
The above tests take command line arguments that determine which test are run
|
||||
as follows:
|
||||
|
||||
test_lib /t:[knec] /k:[468]
|
||||
@@ -339,8 +405,8 @@ the brackets) and have the following meanings:
|
||||
e: generate ECB Monte Carlo Test files
|
||||
c: generate CBC Monte Carlo Test files
|
||||
|
||||
and the characters giving the lengths are digits representing the lengths in
|
||||
32-bit units.\n\n");
|
||||
and the characters giving the lengths are digits representing the key lengths
|
||||
in 32-bit units (4, 6, 8 for lengths of 128, 192 or 256 bits respectively).
|
||||
|
||||
The project test_modes tests the AES modes. It uses the files:
|
||||
|
||||
@@ -351,7 +417,7 @@ The project test_modes tests the AES modes. It uses the files:
|
||||
|
||||
which again links to the last library built.
|
||||
|
||||
F. Other Applications
|
||||
E. Other Applications
|
||||
---------------------
|
||||
|
||||
These are:
|
||||
@@ -370,8 +436,8 @@ These are:
|
||||
These applications are linked to the last static library built or, if
|
||||
DLL_IMPORT is defined during compilation, to the last DLL built.
|
||||
|
||||
G. Use of the VIA ACE Cryptography Engine
|
||||
-----------------------------------------
|
||||
F. Use of the VIA ACE Cryptography Engine (x86 only)
|
||||
----------------------------------------------------
|
||||
|
||||
The use of the code with the VIA ACE cryptography engine in described in the
|
||||
file via_ace.txt. In outline aes_modes.c is used and USE_VIA_ACE_IF_PRESENT
|
||||
@@ -382,7 +448,7 @@ support is needed and AES assembler is being used only the ASM_X86_V1C and
|
||||
ASM_X86_V2C versions should be used since ASM_X86_V2 and ASM_AMD64 do not
|
||||
support the VIA ACE engine.
|
||||
|
||||
H. The AES Test Vector Files
|
||||
G. The AES Test Vector Files
|
||||
----------------------------
|
||||
|
||||
These files fall in the following groups (where <nn> is a two digit
|
||||
@@ -410,7 +476,7 @@ The AES Algorithm Validation Suite tests can be run for ECB, CBC, CFB and
|
||||
OFB modes (CFB1 and CFB8 are not implemented). The test routine uses the
|
||||
*.fax test files, which should be placed in the 'testvals\fax' subdirectory.
|
||||
|
||||
I. The Basic AES Calling Interface
|
||||
H. The Basic AES Calling Interface
|
||||
----------------------------------
|
||||
|
||||
The basic AES code keeps its state in a context, there being different
|
||||
@@ -421,7 +487,7 @@ contexts for encryption and decryption:
|
||||
|
||||
The AES code is initialised with the call
|
||||
|
||||
aes_init(void)
|
||||
aes_init(void)
|
||||
|
||||
although this is only essential if the option to generate the AES tables at
|
||||
run-time has been set in the options (i.e.fixed tables are not being used).
|
||||
@@ -461,7 +527,7 @@ Encryption and decryption for a single 16 byte block is then achieved using:
|
||||
The above subroutines return a value of EXIT_SUCCESS or EXIT_FAILURE
|
||||
depending on whether the operation succeeded or failed.
|
||||
|
||||
J. The Calling Interface for the AES Modes
|
||||
I. The Calling Interface for the AES Modes
|
||||
------------------------------------------
|
||||
|
||||
The subroutines for the AES modes, ECB, CBC, CFB, OFB and CTR, each process
|
||||
@@ -524,8 +590,8 @@ Please note the following IMPORTANT points about the AES mode subroutines:
|
||||
key must be set or a reset must be issued (see
|
||||
below).
|
||||
|
||||
3. For modes with IVs, the IV value is an inpu AND
|
||||
an ouput since it is updated after each call to
|
||||
3. For modes with IVs, the IV value is an input AND
|
||||
an output since it is updated after each call to
|
||||
the value needed for any subsequent incremental
|
||||
call(s). If the mode is reset, the IV hence has
|
||||
to be set (or reset) as well.
|
||||
@@ -546,11 +612,11 @@ Please note the following IMPORTANT points about the AES mode subroutines:
|
||||
|
||||
7. CFB, OFB and CTR modes only use AES encryption
|
||||
operations and contexts and do not need AES
|
||||
decrytpion operations.
|
||||
decryption operations.
|
||||
|
||||
8. AES keys remain valid across resets and changes
|
||||
of mode (but encryption and decryption keys must
|
||||
both be set if they are needed).
|
||||
|
||||
Brian Gladman 22/07/2008
|
||||
Brian Gladman 26/09/2018
|
||||
|
||||
@@ -1,28 +1,21 @@
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Copyright (c) 1998-2007, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
; Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
;
|
||||
; LICENSE TERMS
|
||||
; The redistribution and use of this software (with or without changes)
|
||||
; is allowed without the payment of fees or royalties provided that:
|
||||
;
|
||||
; The free distribution and use of this software is allowed (with or without
|
||||
; changes) provided that:
|
||||
; source code distributions include the above copyright notice, this
|
||||
; list of conditions and the following disclaimer;
|
||||
;
|
||||
; 1. source code distributions include the above copyright notice, this
|
||||
; list of conditions and the following disclaimer;
|
||||
;
|
||||
; 2. binary distributions include the above copyright notice, this list
|
||||
; of conditions and the following disclaimer in their documentation;
|
||||
;
|
||||
; 3. the name of the copyright holder is not used to endorse products
|
||||
; built using this software without specific written permission.
|
||||
;
|
||||
; DISCLAIMER
|
||||
; binary distributions include the above copyright notice, this list
|
||||
; of conditions and the following disclaimer in their documentation.
|
||||
;
|
||||
; 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.
|
||||
; in respect of its operation, including, but not limited to, correctness
|
||||
; and fitness for purpose.
|
||||
; ---------------------------------------------------------------------------
|
||||
; Issue 20/12/2007
|
||||
; Issue Date: 27/10/2018
|
||||
;
|
||||
; I am grateful to Dag Arne Osvik for many discussions of the techniques that
|
||||
; can be used to optimise AES assembler code on AMD64/EM64T architectures.
|
||||
@@ -53,6 +46,9 @@
|
||||
; Define _SEH_ to include support for Win64 structured exception handling
|
||||
; (this requires YASM version 0.6 or later).
|
||||
;
|
||||
; In order to use this code in Windows kernel mode, set the NO_PAGING define
|
||||
; to disable structured exception handling and paging.
|
||||
;
|
||||
; This code provides the standard AES block size (128 bits, 16 bytes) and the
|
||||
; three standard AES key sizes (128, 192 and 256 bits). It has the same call
|
||||
; interface as my C implementation. It uses the Microsoft C AMD64 calling
|
||||
@@ -77,19 +73,40 @@
|
||||
; AES_RETURN aes_decrypt_key(const unsigned char key[],
|
||||
; unsigned int len, const aes_decrypt_ctx cx[1]);
|
||||
;
|
||||
; where <NNN> is 128, 102 or 256. In the last two calls the length can be in
|
||||
; where <NNN> is 128, 192 or 256. In the last two calls the length can be in
|
||||
; either bits or bytes.
|
||||
;
|
||||
; Comment in/out the following lines to obtain the desired subroutines. These
|
||||
; selections MUST match those in the C header file aes.h
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
; Use of this assembler code in Windows kernel mode requires structured
|
||||
; exception handling and memory paging to be disabled
|
||||
%ifdef NO_PAGING
|
||||
%undef _SEH_
|
||||
%define set_page nopage
|
||||
%else
|
||||
%define set_page
|
||||
%endif
|
||||
|
||||
; Comment in/out the following lines to obtain the desired subroutines. These
|
||||
; selections MUST match those in the C header files aes.h and aesopt.h
|
||||
%ifdef INTEL_AES_POSSIBLE
|
||||
%define USE_INTEL_AES_IF_PRESENT
|
||||
%endif
|
||||
%define AES_128 ; define if AES with 128 bit keys is needed
|
||||
%define AES_192 ; define if AES with 192 bit keys is needed
|
||||
%define AES_256 ; define if AES with 256 bit keys is needed
|
||||
%define AES_VAR ; define if a variable key size is needed
|
||||
%define ENCRYPTION ; define if encryption is needed
|
||||
%define DECRYPTION ; define if decryption is needed
|
||||
%define AES_REV_DKS ; define if key decryption schedule is reversed
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
%ifdef USE_INTEL_AES_IF_PRESENT
|
||||
%define aes_ni(x) aes_ %+ x %+ _i
|
||||
%undef AES_REV_DKS
|
||||
%else
|
||||
%define aes_ni(x) aes_ %+ x
|
||||
%define AES_REV_DKS
|
||||
%endif
|
||||
|
||||
%define LAST_ROUND_TABLES ; define for the faster version using extra tables
|
||||
|
||||
@@ -126,15 +143,15 @@
|
||||
; | decryption round N-1 | = INV_MIX_COL[ | encryption round N-1 | ]
|
||||
; hi: | decryption round N | = | encryption round N |
|
||||
;
|
||||
; This layout is faster when the assembler key scheduling provided here
|
||||
; is used.
|
||||
; This layout is faster when the assembler key scheduling is used (not
|
||||
; used here).
|
||||
;
|
||||
; The DLL interface must use the _stdcall convention in which the number
|
||||
; of bytes of parameter space is added after an @ to the sutine's name.
|
||||
; of bytes of parameter space is added after an @ to the rouutine's name.
|
||||
; We must also remove our parameters from the stack before return (see
|
||||
; the do_exit macro). Define DLL_EXPORT for the Dynamic Link Library version.
|
||||
|
||||
;%define DLL_EXPORT
|
||||
; %define DLL_EXPORT
|
||||
|
||||
; End of user defines
|
||||
|
||||
@@ -671,12 +688,12 @@
|
||||
|
||||
%ifdef ENCRYPTION
|
||||
|
||||
global aes_encrypt
|
||||
global aes_ni(encrypt)
|
||||
%ifdef DLL_EXPORT
|
||||
export aes_encrypt
|
||||
export aes_ni(encrypt)
|
||||
%endif
|
||||
|
||||
section .data align=64
|
||||
section .data align=64 set_page
|
||||
align 64
|
||||
enc_tab:
|
||||
enc_vals u8
|
||||
@@ -684,40 +701,40 @@ enc_tab:
|
||||
enc_vals w8
|
||||
%endif
|
||||
|
||||
section .text align=16
|
||||
section .text align=16 set_page
|
||||
align 16
|
||||
|
||||
%ifdef _SEH_
|
||||
proc_frame aes_encrypt
|
||||
alloc_stack 7*8 ; 7 to align stack to 16 bytes
|
||||
save_reg rsi,4*8
|
||||
save_reg rdi,5*8
|
||||
save_reg rbx,1*8
|
||||
save_reg rbp,2*8
|
||||
save_reg r12,3*8
|
||||
proc_frame aes_ni(encrypt)
|
||||
alloc_stack 7*8 ; 7 to align stack to 16 bytes
|
||||
save_reg rsi,4*8
|
||||
save_reg rdi,5*8
|
||||
save_reg rbx,1*8
|
||||
save_reg rbp,2*8
|
||||
save_reg r12,3*8
|
||||
end_prologue
|
||||
mov rdi, rcx ; input pointer
|
||||
mov [rsp+0*8], rdx ; output pointer
|
||||
%else
|
||||
aes_encrypt:
|
||||
%ifdef __GNUC__
|
||||
sub rsp, 4*8 ; gnu/linux binary interface
|
||||
mov [rsp+0*8], rsi ; output pointer
|
||||
mov r8, rdx ; context
|
||||
%else
|
||||
sub rsp, 6*8 ; windows binary interface
|
||||
mov [rsp+4*8], rsi
|
||||
mov [rsp+5*8], rdi
|
||||
mov rdi, rcx ; input pointer
|
||||
mov [rsp+0*8], rdx ; output pointer
|
||||
%endif
|
||||
mov [rsp+1*8], rbx ; input pointer in rdi
|
||||
mov [rsp+2*8], rbp ; output pointer in [rsp]
|
||||
mov [rsp+3*8], r12 ; context in r8
|
||||
aes_ni(encrypt):
|
||||
%ifdef __GNUC__
|
||||
sub rsp, 4*8 ; gnu/linux binary interface
|
||||
mov [rsp+0*8], rsi ; output pointer
|
||||
mov r8, rdx ; context
|
||||
%else
|
||||
sub rsp, 6*8 ; windows binary interface
|
||||
mov [rsp+4*8], rsi
|
||||
mov [rsp+5*8], rdi
|
||||
mov rdi, rcx ; input pointer
|
||||
mov [rsp+0*8], rdx ; output pointer
|
||||
%endif
|
||||
mov [rsp+1*8], rbx ; input pointer in rdi
|
||||
mov [rsp+2*8], rbp ; output pointer in [rsp]
|
||||
mov [rsp+3*8], r12 ; context in r8
|
||||
%endif
|
||||
|
||||
movzx esi, byte [kptr+4*KS_LENGTH]
|
||||
lea tptr,[enc_tab wrt rip]
|
||||
lea tptr, [rel enc_tab]
|
||||
sub kptr, fofs
|
||||
|
||||
mov eax, [rdi+0*4]
|
||||
@@ -769,25 +786,25 @@ end_prologue
|
||||
add rsp, 4*8
|
||||
ret
|
||||
%else
|
||||
mov rsi, [rsp+4*8]
|
||||
mov rdi, [rsp+5*8]
|
||||
%ifdef _SEH_
|
||||
add rsp, 7*8
|
||||
ret
|
||||
endproc_frame
|
||||
%else
|
||||
add rsp, 6*8
|
||||
ret
|
||||
%endif
|
||||
mov rsi, [rsp+4*8]
|
||||
mov rdi, [rsp+5*8]
|
||||
%ifdef _SEH_
|
||||
add rsp, 7*8
|
||||
ret
|
||||
endproc_frame
|
||||
%else
|
||||
add rsp, 6*8
|
||||
ret
|
||||
%endif
|
||||
%endif
|
||||
|
||||
%endif
|
||||
|
||||
%ifdef DECRYPTION
|
||||
|
||||
global aes_decrypt
|
||||
global aes_ni(decrypt)
|
||||
%ifdef DLL_EXPORT
|
||||
export aes_decrypt
|
||||
export aes_ni(decrypt)
|
||||
%endif
|
||||
|
||||
section .data
|
||||
@@ -802,36 +819,36 @@ dec_tab:
|
||||
align 16
|
||||
|
||||
%ifdef _SEH_
|
||||
proc_frame aes_decrypt
|
||||
alloc_stack 7*8 ; 7 to align stack to 16 bytes
|
||||
save_reg rsi,4*8
|
||||
save_reg rdi,5*8
|
||||
save_reg rbx,1*8
|
||||
save_reg rbp,2*8
|
||||
save_reg r12,3*8
|
||||
proc_frame aes_ni(decrypt)
|
||||
alloc_stack 7*8 ; 7 to align stack to 16 bytes
|
||||
save_reg rsi,4*8
|
||||
save_reg rdi,5*8
|
||||
save_reg rbx,1*8
|
||||
save_reg rbp,2*8
|
||||
save_reg r12,3*8
|
||||
end_prologue
|
||||
mov rdi, rcx ; input pointer
|
||||
mov [rsp+0*8], rdx ; output pointer
|
||||
%else
|
||||
aes_decrypt:
|
||||
%ifdef __GNUC__
|
||||
sub rsp, 4*8 ; gnu/linux binary interface
|
||||
mov [rsp+0*8], rsi ; output pointer
|
||||
mov r8, rdx ; context
|
||||
%else
|
||||
sub rsp, 6*8 ; windows binary interface
|
||||
mov [rsp+4*8], rsi
|
||||
mov [rsp+5*8], rdi
|
||||
mov rdi, rcx ; input pointer
|
||||
mov [rsp+0*8], rdx ; output pointer
|
||||
%endif
|
||||
mov [rsp+1*8], rbx ; input pointer in rdi
|
||||
mov [rsp+2*8], rbp ; output pointer in [rsp]
|
||||
mov [rsp+3*8], r12 ; context in r8
|
||||
aes_ni(decrypt):
|
||||
%ifdef __GNUC__
|
||||
sub rsp, 4*8 ; gnu/linux binary interface
|
||||
mov [rsp+0*8], rsi ; output pointer
|
||||
mov r8, rdx ; context
|
||||
%else
|
||||
sub rsp, 6*8 ; windows binary interface
|
||||
mov [rsp+4*8], rsi
|
||||
mov [rsp+5*8], rdi
|
||||
mov rdi, rcx ; input pointer
|
||||
mov [rsp+0*8], rdx ; output pointer
|
||||
%endif
|
||||
mov [rsp+1*8], rbx ; input pointer in rdi
|
||||
mov [rsp+2*8], rbp ; output pointer in [rsp]
|
||||
mov [rsp+3*8], r12 ; context in r8
|
||||
%endif
|
||||
|
||||
movzx esi,byte[kptr+4*KS_LENGTH]
|
||||
lea tptr,[dec_tab wrt rip]
|
||||
movzx esi, byte[kptr+4*KS_LENGTH]
|
||||
lea tptr, [rel dec_tab]
|
||||
sub kptr, rofs
|
||||
|
||||
mov eax, [rdi+0*4]
|
||||
@@ -888,16 +905,16 @@ end_prologue
|
||||
add rsp, 4*8
|
||||
ret
|
||||
%else
|
||||
mov rsi, [rsp+4*8]
|
||||
mov rdi, [rsp+5*8]
|
||||
%ifdef _SEH_
|
||||
add rsp, 7*8
|
||||
ret
|
||||
endproc_frame
|
||||
%else
|
||||
add rsp, 6*8
|
||||
ret
|
||||
%endif
|
||||
mov rsi, [rsp+4*8]
|
||||
mov rdi, [rsp+5*8]
|
||||
%ifdef _SEH_
|
||||
add rsp, 7*8
|
||||
ret
|
||||
endproc_frame
|
||||
%else
|
||||
add rsp, 6*8
|
||||
ret
|
||||
%endif
|
||||
%endif
|
||||
|
||||
%endif
|
||||
|
||||
@@ -1,28 +1,21 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
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 Date: 20/12/2007
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
These subroutines implement multiple block AES modes for ECB, CBC, CFB,
|
||||
OFB and CTR encryption, The code provides support for the VIA Advanced
|
||||
@@ -34,6 +27,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "aesopt.h"
|
||||
|
||||
@@ -55,7 +49,7 @@ extern "C"
|
||||
|
||||
#define FAST_BUFFER_OPERATIONS
|
||||
|
||||
#define lp32(x) ((uint_32t*)(x))
|
||||
#define lp32(x) ((uint32_t*)(x))
|
||||
|
||||
#if defined( USE_VIA_ACE_IF_PRESENT )
|
||||
|
||||
@@ -72,13 +66,21 @@ aligned_array(unsigned long, dec_hybrid_table, 12, 16) = NEH_DEC_HYBRID_DATA;
|
||||
|
||||
/* NOTE: These control word macros must only be used after */
|
||||
/* a key has been set up because they depend on key size */
|
||||
/* See the VIA ACE documentation for key type information */
|
||||
/* and aes_via_ace.h for non-default NEH_KEY_TYPE values */
|
||||
|
||||
#ifndef NEH_KEY_TYPE
|
||||
# define NEH_KEY_TYPE NEH_HYBRID
|
||||
#endif
|
||||
|
||||
#if NEH_KEY_TYPE == NEH_LOAD
|
||||
#define kd_adr(c) ((uint_8t*)(c)->ks)
|
||||
#define kd_adr(c) ((uint8_t*)(c)->ks)
|
||||
#elif NEH_KEY_TYPE == NEH_GENERATE
|
||||
#define kd_adr(c) ((uint_8t*)(c)->ks + (c)->inf.b[0])
|
||||
#define kd_adr(c) ((uint8_t*)(c)->ks + (c)->inf.b[0])
|
||||
#elif NEH_KEY_TYPE == NEH_HYBRID
|
||||
#define kd_adr(c) ((uint8_t*)(c)->ks + ((c)->inf.b[0] == 160 ? 160 : 0))
|
||||
#else
|
||||
#define kd_adr(c) ((uint_8t*)(c)->ks + ((c)->inf.b[0] == 160 ? 160 : 0))
|
||||
#error no key type defined for VIA ACE
|
||||
#endif
|
||||
|
||||
#else
|
||||
@@ -105,25 +107,25 @@ aligned_array(unsigned long, dec_hybrid_table, 12, 16) = NEH_DEC_HYBRID_DATA;
|
||||
/* test the code for detecting and setting pointer alignment */
|
||||
|
||||
AES_RETURN aes_test_alignment_detection(unsigned int n) /* 4 <= n <= 16 */
|
||||
{ uint_8t p[16];
|
||||
uint_32t i, count_eq = 0, count_neq = 0;
|
||||
{ uint8_t p[16];
|
||||
uint32_t i, count_eq = 0, count_neq = 0;
|
||||
|
||||
if(n < 4 || n > 16)
|
||||
return EXIT_FAILURE;
|
||||
if(n < 4 || n > 16)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
for(i = 0; i < n; ++i)
|
||||
{
|
||||
uint_8t *qf = ALIGN_FLOOR(p + i, n),
|
||||
*qh = ALIGN_CEIL(p + i, n);
|
||||
for(i = 0; i < n; ++i)
|
||||
{
|
||||
uint8_t *qf = ALIGN_FLOOR(p + i, n),
|
||||
*qh = ALIGN_CEIL(p + i, n);
|
||||
|
||||
if(qh == qf)
|
||||
++count_eq;
|
||||
else if(qh == qf + n)
|
||||
++count_neq;
|
||||
else
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return (count_eq != 1 || count_neq != n - 1 ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
if(qh == qf)
|
||||
++count_eq;
|
||||
else if(qh == qf + n)
|
||||
++count_neq;
|
||||
else
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return (count_eq != 1 || count_neq != n - 1 ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
AES_RETURN aes_mode_reset(aes_encrypt_ctx ctx[1])
|
||||
@@ -134,7 +136,7 @@ AES_RETURN aes_mode_reset(aes_encrypt_ctx ctx[1])
|
||||
|
||||
AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, const aes_encrypt_ctx ctx[1])
|
||||
{ int nb = len >> 4;
|
||||
{ int nb = len >> AES_BLOCK_SIZE_P2;
|
||||
|
||||
if(len & (AES_BLOCK_SIZE - 1))
|
||||
return EXIT_FAILURE;
|
||||
@@ -142,7 +144,7 @@ AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
#if defined( USE_VIA_ACE_IF_PRESENT )
|
||||
|
||||
if(ctx->inf.b[1] == 0xff)
|
||||
{ uint_8t *ksp = (uint_8t*)(ctx->ks);
|
||||
{ uint8_t *ksp = (uint8_t*)(ctx->ks);
|
||||
via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192);
|
||||
|
||||
if(ALIGN_OFFSET( ctx, 16 ))
|
||||
@@ -153,8 +155,8 @@ AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
via_ecb_op5(ksp, cwd, ibuf, obuf, nb);
|
||||
}
|
||||
else
|
||||
{ aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
|
||||
uint_8t *ip, *op;
|
||||
{ aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
|
||||
uint8_t *ip, *op;
|
||||
|
||||
while(nb)
|
||||
{
|
||||
@@ -186,7 +188,7 @@ AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
while(nb--)
|
||||
{
|
||||
if(aes_encrypt(ibuf, obuf, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_FAILURE;
|
||||
ibuf += AES_BLOCK_SIZE;
|
||||
obuf += AES_BLOCK_SIZE;
|
||||
}
|
||||
@@ -196,7 +198,7 @@ AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
|
||||
AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, const aes_decrypt_ctx ctx[1])
|
||||
{ int nb = len >> 4;
|
||||
{ int nb = len >> AES_BLOCK_SIZE_P2;
|
||||
|
||||
if(len & (AES_BLOCK_SIZE - 1))
|
||||
return EXIT_FAILURE;
|
||||
@@ -204,7 +206,7 @@ AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
#if defined( USE_VIA_ACE_IF_PRESENT )
|
||||
|
||||
if(ctx->inf.b[1] == 0xff)
|
||||
{ uint_8t *ksp = kd_adr(ctx);
|
||||
{ uint8_t *ksp = kd_adr(ctx);
|
||||
via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192);
|
||||
|
||||
if(ALIGN_OFFSET( ctx, 16 ))
|
||||
@@ -215,8 +217,8 @@ AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
via_ecb_op5(ksp, cwd, ibuf, obuf, nb);
|
||||
}
|
||||
else
|
||||
{ aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
|
||||
uint_8t *ip, *op;
|
||||
{ aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
|
||||
uint8_t *ip, *op;
|
||||
|
||||
while(nb)
|
||||
{
|
||||
@@ -248,7 +250,7 @@ AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
while(nb--)
|
||||
{
|
||||
if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_FAILURE;
|
||||
ibuf += AES_BLOCK_SIZE;
|
||||
obuf += AES_BLOCK_SIZE;
|
||||
}
|
||||
@@ -258,7 +260,7 @@ AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
|
||||
AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, const aes_encrypt_ctx ctx[1])
|
||||
{ int nb = len >> 4;
|
||||
{ int nb = len >> AES_BLOCK_SIZE_P2;
|
||||
|
||||
if(len & (AES_BLOCK_SIZE - 1))
|
||||
return EXIT_FAILURE;
|
||||
@@ -266,8 +268,8 @@ AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
#if defined( USE_VIA_ACE_IF_PRESENT )
|
||||
|
||||
if(ctx->inf.b[1] == 0xff)
|
||||
{ uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv;
|
||||
aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);
|
||||
{ uint8_t *ksp = (uint8_t*)(ctx->ks), *ivp = iv;
|
||||
aligned_auto(uint8_t, liv, AES_BLOCK_SIZE, 16);
|
||||
via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192);
|
||||
|
||||
if(ALIGN_OFFSET( ctx, 16 ))
|
||||
@@ -284,8 +286,8 @@ AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
via_cbc_op7(ksp, cwd, ibuf, obuf, nb, ivp, ivp);
|
||||
}
|
||||
else
|
||||
{ aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
|
||||
uint_8t *ip, *op;
|
||||
{ aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
|
||||
uint8_t *ip, *op;
|
||||
|
||||
while(nb)
|
||||
{
|
||||
@@ -326,7 +328,7 @@ AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
lp32(iv)[2] ^= lp32(ibuf)[2];
|
||||
lp32(iv)[3] ^= lp32(ibuf)[3];
|
||||
if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_FAILURE;
|
||||
memcpy(obuf, iv, AES_BLOCK_SIZE);
|
||||
ibuf += AES_BLOCK_SIZE;
|
||||
obuf += AES_BLOCK_SIZE;
|
||||
@@ -344,7 +346,7 @@ AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
iv[12] ^= ibuf[12]; iv[13] ^= ibuf[13];
|
||||
iv[14] ^= ibuf[14]; iv[15] ^= ibuf[15];
|
||||
if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_FAILURE;
|
||||
memcpy(obuf, iv, AES_BLOCK_SIZE);
|
||||
ibuf += AES_BLOCK_SIZE;
|
||||
obuf += AES_BLOCK_SIZE;
|
||||
@@ -356,7 +358,7 @@ AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, const aes_decrypt_ctx ctx[1])
|
||||
{ unsigned char tmp[AES_BLOCK_SIZE];
|
||||
int nb = len >> 4;
|
||||
int nb = len >> AES_BLOCK_SIZE_P2;
|
||||
|
||||
if(len & (AES_BLOCK_SIZE - 1))
|
||||
return EXIT_FAILURE;
|
||||
@@ -364,8 +366,8 @@ AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
#if defined( USE_VIA_ACE_IF_PRESENT )
|
||||
|
||||
if(ctx->inf.b[1] == 0xff)
|
||||
{ uint_8t *ksp = kd_adr(ctx), *ivp = iv;
|
||||
aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);
|
||||
{ uint8_t *ksp = kd_adr(ctx), *ivp = iv;
|
||||
aligned_auto(uint8_t, liv, AES_BLOCK_SIZE, 16);
|
||||
via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192);
|
||||
|
||||
if(ALIGN_OFFSET( ctx, 16 ))
|
||||
@@ -382,8 +384,8 @@ AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
via_cbc_op6(ksp, cwd, ibuf, obuf, nb, ivp);
|
||||
}
|
||||
else
|
||||
{ aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
|
||||
uint_8t *ip, *op;
|
||||
{ aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
|
||||
uint8_t *ip, *op;
|
||||
|
||||
while(nb)
|
||||
{
|
||||
@@ -420,7 +422,7 @@ AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
{
|
||||
memcpy(tmp, ibuf, AES_BLOCK_SIZE);
|
||||
if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_FAILURE;
|
||||
lp32(obuf)[0] ^= lp32(iv)[0];
|
||||
lp32(obuf)[1] ^= lp32(iv)[1];
|
||||
lp32(obuf)[2] ^= lp32(iv)[2];
|
||||
@@ -435,7 +437,7 @@ AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
{
|
||||
memcpy(tmp, ibuf, AES_BLOCK_SIZE);
|
||||
if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_FAILURE;
|
||||
obuf[ 0] ^= iv[ 0]; obuf[ 1] ^= iv[ 1];
|
||||
obuf[ 2] ^= iv[ 2]; obuf[ 3] ^= iv[ 3];
|
||||
obuf[ 4] ^= iv[ 4]; obuf[ 5] ^= iv[ 5];
|
||||
@@ -467,14 +469,14 @@ AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
|
||||
}
|
||||
|
||||
if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */
|
||||
if((nb = (len - cnt) >> AES_BLOCK_SIZE_P2) != 0) /* process whole blocks */
|
||||
{
|
||||
#if defined( USE_VIA_ACE_IF_PRESENT )
|
||||
|
||||
if(ctx->inf.b[1] == 0xff)
|
||||
{ int m;
|
||||
uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv;
|
||||
aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);
|
||||
uint8_t *ksp = (uint8_t*)(ctx->ks), *ivp = iv;
|
||||
aligned_auto(uint8_t, liv, AES_BLOCK_SIZE, 16);
|
||||
via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192);
|
||||
|
||||
if(ALIGN_OFFSET( ctx, 16 ))
|
||||
@@ -494,8 +496,8 @@ AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
cnt += nb * AES_BLOCK_SIZE;
|
||||
}
|
||||
else /* input, output or both are unaligned */
|
||||
{ aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
|
||||
uint_8t *ip, *op;
|
||||
{ aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
|
||||
uint8_t *ip, *op;
|
||||
|
||||
while(nb)
|
||||
{
|
||||
@@ -528,7 +530,7 @@ AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
{
|
||||
assert(b_pos == 0);
|
||||
if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_FAILURE;
|
||||
lp32(obuf)[0] = lp32(iv)[0] ^= lp32(ibuf)[0];
|
||||
lp32(obuf)[1] = lp32(iv)[1] ^= lp32(ibuf)[1];
|
||||
lp32(obuf)[2] = lp32(iv)[2] ^= lp32(ibuf)[2];
|
||||
@@ -543,7 +545,7 @@ AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
{
|
||||
assert(b_pos == 0);
|
||||
if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_FAILURE;
|
||||
obuf[ 0] = iv[ 0] ^= ibuf[ 0]; obuf[ 1] = iv[ 1] ^= ibuf[ 1];
|
||||
obuf[ 2] = iv[ 2] ^= ibuf[ 2]; obuf[ 3] = iv[ 3] ^= ibuf[ 3];
|
||||
obuf[ 4] = iv[ 4] ^= ibuf[ 4]; obuf[ 5] = iv[ 5] ^= ibuf[ 5];
|
||||
@@ -562,7 +564,7 @@ AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
while(cnt < len)
|
||||
{
|
||||
if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_FAILURE;
|
||||
|
||||
while(cnt < len && b_pos < AES_BLOCK_SIZE)
|
||||
{
|
||||
@@ -573,7 +575,7 @@ AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
|
||||
}
|
||||
|
||||
ctx->inf.b[2] = (uint_8t)b_pos;
|
||||
ctx->inf.b[2] = (uint8_t)b_pos;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -582,7 +584,7 @@ AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
{ int cnt = 0, b_pos = (int)ctx->inf.b[2], nb;
|
||||
|
||||
if(b_pos) /* complete any partial block */
|
||||
{ uint_8t t;
|
||||
{ uint8_t t;
|
||||
|
||||
while(b_pos < AES_BLOCK_SIZE && cnt < len)
|
||||
{
|
||||
@@ -595,14 +597,14 @@ AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
|
||||
}
|
||||
|
||||
if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */
|
||||
if((nb = (len - cnt) >> AES_BLOCK_SIZE_P2) != 0) /* process whole blocks */
|
||||
{
|
||||
#if defined( USE_VIA_ACE_IF_PRESENT )
|
||||
|
||||
if(ctx->inf.b[1] == 0xff)
|
||||
{ int m;
|
||||
uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv;
|
||||
aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);
|
||||
uint8_t *ksp = (uint8_t*)(ctx->ks), *ivp = iv;
|
||||
aligned_auto(uint8_t, liv, AES_BLOCK_SIZE, 16);
|
||||
via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192);
|
||||
|
||||
if(ALIGN_OFFSET( ctx, 16 ))
|
||||
@@ -622,8 +624,8 @@ AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
cnt += nb * AES_BLOCK_SIZE;
|
||||
}
|
||||
else /* input, output or both are unaligned */
|
||||
{ aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
|
||||
uint_8t *ip, *op;
|
||||
{ aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
|
||||
uint8_t *ip, *op;
|
||||
|
||||
while(nb)
|
||||
{
|
||||
@@ -653,11 +655,11 @@ AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
# ifdef FAST_BUFFER_OPERATIONS
|
||||
if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) &&!ALIGN_OFFSET( iv, 4 ))
|
||||
while(cnt + AES_BLOCK_SIZE <= len)
|
||||
{ uint_32t t;
|
||||
{ uint32_t t;
|
||||
|
||||
assert(b_pos == 0);
|
||||
if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_FAILURE;
|
||||
t = lp32(ibuf)[0], lp32(obuf)[0] = t ^ lp32(iv)[0], lp32(iv)[0] = t;
|
||||
t = lp32(ibuf)[1], lp32(obuf)[1] = t ^ lp32(iv)[1], lp32(iv)[1] = t;
|
||||
t = lp32(ibuf)[2], lp32(obuf)[2] = t ^ lp32(iv)[2], lp32(iv)[2] = t;
|
||||
@@ -669,11 +671,11 @@ AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
else
|
||||
# endif
|
||||
while(cnt + AES_BLOCK_SIZE <= len)
|
||||
{ uint_8t t;
|
||||
{ uint8_t t;
|
||||
|
||||
assert(b_pos == 0);
|
||||
if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_FAILURE;
|
||||
t = ibuf[ 0], obuf[ 0] = t ^ iv[ 0], iv[ 0] = t;
|
||||
t = ibuf[ 1], obuf[ 1] = t ^ iv[ 1], iv[ 1] = t;
|
||||
t = ibuf[ 2], obuf[ 2] = t ^ iv[ 2], iv[ 2] = t;
|
||||
@@ -698,10 +700,10 @@ AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
}
|
||||
|
||||
while(cnt < len)
|
||||
{ uint_8t t;
|
||||
{ uint8_t t;
|
||||
|
||||
if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_FAILURE;
|
||||
|
||||
while(cnt < len && b_pos < AES_BLOCK_SIZE)
|
||||
{
|
||||
@@ -714,7 +716,7 @@ AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
|
||||
}
|
||||
|
||||
ctx->inf.b[2] = (uint_8t)b_pos;
|
||||
ctx->inf.b[2] = (uint8_t)b_pos;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -733,14 +735,14 @@ AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
|
||||
}
|
||||
|
||||
if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */
|
||||
if((nb = (len - cnt) >> AES_BLOCK_SIZE_P2) != 0) /* process whole blocks */
|
||||
{
|
||||
#if defined( USE_VIA_ACE_IF_PRESENT )
|
||||
|
||||
if(ctx->inf.b[1] == 0xff)
|
||||
{ int m;
|
||||
uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv;
|
||||
aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);
|
||||
uint8_t *ksp = (uint8_t*)(ctx->ks), *ivp = iv;
|
||||
aligned_auto(uint8_t, liv, AES_BLOCK_SIZE, 16);
|
||||
via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192);
|
||||
|
||||
if(ALIGN_OFFSET( ctx, 16 ))
|
||||
@@ -760,8 +762,8 @@ AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
cnt += nb * AES_BLOCK_SIZE;
|
||||
}
|
||||
else /* input, output or both are unaligned */
|
||||
{ aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
|
||||
uint_8t *ip, *op;
|
||||
{ aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
|
||||
uint8_t *ip, *op;
|
||||
|
||||
while(nb)
|
||||
{
|
||||
@@ -794,7 +796,7 @@ AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
{
|
||||
assert(b_pos == 0);
|
||||
if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_FAILURE;
|
||||
lp32(obuf)[0] = lp32(iv)[0] ^ lp32(ibuf)[0];
|
||||
lp32(obuf)[1] = lp32(iv)[1] ^ lp32(ibuf)[1];
|
||||
lp32(obuf)[2] = lp32(iv)[2] ^ lp32(ibuf)[2];
|
||||
@@ -809,7 +811,7 @@ AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
{
|
||||
assert(b_pos == 0);
|
||||
if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_FAILURE;
|
||||
obuf[ 0] = iv[ 0] ^ ibuf[ 0]; obuf[ 1] = iv[ 1] ^ ibuf[ 1];
|
||||
obuf[ 2] = iv[ 2] ^ ibuf[ 2]; obuf[ 3] = iv[ 3] ^ ibuf[ 3];
|
||||
obuf[ 4] = iv[ 4] ^ ibuf[ 4]; obuf[ 5] = iv[ 5] ^ ibuf[ 5];
|
||||
@@ -828,7 +830,7 @@ AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
while(cnt < len)
|
||||
{
|
||||
if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_FAILURE;
|
||||
|
||||
while(cnt < len && b_pos < AES_BLOCK_SIZE)
|
||||
{
|
||||
@@ -839,7 +841,7 @@ AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
|
||||
}
|
||||
|
||||
ctx->inf.b[2] = (uint_8t)b_pos;
|
||||
ctx->inf.b[2] = (uint8_t)b_pos;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -851,18 +853,18 @@ AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int i, blen, b_pos = (int)(ctx->inf.b[2]);
|
||||
|
||||
#if defined( USE_VIA_ACE_IF_PRESENT )
|
||||
aligned_auto(uint_8t, buf, BFR_LENGTH, 16);
|
||||
aligned_auto(uint8_t, buf, BFR_LENGTH, 16);
|
||||
if(ctx->inf.b[1] == 0xff && ALIGN_OFFSET( ctx, 16 ))
|
||||
return EXIT_FAILURE;
|
||||
#else
|
||||
uint_8t buf[BFR_LENGTH];
|
||||
uint8_t buf[BFR_LENGTH];
|
||||
#endif
|
||||
|
||||
if(b_pos)
|
||||
{
|
||||
memcpy(buf, cbuf, AES_BLOCK_SIZE);
|
||||
if(aes_ecb_encrypt(buf, buf, AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_FAILURE;
|
||||
|
||||
while(b_pos < AES_BLOCK_SIZE && len)
|
||||
{
|
||||
@@ -878,7 +880,7 @@ AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
{
|
||||
blen = (len > BFR_LENGTH ? BFR_LENGTH : len), len -= blen;
|
||||
|
||||
for(i = 0, ip = buf; i < (blen >> 4); ++i)
|
||||
for(i = 0, ip = buf; i < (blen >> AES_BLOCK_SIZE_P2); ++i)
|
||||
{
|
||||
memcpy(ip, cbuf, AES_BLOCK_SIZE);
|
||||
ctr_inc(cbuf);
|
||||
@@ -897,7 +899,7 @@ AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
else
|
||||
#endif
|
||||
if(aes_ecb_encrypt(buf, buf, i * AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_FAILURE;
|
||||
|
||||
i = 0; ip = buf;
|
||||
# ifdef FAST_BUFFER_OPERATIONS
|
||||
@@ -935,7 +937,7 @@ AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
*obuf++ = *ibuf++ ^ ip[b_pos++];
|
||||
}
|
||||
|
||||
ctx->inf.b[2] = (uint_8t)b_pos;
|
||||
ctx->inf.b[2] = (uint8_t)b_pos;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +1,20 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
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 Date: 20/12/20077
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#ifndef AES_VIA_ACE_H
|
||||
@@ -172,7 +164,8 @@ INLINE int has_cpuid(void)
|
||||
INLINE int is_via_cpu(void)
|
||||
{ char ret_value;
|
||||
__asm
|
||||
{ xor eax,eax /* use CPUID to get vendor */
|
||||
{ push ebx
|
||||
xor eax,eax /* use CPUID to get vendor */
|
||||
cpuid /* identity string */
|
||||
xor eax,eax /* is it "CentaurHauls" ? */
|
||||
sub ebx,0x746e6543 /* 'Cent' */
|
||||
@@ -186,6 +179,7 @@ INLINE int is_via_cpu(void)
|
||||
or dl,al /* & store result in flags */
|
||||
mov [via_flags],dl /* set VIA detected flag */
|
||||
mov ret_value,al /* able to change it */
|
||||
pop ebx
|
||||
}
|
||||
return (int)ret_value;
|
||||
}
|
||||
@@ -193,8 +187,7 @@ INLINE int is_via_cpu(void)
|
||||
INLINE int read_via_flags(void)
|
||||
{ char ret_value = 0;
|
||||
__asm
|
||||
{
|
||||
mov eax,0xC0000000 /* Centaur extended CPUID */
|
||||
{ mov eax,0xC0000000 /* Centaur extended CPUID */
|
||||
cpuid
|
||||
mov edx,0xc0000001 /* >= 0xc0000001 if support */
|
||||
cmp eax,edx /* for VIA extended feature */
|
||||
@@ -213,8 +206,7 @@ no_rng:
|
||||
INLINE unsigned int via_rng_in(void *buf)
|
||||
{ char ret_value = 0x1f;
|
||||
__asm
|
||||
{
|
||||
push edi
|
||||
{ push edi
|
||||
mov edi,buf /* input buffer address */
|
||||
xor edx,edx /* try to fetch 8 bytes */
|
||||
NEH_RNG /* do RNG read operation */
|
||||
@@ -227,7 +219,7 @@ INLINE unsigned int via_rng_in(void *buf)
|
||||
INLINE void via_ecb_op5(
|
||||
const void *k, const void *c, const void *s, void *d, int l)
|
||||
{ __asm
|
||||
{
|
||||
{ push ebx
|
||||
NEH_REKEY
|
||||
mov ebx, (k)
|
||||
mov edx, (c)
|
||||
@@ -235,13 +227,14 @@ INLINE void via_ecb_op5(
|
||||
mov edi, (d)
|
||||
mov ecx, (l)
|
||||
NEH_ECB
|
||||
pop ebx
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void via_cbc_op6(
|
||||
const void *k, const void *c, const void *s, void *d, int l, void *v)
|
||||
{ __asm
|
||||
{
|
||||
{ push ebx
|
||||
NEH_REKEY
|
||||
mov ebx, (k)
|
||||
mov edx, (c)
|
||||
@@ -250,13 +243,14 @@ INLINE void via_cbc_op6(
|
||||
mov ecx, (l)
|
||||
mov eax, (v)
|
||||
NEH_CBC
|
||||
pop ebx
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void via_cbc_op7(
|
||||
const void *k, const void *c, const void *s, void *d, int l, void *v, void *w)
|
||||
{ __asm
|
||||
{
|
||||
{ push ebx
|
||||
NEH_REKEY
|
||||
mov ebx, (k)
|
||||
mov edx, (c)
|
||||
@@ -271,13 +265,14 @@ INLINE void via_cbc_op7(
|
||||
movsd
|
||||
movsd
|
||||
movsd
|
||||
pop ebx
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void via_cfb_op6(
|
||||
const void *k, const void *c, const void *s, void *d, int l, void *v)
|
||||
{ __asm
|
||||
{
|
||||
{ push ebx
|
||||
NEH_REKEY
|
||||
mov ebx, (k)
|
||||
mov edx, (c)
|
||||
@@ -286,13 +281,14 @@ INLINE void via_cfb_op6(
|
||||
mov ecx, (l)
|
||||
mov eax, (v)
|
||||
NEH_CFB
|
||||
pop ebx
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void via_cfb_op7(
|
||||
const void *k, const void *c, const void *s, void *d, int l, void *v, void *w)
|
||||
{ __asm
|
||||
{
|
||||
{ push ebx
|
||||
NEH_REKEY
|
||||
mov ebx, (k)
|
||||
mov edx, (c)
|
||||
@@ -307,13 +303,14 @@ INLINE void via_cfb_op7(
|
||||
movsd
|
||||
movsd
|
||||
movsd
|
||||
pop ebx
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void via_ofb_op6(
|
||||
const void *k, const void *c, const void *s, void *d, int l, void *v)
|
||||
{ __asm
|
||||
{
|
||||
{ push ebx
|
||||
NEH_REKEY
|
||||
mov ebx, (k)
|
||||
mov edx, (c)
|
||||
@@ -322,6 +319,7 @@ INLINE void via_ofb_op6(
|
||||
mov ecx, (l)
|
||||
mov eax, (v)
|
||||
NEH_OFB
|
||||
pop ebx
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,6 +350,10 @@ INLINE int has_cpuid(void)
|
||||
|
||||
INLINE int is_via_cpu(void)
|
||||
{ int val;
|
||||
asm("pushl %eax\n\t");
|
||||
asm("pushl %ebx\n\t");
|
||||
asm("pushl %ecx\n\t");
|
||||
asm("pushl %edx\n\t");
|
||||
asm("xorl %eax,%eax\n\t");
|
||||
asm("cpuid\n\t");
|
||||
asm("xorl %eax,%eax\n\t");
|
||||
@@ -362,6 +364,10 @@ INLINE int is_via_cpu(void)
|
||||
asm("subl $0x736c7561,%ecx\n\t");
|
||||
asm("orl %ecx,%eax\n\t");
|
||||
asm("movl %%eax,%0\n\t" : "=m" (val));
|
||||
asm("popl %edx\n\t");
|
||||
asm("popl %ecx\n\t");
|
||||
asm("popl %ebx\n\t");
|
||||
asm("popl %eax\n\t");
|
||||
val = (val ? 0 : 1);
|
||||
via_flags = (val | NEH_CPU_READ);
|
||||
return val;
|
||||
@@ -399,6 +405,7 @@ INLINE int via_rng_in(void *buf)
|
||||
INLINE volatile void via_ecb_op5(
|
||||
const void *k, const void *c, const void *s, void *d, int l)
|
||||
{
|
||||
asm("pushl %ebx\n\t");
|
||||
NEH_REKEY;
|
||||
asm("movl %0, %%ebx\n\t" : : "m" (k));
|
||||
asm("movl %0, %%edx\n\t" : : "m" (c));
|
||||
@@ -406,11 +413,13 @@ INLINE volatile void via_ecb_op5(
|
||||
asm("movl %0, %%edi\n\t" : : "m" (d));
|
||||
asm("movl %0, %%ecx\n\t" : : "m" (l));
|
||||
NEH_ECB;
|
||||
asm("popl %ebx\n\t");
|
||||
}
|
||||
|
||||
INLINE volatile void via_cbc_op6(
|
||||
const void *k, const void *c, const void *s, void *d, int l, void *v)
|
||||
{
|
||||
asm("pushl %ebx\n\t");
|
||||
NEH_REKEY;
|
||||
asm("movl %0, %%ebx\n\t" : : "m" (k));
|
||||
asm("movl %0, %%edx\n\t" : : "m" (c));
|
||||
@@ -419,11 +428,13 @@ INLINE volatile void via_cbc_op6(
|
||||
asm("movl %0, %%ecx\n\t" : : "m" (l));
|
||||
asm("movl %0, %%eax\n\t" : : "m" (v));
|
||||
NEH_CBC;
|
||||
asm("popl %ebx\n\t");
|
||||
}
|
||||
|
||||
INLINE volatile void via_cbc_op7(
|
||||
const void *k, const void *c, const void *s, void *d, int l, void *v, void *w)
|
||||
{
|
||||
asm("pushl %ebx\n\t");
|
||||
NEH_REKEY;
|
||||
asm("movl %0, %%ebx\n\t" : : "m" (k));
|
||||
asm("movl %0, %%edx\n\t" : : "m" (c));
|
||||
@@ -435,11 +446,13 @@ INLINE volatile void via_cbc_op7(
|
||||
asm("movl %eax,%esi\n\t");
|
||||
asm("movl %0, %%edi\n\t" : : "m" (w));
|
||||
asm("movsl; movsl; movsl; movsl\n\t");
|
||||
asm("popl %ebx\n\t");
|
||||
}
|
||||
|
||||
INLINE volatile void via_cfb_op6(
|
||||
const void *k, const void *c, const void *s, void *d, int l, void *v)
|
||||
{
|
||||
asm("pushl %ebx\n\t");
|
||||
NEH_REKEY;
|
||||
asm("movl %0, %%ebx\n\t" : : "m" (k));
|
||||
asm("movl %0, %%edx\n\t" : : "m" (c));
|
||||
@@ -448,11 +461,13 @@ INLINE volatile void via_cfb_op6(
|
||||
asm("movl %0, %%ecx\n\t" : : "m" (l));
|
||||
asm("movl %0, %%eax\n\t" : : "m" (v));
|
||||
NEH_CFB;
|
||||
asm("popl %ebx\n\t");
|
||||
}
|
||||
|
||||
INLINE volatile void via_cfb_op7(
|
||||
const void *k, const void *c, const void *s, void *d, int l, void *v, void *w)
|
||||
{
|
||||
asm("pushl %ebx\n\t");
|
||||
NEH_REKEY;
|
||||
asm("movl %0, %%ebx\n\t" : : "m" (k));
|
||||
asm("movl %0, %%edx\n\t" : : "m" (c));
|
||||
@@ -464,11 +479,13 @@ INLINE volatile void via_cfb_op7(
|
||||
asm("movl %eax,%esi\n\t");
|
||||
asm("movl %0, %%edi\n\t" : : "m" (w));
|
||||
asm("movsl; movsl; movsl; movsl\n\t");
|
||||
asm("popl %ebx\n\t");
|
||||
}
|
||||
|
||||
INLINE volatile void via_ofb_op6(
|
||||
const void *k, const void *c, const void *s, void *d, int l, void *v)
|
||||
{
|
||||
asm("pushl %ebx\n\t");
|
||||
NEH_REKEY;
|
||||
asm("movl %0, %%ebx\n\t" : : "m" (k));
|
||||
asm("movl %0, %%edx\n\t" : : "m" (c));
|
||||
@@ -477,6 +494,7 @@ INLINE volatile void via_ofb_op6(
|
||||
asm("movl %0, %%ecx\n\t" : : "m" (l));
|
||||
asm("movl %0, %%eax\n\t" : : "m" (v));
|
||||
NEH_OFB;
|
||||
asm("popl %ebx\n\t");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
@@ -1,26 +1,19 @@
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
;
|
||||
; LICENSE TERMS
|
||||
; Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
;
|
||||
; The redistribution and use of this software (with or without changes)
|
||||
; is allowed without the payment of fees or royalties provided that:
|
||||
;
|
||||
; 1. source code distributions include the above copyright notice, this
|
||||
; list of conditions and the following disclaimer;
|
||||
; source code distributions include the above copyright notice, this
|
||||
; list of conditions and the following disclaimer;
|
||||
;
|
||||
; 2. binary distributions include the above copyright notice, this list
|
||||
; of conditions and the following disclaimer in their documentation;
|
||||
;
|
||||
; 3. the name of the copyright holder is not used to endorse products
|
||||
; built using this software without specific written permission.
|
||||
;
|
||||
; DISCLAIMER
|
||||
; binary distributions include the above copyright notice, this list
|
||||
; of conditions and the following disclaimer in their documentation.
|
||||
;
|
||||
; 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.
|
||||
; in respect of its operation, including, but not limited to, correctness
|
||||
; and fitness for purpose.
|
||||
; ---------------------------------------------------------------------------
|
||||
; Issue 13/08/2008
|
||||
;
|
||||
@@ -67,7 +60,15 @@
|
||||
;
|
||||
; where <NNN> is 128, 102 or 256. In the last two calls the length can be in
|
||||
; either bits or bytes.
|
||||
;
|
||||
|
||||
; Use of this assembler code in Windows kernel mode requires memory paging
|
||||
; to be disabled
|
||||
%ifdef NO_PAGING
|
||||
%define set_page nopage
|
||||
%else
|
||||
%define set_page
|
||||
%endif
|
||||
|
||||
; Comment in/out the following lines to obtain the desired subroutines. These
|
||||
; selections MUST match those in the C header file aes.h
|
||||
|
||||
@@ -133,6 +134,8 @@ stk_spc equ 20 ; stack space
|
||||
|
||||
; End of user defines
|
||||
|
||||
section .text align=32 set_page
|
||||
|
||||
%ifdef AES_VAR
|
||||
%ifndef AES_128
|
||||
%define AES_128
|
||||
@@ -353,8 +356,6 @@ stk_spc equ 20 ; stack space
|
||||
|
||||
%endmacro
|
||||
|
||||
section .text align=32
|
||||
|
||||
; AES Encryption Subroutine
|
||||
|
||||
align 32
|
||||
@@ -564,8 +565,6 @@ stk_spc equ 20 ; stack space
|
||||
|
||||
%endmacro
|
||||
|
||||
section .text
|
||||
|
||||
; AES Decryption Subroutine
|
||||
|
||||
align 32
|
||||
|
||||
@@ -1,28 +1,21 @@
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
;
|
||||
; LICENSE TERMS
|
||||
; Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
;
|
||||
; The redistribution and use of this software (with or without changes)
|
||||
; is allowed without the payment of fees or royalties provided that:
|
||||
;
|
||||
; 1. source code distributions include the above copyright notice, this
|
||||
; list of conditions and the following disclaimer;
|
||||
; source code distributions include the above copyright notice, this
|
||||
; list of conditions and the following disclaimer;
|
||||
;
|
||||
; 2. binary distributions include the above copyright notice, this list
|
||||
; of conditions and the following disclaimer in their documentation;
|
||||
;
|
||||
; 3. the name of the copyright holder is not used to endorse products
|
||||
; built using this software without specific written permission.
|
||||
;
|
||||
; DISCLAIMER
|
||||
; binary distributions include the above copyright notice, this list
|
||||
; of conditions and the following disclaimer in their documentation.
|
||||
;
|
||||
; 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.
|
||||
; in respect of its operation, including, but not limited to, correctness
|
||||
; and fitness for purpose.
|
||||
; ---------------------------------------------------------------------------
|
||||
; Issue 13/08/2008
|
||||
; Issue Date: 20/11/2013
|
||||
;
|
||||
; This code requires either ASM_X86_V2 or ASM_X86_V2C to be set in aesopt.h
|
||||
; and the same define to be set here as well. If AES_V2C is set this file
|
||||
@@ -79,6 +72,14 @@
|
||||
; where <NNN> is 128, 102 or 256. In the last two calls the length can be in
|
||||
; either bits or bytes.
|
||||
|
||||
; Use of this assembler code in Windows kernel mode requires memory paging
|
||||
; to be disabled
|
||||
%ifdef NO_PAGING
|
||||
%define set_page nopage
|
||||
%else
|
||||
%define set_page
|
||||
%endif
|
||||
|
||||
; The DLL interface must use the _stdcall convention in which the number
|
||||
; of bytes of parameter space is added after an @ to the sutine's name.
|
||||
; We must also remove our parameters from the stack before return (see
|
||||
@@ -145,6 +146,8 @@
|
||||
;
|
||||
; End of user defines
|
||||
|
||||
section .text align=32 set_page
|
||||
|
||||
%ifdef AES_VAR
|
||||
%ifndef AES_128
|
||||
%define AES_128
|
||||
@@ -411,9 +414,8 @@ stk_spc equ 16 ; stack space
|
||||
|
||||
%define ENCRYPTION_TABLE
|
||||
|
||||
%ifdef REDUCE_CODE_SIZE
|
||||
%macro _enc_round 0
|
||||
|
||||
enc_round:
|
||||
add ebp,16
|
||||
mov esi,[ebp+8]
|
||||
mov edi,[ebp+12]
|
||||
@@ -425,24 +427,19 @@ enc_round:
|
||||
mov edx,edi
|
||||
xor eax,[ebp]
|
||||
xor ebx,[ebp+4]
|
||||
ret
|
||||
|
||||
%endmacro
|
||||
|
||||
%ifdef REDUCE_CODE_SIZE
|
||||
|
||||
enc_round:
|
||||
_enc_round
|
||||
ret
|
||||
|
||||
%else
|
||||
|
||||
%macro enc_round 0
|
||||
|
||||
add ebp,16
|
||||
mov esi,[ebp+8]
|
||||
mov edi,[ebp+12]
|
||||
push ebp
|
||||
rnd_fun nr_xor, nr_mov
|
||||
mov eax,ebp
|
||||
pop ebp
|
||||
mov ecx,esi
|
||||
mov edx,edi
|
||||
xor eax,[ebp]
|
||||
xor ebx,[ebp+4]
|
||||
|
||||
_enc_round
|
||||
%endmacro
|
||||
|
||||
%endif
|
||||
@@ -461,10 +458,7 @@ enc_round:
|
||||
|
||||
%endmacro
|
||||
|
||||
section .text align=32
|
||||
|
||||
; AES Encryption Subroutine
|
||||
|
||||
align 32
|
||||
do_name _aes_encrypt,12
|
||||
push ebp
|
||||
@@ -789,51 +783,6 @@ enc_round:
|
||||
|
||||
%endif
|
||||
|
||||
%ifdef ENCRYPTION_TABLE
|
||||
|
||||
; S-box data - 256 entries
|
||||
|
||||
section .data align=32
|
||||
align 32
|
||||
|
||||
%define u8(x) 0, x, x, f3(x), f2(x), x, x, f3(x)
|
||||
|
||||
enc_tab:
|
||||
db u8(0x63),u8(0x7c),u8(0x77),u8(0x7b),u8(0xf2),u8(0x6b),u8(0x6f),u8(0xc5)
|
||||
db u8(0x30),u8(0x01),u8(0x67),u8(0x2b),u8(0xfe),u8(0xd7),u8(0xab),u8(0x76)
|
||||
db u8(0xca),u8(0x82),u8(0xc9),u8(0x7d),u8(0xfa),u8(0x59),u8(0x47),u8(0xf0)
|
||||
db u8(0xad),u8(0xd4),u8(0xa2),u8(0xaf),u8(0x9c),u8(0xa4),u8(0x72),u8(0xc0)
|
||||
db u8(0xb7),u8(0xfd),u8(0x93),u8(0x26),u8(0x36),u8(0x3f),u8(0xf7),u8(0xcc)
|
||||
db u8(0x34),u8(0xa5),u8(0xe5),u8(0xf1),u8(0x71),u8(0xd8),u8(0x31),u8(0x15)
|
||||
db u8(0x04),u8(0xc7),u8(0x23),u8(0xc3),u8(0x18),u8(0x96),u8(0x05),u8(0x9a)
|
||||
db u8(0x07),u8(0x12),u8(0x80),u8(0xe2),u8(0xeb),u8(0x27),u8(0xb2),u8(0x75)
|
||||
db u8(0x09),u8(0x83),u8(0x2c),u8(0x1a),u8(0x1b),u8(0x6e),u8(0x5a),u8(0xa0)
|
||||
db u8(0x52),u8(0x3b),u8(0xd6),u8(0xb3),u8(0x29),u8(0xe3),u8(0x2f),u8(0x84)
|
||||
db u8(0x53),u8(0xd1),u8(0x00),u8(0xed),u8(0x20),u8(0xfc),u8(0xb1),u8(0x5b)
|
||||
db u8(0x6a),u8(0xcb),u8(0xbe),u8(0x39),u8(0x4a),u8(0x4c),u8(0x58),u8(0xcf)
|
||||
db u8(0xd0),u8(0xef),u8(0xaa),u8(0xfb),u8(0x43),u8(0x4d),u8(0x33),u8(0x85)
|
||||
db u8(0x45),u8(0xf9),u8(0x02),u8(0x7f),u8(0x50),u8(0x3c),u8(0x9f),u8(0xa8)
|
||||
db u8(0x51),u8(0xa3),u8(0x40),u8(0x8f),u8(0x92),u8(0x9d),u8(0x38),u8(0xf5)
|
||||
db u8(0xbc),u8(0xb6),u8(0xda),u8(0x21),u8(0x10),u8(0xff),u8(0xf3),u8(0xd2)
|
||||
db u8(0xcd),u8(0x0c),u8(0x13),u8(0xec),u8(0x5f),u8(0x97),u8(0x44),u8(0x17)
|
||||
db u8(0xc4),u8(0xa7),u8(0x7e),u8(0x3d),u8(0x64),u8(0x5d),u8(0x19),u8(0x73)
|
||||
db u8(0x60),u8(0x81),u8(0x4f),u8(0xdc),u8(0x22),u8(0x2a),u8(0x90),u8(0x88)
|
||||
db u8(0x46),u8(0xee),u8(0xb8),u8(0x14),u8(0xde),u8(0x5e),u8(0x0b),u8(0xdb)
|
||||
db u8(0xe0),u8(0x32),u8(0x3a),u8(0x0a),u8(0x49),u8(0x06),u8(0x24),u8(0x5c)
|
||||
db u8(0xc2),u8(0xd3),u8(0xac),u8(0x62),u8(0x91),u8(0x95),u8(0xe4),u8(0x79)
|
||||
db u8(0xe7),u8(0xc8),u8(0x37),u8(0x6d),u8(0x8d),u8(0xd5),u8(0x4e),u8(0xa9)
|
||||
db u8(0x6c),u8(0x56),u8(0xf4),u8(0xea),u8(0x65),u8(0x7a),u8(0xae),u8(0x08)
|
||||
db u8(0xba),u8(0x78),u8(0x25),u8(0x2e),u8(0x1c),u8(0xa6),u8(0xb4),u8(0xc6)
|
||||
db u8(0xe8),u8(0xdd),u8(0x74),u8(0x1f),u8(0x4b),u8(0xbd),u8(0x8b),u8(0x8a)
|
||||
db u8(0x70),u8(0x3e),u8(0xb5),u8(0x66),u8(0x48),u8(0x03),u8(0xf6),u8(0x0e)
|
||||
db u8(0x61),u8(0x35),u8(0x57),u8(0xb9),u8(0x86),u8(0xc1),u8(0x1d),u8(0x9e)
|
||||
db u8(0xe1),u8(0xf8),u8(0x98),u8(0x11),u8(0x69),u8(0xd9),u8(0x8e),u8(0x94)
|
||||
db u8(0x9b),u8(0x1e),u8(0x87),u8(0xe9),u8(0xce),u8(0x55),u8(0x28),u8(0xdf)
|
||||
db u8(0x8c),u8(0xa1),u8(0x89),u8(0x0d),u8(0xbf),u8(0xe6),u8(0x42),u8(0x68)
|
||||
db u8(0x41),u8(0x99),u8(0x2d),u8(0x0f),u8(0xb0),u8(0x54),u8(0xbb),u8(0x16)
|
||||
|
||||
%endif
|
||||
|
||||
%ifdef DECRYPTION
|
||||
|
||||
%define DECRYPTION_TABLE
|
||||
@@ -903,9 +852,8 @@ enc_tab:
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%ifdef REDUCE_CODE_SIZE
|
||||
%macro _dec_round 0
|
||||
|
||||
dec_round:
|
||||
%ifdef AES_REV_DKS
|
||||
add ebp,16
|
||||
%else
|
||||
@@ -921,28 +869,20 @@ dec_round:
|
||||
mov edx,edi
|
||||
xor eax,[ebp]
|
||||
xor ebx,[ebp+4]
|
||||
ret
|
||||
|
||||
%endmacro
|
||||
|
||||
%ifdef REDUCE_CODE_SIZE
|
||||
|
||||
align 32
|
||||
dec_round:
|
||||
_dec_round
|
||||
ret
|
||||
|
||||
%else
|
||||
|
||||
%macro dec_round 0
|
||||
|
||||
%ifdef AES_REV_DKS
|
||||
add ebp,16
|
||||
%else
|
||||
sub ebp,16
|
||||
%endif
|
||||
mov esi,[ebp+8]
|
||||
mov edi,[ebp+12]
|
||||
push ebp
|
||||
irn_fun ni_xor, ni_mov
|
||||
mov ebx,ebp
|
||||
pop ebp
|
||||
mov ecx,esi
|
||||
mov edx,edi
|
||||
xor eax,[ebp]
|
||||
xor ebx,[ebp+4]
|
||||
|
||||
_dec_round
|
||||
%endmacro
|
||||
|
||||
%endif
|
||||
@@ -965,10 +905,7 @@ dec_round:
|
||||
|
||||
%endmacro
|
||||
|
||||
section .text
|
||||
|
||||
; AES Decryption Subroutine
|
||||
|
||||
align 32
|
||||
do_name _aes_decrypt,12
|
||||
push ebp
|
||||
@@ -1368,15 +1305,56 @@ dec_end:
|
||||
|
||||
%endif
|
||||
|
||||
%endif
|
||||
|
||||
section .data align=32 set_page
|
||||
|
||||
%ifdef ENCRYPTION_TABLE
|
||||
|
||||
; S-box data - 256 entries
|
||||
|
||||
%define u8(x) 0, x, x, f3(x), f2(x), x, x, f3(x)
|
||||
|
||||
enc_tab:
|
||||
db u8(0x63),u8(0x7c),u8(0x77),u8(0x7b),u8(0xf2),u8(0x6b),u8(0x6f),u8(0xc5)
|
||||
db u8(0x30),u8(0x01),u8(0x67),u8(0x2b),u8(0xfe),u8(0xd7),u8(0xab),u8(0x76)
|
||||
db u8(0xca),u8(0x82),u8(0xc9),u8(0x7d),u8(0xfa),u8(0x59),u8(0x47),u8(0xf0)
|
||||
db u8(0xad),u8(0xd4),u8(0xa2),u8(0xaf),u8(0x9c),u8(0xa4),u8(0x72),u8(0xc0)
|
||||
db u8(0xb7),u8(0xfd),u8(0x93),u8(0x26),u8(0x36),u8(0x3f),u8(0xf7),u8(0xcc)
|
||||
db u8(0x34),u8(0xa5),u8(0xe5),u8(0xf1),u8(0x71),u8(0xd8),u8(0x31),u8(0x15)
|
||||
db u8(0x04),u8(0xc7),u8(0x23),u8(0xc3),u8(0x18),u8(0x96),u8(0x05),u8(0x9a)
|
||||
db u8(0x07),u8(0x12),u8(0x80),u8(0xe2),u8(0xeb),u8(0x27),u8(0xb2),u8(0x75)
|
||||
db u8(0x09),u8(0x83),u8(0x2c),u8(0x1a),u8(0x1b),u8(0x6e),u8(0x5a),u8(0xa0)
|
||||
db u8(0x52),u8(0x3b),u8(0xd6),u8(0xb3),u8(0x29),u8(0xe3),u8(0x2f),u8(0x84)
|
||||
db u8(0x53),u8(0xd1),u8(0x00),u8(0xed),u8(0x20),u8(0xfc),u8(0xb1),u8(0x5b)
|
||||
db u8(0x6a),u8(0xcb),u8(0xbe),u8(0x39),u8(0x4a),u8(0x4c),u8(0x58),u8(0xcf)
|
||||
db u8(0xd0),u8(0xef),u8(0xaa),u8(0xfb),u8(0x43),u8(0x4d),u8(0x33),u8(0x85)
|
||||
db u8(0x45),u8(0xf9),u8(0x02),u8(0x7f),u8(0x50),u8(0x3c),u8(0x9f),u8(0xa8)
|
||||
db u8(0x51),u8(0xa3),u8(0x40),u8(0x8f),u8(0x92),u8(0x9d),u8(0x38),u8(0xf5)
|
||||
db u8(0xbc),u8(0xb6),u8(0xda),u8(0x21),u8(0x10),u8(0xff),u8(0xf3),u8(0xd2)
|
||||
db u8(0xcd),u8(0x0c),u8(0x13),u8(0xec),u8(0x5f),u8(0x97),u8(0x44),u8(0x17)
|
||||
db u8(0xc4),u8(0xa7),u8(0x7e),u8(0x3d),u8(0x64),u8(0x5d),u8(0x19),u8(0x73)
|
||||
db u8(0x60),u8(0x81),u8(0x4f),u8(0xdc),u8(0x22),u8(0x2a),u8(0x90),u8(0x88)
|
||||
db u8(0x46),u8(0xee),u8(0xb8),u8(0x14),u8(0xde),u8(0x5e),u8(0x0b),u8(0xdb)
|
||||
db u8(0xe0),u8(0x32),u8(0x3a),u8(0x0a),u8(0x49),u8(0x06),u8(0x24),u8(0x5c)
|
||||
db u8(0xc2),u8(0xd3),u8(0xac),u8(0x62),u8(0x91),u8(0x95),u8(0xe4),u8(0x79)
|
||||
db u8(0xe7),u8(0xc8),u8(0x37),u8(0x6d),u8(0x8d),u8(0xd5),u8(0x4e),u8(0xa9)
|
||||
db u8(0x6c),u8(0x56),u8(0xf4),u8(0xea),u8(0x65),u8(0x7a),u8(0xae),u8(0x08)
|
||||
db u8(0xba),u8(0x78),u8(0x25),u8(0x2e),u8(0x1c),u8(0xa6),u8(0xb4),u8(0xc6)
|
||||
db u8(0xe8),u8(0xdd),u8(0x74),u8(0x1f),u8(0x4b),u8(0xbd),u8(0x8b),u8(0x8a)
|
||||
db u8(0x70),u8(0x3e),u8(0xb5),u8(0x66),u8(0x48),u8(0x03),u8(0xf6),u8(0x0e)
|
||||
db u8(0x61),u8(0x35),u8(0x57),u8(0xb9),u8(0x86),u8(0xc1),u8(0x1d),u8(0x9e)
|
||||
db u8(0xe1),u8(0xf8),u8(0x98),u8(0x11),u8(0x69),u8(0xd9),u8(0x8e),u8(0x94)
|
||||
db u8(0x9b),u8(0x1e),u8(0x87),u8(0xe9),u8(0xce),u8(0x55),u8(0x28),u8(0xdf)
|
||||
db u8(0x8c),u8(0xa1),u8(0x89),u8(0x0d),u8(0xbf),u8(0xe6),u8(0x42),u8(0x68)
|
||||
db u8(0x41),u8(0x99),u8(0x2d),u8(0x0f),u8(0xb0),u8(0x54),u8(0xbb),u8(0x16)
|
||||
|
||||
%endif
|
||||
|
||||
%ifdef DECRYPTION_TABLE
|
||||
|
||||
; Inverse S-box data - 256 entries
|
||||
|
||||
section .data
|
||||
align 32
|
||||
|
||||
%define v8(x) fe(x), f9(x), fd(x), fb(x), fe(x), f9(x), fd(x), x
|
||||
|
||||
dec_tab:
|
||||
@@ -1416,4 +1394,3 @@ dec_tab:
|
||||
%endif
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -1,28 +1,21 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
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 Date: 20/12/2007
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
This file contains the definitions required to use AES (Rijndael) in C++.
|
||||
*/
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
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 Date: 20/12/2007
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#include "aesopt.h"
|
||||
#include "aestab.h"
|
||||
|
||||
#if defined( USE_INTEL_AES_IF_PRESENT )
|
||||
# include "aes_ni.h"
|
||||
#else
|
||||
/* map names here to provide the external API ('name' -> 'aes_name') */
|
||||
# define aes_xi(x) aes_ ## x
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
@@ -51,11 +51,11 @@ extern "C"
|
||||
#if ( FUNCS_IN_C & ENCRYPTION_IN_C )
|
||||
|
||||
/* Visual C++ .Net v7.1 provides the fastest encryption code when using
|
||||
Pentium optimiation with small code but this is poor for decryption
|
||||
Pentium optimisation with small code but this is poor for decryption
|
||||
so we need to control this with the following VC++ pragmas
|
||||
*/
|
||||
|
||||
#if defined( _MSC_VER ) && !defined( _WIN64 )
|
||||
#if defined( _MSC_VER ) && !defined( _WIN64 ) && !defined( __clang__ )
|
||||
#pragma optimize( "s", on )
|
||||
#endif
|
||||
|
||||
@@ -94,32 +94,32 @@ extern "C"
|
||||
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c))
|
||||
#endif
|
||||
|
||||
AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
|
||||
{ uint_32t locals(b0, b1);
|
||||
const uint_32t *kp;
|
||||
AES_RETURN aes_xi(encrypt)(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
|
||||
{ uint32_t locals(b0, b1);
|
||||
const uint32_t *kp;
|
||||
#if defined( dec_fmvars )
|
||||
dec_fmvars; /* declare variables for fwd_mcol() if needed */
|
||||
#endif
|
||||
|
||||
if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )
|
||||
return EXIT_FAILURE;
|
||||
if(cx->inf.b[0] != 10 * AES_BLOCK_SIZE && cx->inf.b[0] != 12 * AES_BLOCK_SIZE && cx->inf.b[0] != 14 * AES_BLOCK_SIZE)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
kp = cx->ks;
|
||||
kp = cx->ks;
|
||||
state_in(b0, in, kp);
|
||||
|
||||
#if (ENC_UNROLL == FULL)
|
||||
|
||||
switch(cx->inf.b[0])
|
||||
{
|
||||
case 14 * 16:
|
||||
case 14 * AES_BLOCK_SIZE:
|
||||
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
|
||||
kp += 2 * N_COLS;
|
||||
case 12 * 16:
|
||||
case 12 * AES_BLOCK_SIZE:
|
||||
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
|
||||
kp += 2 * N_COLS;
|
||||
case 10 * 16:
|
||||
case 10 * AES_BLOCK_SIZE:
|
||||
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
|
||||
round(fwd_rnd, b1, b0, kp + 3 * N_COLS);
|
||||
@@ -135,8 +135,8 @@ AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_en
|
||||
#else
|
||||
|
||||
#if (ENC_UNROLL == PARTIAL)
|
||||
{ uint_32t rnd;
|
||||
for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
|
||||
{ uint32_t rnd;
|
||||
for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1ul; ++rnd)
|
||||
{
|
||||
kp += N_COLS;
|
||||
round(fwd_rnd, b1, b0, kp);
|
||||
@@ -146,8 +146,8 @@ AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_en
|
||||
kp += N_COLS;
|
||||
round(fwd_rnd, b1, b0, kp);
|
||||
#else
|
||||
{ uint_32t rnd;
|
||||
for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
|
||||
{ uint32_t rnd;
|
||||
for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1ul; ++rnd)
|
||||
{
|
||||
kp += N_COLS;
|
||||
round(fwd_rnd, b1, b0, kp);
|
||||
@@ -168,11 +168,11 @@ AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_en
|
||||
#if ( FUNCS_IN_C & DECRYPTION_IN_C)
|
||||
|
||||
/* Visual C++ .Net v7.1 provides the fastest encryption code when using
|
||||
Pentium optimiation with small code but this is poor for decryption
|
||||
Pentium optimisation with small code but this is poor for decryption
|
||||
so we need to control this with the following VC++ pragmas
|
||||
*/
|
||||
|
||||
#if defined( _MSC_VER ) && !defined( _WIN64 )
|
||||
#if defined( _MSC_VER ) && !defined( _WIN64 ) && !defined( __clang__ )
|
||||
#pragma optimize( "t", on )
|
||||
#endif
|
||||
|
||||
@@ -212,7 +212,7 @@ AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_en
|
||||
#endif
|
||||
|
||||
/* This code can work with the decryption key schedule in the */
|
||||
/* order that is used for encrytpion (where the 1st decryption */
|
||||
/* order that is used for encryption (where the 1st decryption */
|
||||
/* round key is at the high end ot the schedule) or with a key */
|
||||
/* schedule that has been reversed to put the 1st decryption */
|
||||
/* round key at the low end of the schedule in memory (when */
|
||||
@@ -226,15 +226,15 @@ AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_en
|
||||
#define rnd_key(n) (kp - n * N_COLS)
|
||||
#endif
|
||||
|
||||
AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
|
||||
{ uint_32t locals(b0, b1);
|
||||
AES_RETURN aes_xi(decrypt)(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
|
||||
{ uint32_t locals(b0, b1);
|
||||
#if defined( dec_imvars )
|
||||
dec_imvars; /* declare variables for inv_mcol() if needed */
|
||||
#endif
|
||||
const uint_32t *kp;
|
||||
const uint32_t *kp;
|
||||
|
||||
if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )
|
||||
return EXIT_FAILURE;
|
||||
if(cx->inf.b[0] != 10 * AES_BLOCK_SIZE && cx->inf.b[0] != 12 * AES_BLOCK_SIZE && cx->inf.b[0] != 14 * AES_BLOCK_SIZE)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
|
||||
state_in(b0, in, kp);
|
||||
@@ -244,13 +244,13 @@ AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_de
|
||||
kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
|
||||
switch(cx->inf.b[0])
|
||||
{
|
||||
case 14 * 16:
|
||||
case 14 * AES_BLOCK_SIZE:
|
||||
round(inv_rnd, b1, b0, rnd_key(-13));
|
||||
round(inv_rnd, b0, b1, rnd_key(-12));
|
||||
case 12 * 16:
|
||||
case 12 * AES_BLOCK_SIZE:
|
||||
round(inv_rnd, b1, b0, rnd_key(-11));
|
||||
round(inv_rnd, b0, b1, rnd_key(-10));
|
||||
case 10 * 16:
|
||||
case 10 * AES_BLOCK_SIZE:
|
||||
round(inv_rnd, b1, b0, rnd_key(-9));
|
||||
round(inv_rnd, b0, b1, rnd_key(-8));
|
||||
round(inv_rnd, b1, b0, rnd_key(-7));
|
||||
@@ -266,8 +266,8 @@ AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_de
|
||||
#else
|
||||
|
||||
#if (DEC_UNROLL == PARTIAL)
|
||||
{ uint_32t rnd;
|
||||
for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
|
||||
{ uint32_t rnd;
|
||||
for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1ul; ++rnd)
|
||||
{
|
||||
kp = rnd_key(1);
|
||||
round(inv_rnd, b1, b0, kp);
|
||||
@@ -277,8 +277,8 @@ AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_de
|
||||
kp = rnd_key(1);
|
||||
round(inv_rnd, b1, b0, kp);
|
||||
#else
|
||||
{ uint_32t rnd;
|
||||
for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
|
||||
{ uint32_t rnd;
|
||||
for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1ul; ++rnd)
|
||||
{
|
||||
kp = rnd_key(1);
|
||||
round(inv_rnd, b1, b0, kp);
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
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 Date: 20/12/2007
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#include "aesopt.h"
|
||||
#include "aestab.h"
|
||||
|
||||
#if defined( USE_INTEL_AES_IF_PRESENT )
|
||||
# include "aes_ni.h"
|
||||
#else
|
||||
/* map names here to provide the external API ('name' -> 'aes_name') */
|
||||
# define aes_xi(x) aes_ ## x
|
||||
#endif
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
# include "aes_via_ace.h"
|
||||
#endif
|
||||
@@ -37,6 +37,13 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Use the low bit in the context's inf.b[2] as a flag to
|
||||
indicate whether a context was initialized for encryption
|
||||
or decryption.
|
||||
*/
|
||||
#define MARK_AS_ENCRYPTION_CTX(cx) (cx)->inf.b[2] |= (uint8_t)0x01
|
||||
#define MARK_AS_DECRYPTION_CTX(cx) (cx)->inf.b[2] &= (uint8_t)0xfe
|
||||
|
||||
/* Initialise the key schedule from the user supplied key. The key
|
||||
length can be specified in bytes, with legal values of 16, 24
|
||||
and 32, or in bits, with legal values of 128, 192 and 256. These
|
||||
@@ -57,9 +64,9 @@ extern "C"
|
||||
|
||||
#if defined( REDUCE_CODE_SIZE )
|
||||
# define ls_box ls_sub
|
||||
uint_32t ls_sub(const uint_32t t, const uint_32t n);
|
||||
uint32_t ls_sub(const uint32_t t, const uint32_t n);
|
||||
# define inv_mcol im_sub
|
||||
uint_32t im_sub(const uint_32t x);
|
||||
uint32_t im_sub(const uint32_t x);
|
||||
# ifdef ENC_KS_UNROLL
|
||||
# undef ENC_KS_UNROLL
|
||||
# endif
|
||||
@@ -79,8 +86,8 @@ extern "C"
|
||||
k[4*(i)+7] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
|
||||
AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
{ uint_32t ss[4];
|
||||
AES_RETURN aes_xi(encrypt_key128)(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
{ uint32_t ss[4];
|
||||
|
||||
cx->ks[0] = ss[0] = word_in(key, 0);
|
||||
cx->ks[1] = ss[1] = word_in(key, 1);
|
||||
@@ -94,19 +101,20 @@ AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
ke4(cx->ks, 6); ke4(cx->ks, 7);
|
||||
ke4(cx->ks, 8);
|
||||
#else
|
||||
{ uint_32t i;
|
||||
{ uint32_t i;
|
||||
for(i = 0; i < 9; ++i)
|
||||
ke4(cx->ks, i);
|
||||
}
|
||||
#endif
|
||||
ke4(cx->ks, 9);
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 10 * 16;
|
||||
cx->inf.b[0] = 10 * AES_BLOCK_SIZE;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
MARK_AS_ENCRYPTION_CTX(cx);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -127,10 +135,10 @@ AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
k[6*(i)+11] = ss[5] ^= ss[4]; \
|
||||
}
|
||||
|
||||
AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
{ uint_32t ss[6];
|
||||
AES_RETURN aes_xi(encrypt_key192)(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
{ uint32_t ss[6];
|
||||
|
||||
cx->ks[0] = ss[0] = word_in(key, 0);
|
||||
cx->ks[0] = ss[0] = word_in(key, 0);
|
||||
cx->ks[1] = ss[1] = word_in(key, 1);
|
||||
cx->ks[2] = ss[2] = word_in(key, 2);
|
||||
cx->ks[3] = ss[3] = word_in(key, 3);
|
||||
@@ -143,19 +151,20 @@ AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
ke6(cx->ks, 4); ke6(cx->ks, 5);
|
||||
ke6(cx->ks, 6);
|
||||
#else
|
||||
{ uint_32t i;
|
||||
{ uint32_t i;
|
||||
for(i = 0; i < 7; ++i)
|
||||
ke6(cx->ks, i);
|
||||
}
|
||||
#endif
|
||||
kef6(cx->ks, 7);
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 12 * 16;
|
||||
cx->inf.b[0] = 12 * AES_BLOCK_SIZE;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
MARK_AS_ENCRYPTION_CTX(cx);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -178,8 +187,8 @@ AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
k[8*(i)+15] = ss[7] ^= ss[6]; \
|
||||
}
|
||||
|
||||
AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
{ uint_32t ss[8];
|
||||
AES_RETURN aes_xi(encrypt_key256)(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
{ uint32_t ss[8];
|
||||
|
||||
cx->ks[0] = ss[0] = word_in(key, 0);
|
||||
cx->ks[1] = ss[1] = word_in(key, 1);
|
||||
@@ -195,39 +204,25 @@ AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
ke8(cx->ks, 2); ke8(cx->ks, 3);
|
||||
ke8(cx->ks, 4); ke8(cx->ks, 5);
|
||||
#else
|
||||
{ uint_32t i;
|
||||
{ uint32_t i;
|
||||
for(i = 0; i < 6; ++i)
|
||||
ke8(cx->ks, i);
|
||||
}
|
||||
#endif
|
||||
kef8(cx->ks, 6);
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 14 * 16;
|
||||
cx->inf.b[0] = 14 * AES_BLOCK_SIZE;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
MARK_AS_ENCRYPTION_CTX(cx);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_VAR )
|
||||
|
||||
AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
|
||||
{
|
||||
switch(key_len)
|
||||
{
|
||||
case 16: case 128: return aes_encrypt_key128(key, cx);
|
||||
case 24: case 192: return aes_encrypt_key192(key, cx);
|
||||
case 32: case 256: return aes_encrypt_key256(key, cx);
|
||||
default: return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (FUNCS_IN_C & DEC_KEYING_IN_C)
|
||||
@@ -316,12 +311,13 @@ AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ct
|
||||
|
||||
#endif
|
||||
|
||||
AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
{ uint_32t ss[5];
|
||||
AES_RETURN aes_xi(decrypt_key128)(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
{ uint32_t ss[5];
|
||||
#if defined( d_vars )
|
||||
d_vars;
|
||||
#endif
|
||||
cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);
|
||||
|
||||
cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);
|
||||
cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);
|
||||
cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);
|
||||
cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);
|
||||
@@ -333,7 +329,7 @@ AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
kd4(cx->ks, 6); kd4(cx->ks, 7);
|
||||
kd4(cx->ks, 8); kdl4(cx->ks, 9);
|
||||
#else
|
||||
{ uint_32t i;
|
||||
{ uint32_t i;
|
||||
for(i = 0; i < 10; ++i)
|
||||
k4e(cx->ks, i);
|
||||
#if !(DEC_ROUND == NO_TABLES)
|
||||
@@ -343,12 +339,13 @@ AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
}
|
||||
#endif
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 10 * 16;
|
||||
cx->inf.b[0] = 10 * AES_BLOCK_SIZE;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
MARK_AS_DECRYPTION_CTX(cx);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -395,19 +392,22 @@ AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
|
||||
}
|
||||
|
||||
AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
{ uint_32t ss[7];
|
||||
AES_RETURN aes_xi(decrypt_key192)(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
{ uint32_t ss[7];
|
||||
#if defined( d_vars )
|
||||
d_vars;
|
||||
#endif
|
||||
|
||||
cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);
|
||||
cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);
|
||||
cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
|
||||
cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
|
||||
|
||||
#ifdef DEC_KS_UNROLL
|
||||
cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
|
||||
cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
|
||||
ss[4] = word_in(key, 4);
|
||||
ss[5] = word_in(key, 5);
|
||||
cx->ks[v(48, (4))] = ff(ss[4]);
|
||||
cx->ks[v(48, (5))] = ff(ss[5]);
|
||||
kdf6(cx->ks, 0); kd6(cx->ks, 1);
|
||||
kd6(cx->ks, 2); kd6(cx->ks, 3);
|
||||
kd6(cx->ks, 4); kd6(cx->ks, 5);
|
||||
@@ -415,7 +415,7 @@ AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
#else
|
||||
cx->ks[v(48,(4))] = ss[4] = word_in(key, 4);
|
||||
cx->ks[v(48,(5))] = ss[5] = word_in(key, 5);
|
||||
{ uint_32t i;
|
||||
{ uint32_t i;
|
||||
|
||||
for(i = 0; i < 7; ++i)
|
||||
k6e(cx->ks, i);
|
||||
@@ -427,12 +427,13 @@ AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
}
|
||||
#endif
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 12 * 16;
|
||||
cx->inf.b[0] = 12 * AES_BLOCK_SIZE;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
MARK_AS_DECRYPTION_CTX(cx);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -486,21 +487,26 @@ AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
|
||||
}
|
||||
|
||||
AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
{ uint_32t ss[9];
|
||||
AES_RETURN aes_xi(decrypt_key256)(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
{ uint32_t ss[9];
|
||||
#if defined( d_vars )
|
||||
d_vars;
|
||||
#endif
|
||||
|
||||
cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);
|
||||
cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);
|
||||
cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);
|
||||
cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
|
||||
|
||||
#ifdef DEC_KS_UNROLL
|
||||
cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));
|
||||
cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));
|
||||
cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));
|
||||
cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));
|
||||
ss[4] = word_in(key, 4);
|
||||
ss[5] = word_in(key, 5);
|
||||
ss[6] = word_in(key, 6);
|
||||
ss[7] = word_in(key, 7);
|
||||
cx->ks[v(56,(4))] = ff(ss[4]);
|
||||
cx->ks[v(56,(5))] = ff(ss[5]);
|
||||
cx->ks[v(56,(6))] = ff(ss[6]);
|
||||
cx->ks[v(56,(7))] = ff(ss[7]);
|
||||
kdf8(cx->ks, 0); kd8(cx->ks, 1);
|
||||
kd8(cx->ks, 2); kd8(cx->ks, 3);
|
||||
kd8(cx->ks, 4); kd8(cx->ks, 5);
|
||||
@@ -510,7 +516,7 @@ AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
cx->ks[v(56,(5))] = ss[5] = word_in(key, 5);
|
||||
cx->ks[v(56,(6))] = ss[6] = word_in(key, 6);
|
||||
cx->ks[v(56,(7))] = ss[7] = word_in(key, 7);
|
||||
{ uint_32t i;
|
||||
{ uint32_t i;
|
||||
|
||||
for(i = 0; i < 6; ++i)
|
||||
k8e(cx->ks, i);
|
||||
@@ -522,34 +528,46 @@ AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
}
|
||||
#endif
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 14 * 16;
|
||||
cx->inf.b[0] = 14 * AES_BLOCK_SIZE;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
MARK_AS_DECRYPTION_CTX(cx);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_VAR )
|
||||
|
||||
AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
|
||||
{
|
||||
switch(key_len)
|
||||
{
|
||||
case 16: case 128: return aes_encrypt_key128(key, cx);
|
||||
case 24: case 192: return aes_encrypt_key192(key, cx);
|
||||
case 32: case 256: return aes_encrypt_key256(key, cx);
|
||||
default: return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
|
||||
{
|
||||
switch(key_len)
|
||||
{
|
||||
case 16: case 128: return aes_decrypt_key128(key, cx);
|
||||
case 24: case 192: return aes_decrypt_key192(key, cx);
|
||||
case 32: case 256: return aes_decrypt_key256(key, cx);
|
||||
default: return EXIT_FAILURE;
|
||||
}
|
||||
switch(key_len)
|
||||
{
|
||||
case 16: case 128: return aes_decrypt_key128(key, cx);
|
||||
case 24: case 192: return aes_decrypt_key192(key, cx);
|
||||
case 32: case 256: return aes_decrypt_key256(key, cx);
|
||||
default: return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,28 +1,21 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
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 Date: 20/12/2007
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
This file contains the compilation options for AES (Rijndael) and code
|
||||
that is common across encryption, key scheduling and table generation.
|
||||
@@ -44,8 +37,8 @@
|
||||
The cipher interface is implemented as an array of bytes in which lower
|
||||
AES bit sequence indexes map to higher numeric significance within bytes.
|
||||
|
||||
uint_8t (an unsigned 8-bit type)
|
||||
uint_32t (an unsigned 32-bit type)
|
||||
uint8_t (an unsigned 8-bit type)
|
||||
uint32_t (an unsigned 32-bit type)
|
||||
struct aes_encrypt_ctx (structure for the cipher encryption context)
|
||||
struct aes_decrypt_ctx (structure for the cipher decryption context)
|
||||
AES_RETURN the function return type
|
||||
@@ -71,7 +64,7 @@
|
||||
|
||||
Class AESencrypt for encryption
|
||||
|
||||
Construtors:
|
||||
Constructors:
|
||||
AESencrypt(void)
|
||||
AESencrypt(const unsigned char *key) - 128 bit key
|
||||
Members:
|
||||
@@ -81,7 +74,7 @@
|
||||
AES_RETURN encrypt(const unsigned char *in, unsigned char *out) const
|
||||
|
||||
Class AESdecrypt for encryption
|
||||
Construtors:
|
||||
Constructors:
|
||||
AESdecrypt(void)
|
||||
AESdecrypt(const unsigned char *key) - 128 bit key
|
||||
Members:
|
||||
@@ -168,14 +161,47 @@
|
||||
# error The algorithm byte order is not defined
|
||||
#endif
|
||||
|
||||
/* 2. VIA ACE SUPPORT */
|
||||
/* 2. Intel AES AND VIA ACE SUPPORT */
|
||||
|
||||
#if defined( __GNUC__ ) && defined( __i386__ ) \
|
||||
|| defined( _WIN32 ) && defined( _M_IX86 ) \
|
||||
&& !(defined( _WIN64 ) || defined( _WIN32_WCE ) || defined( _MSC_VER ) && ( _MSC_VER <= 800 ))
|
||||
#if defined( __GNUC__ ) && defined( __i386__ ) && !defined(__BEOS__) \
|
||||
|| defined( _WIN32 ) && defined( _M_IX86 ) && !(defined( _WIN64 ) \
|
||||
|| defined( _WIN32_WCE ) || defined( _MSC_VER ) && ( _MSC_VER <= 800 ))
|
||||
# define VIA_ACE_POSSIBLE
|
||||
#endif
|
||||
|
||||
/* AESNI is supported by all Windows x64 compilers, but for Linux/GCC
|
||||
we have to test for SSE 2, SSE 3, and AES to before enabling it; */
|
||||
#if !defined( INTEL_AES_POSSIBLE )
|
||||
# if defined( _WIN64 ) && defined( _MSC_VER ) \
|
||||
|| defined( __GNUC__ ) && defined( __x86_64__ ) && \
|
||||
defined( __SSE2__ ) && defined( __SSE3__ ) && \
|
||||
defined( __AES__ )
|
||||
# define INTEL_AES_POSSIBLE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Define this option if support for the Intel AESNI is required
|
||||
If USE_INTEL_AES_IF_PRESENT is defined then AESNI will be used
|
||||
if it is detected (both present and enabled).
|
||||
|
||||
AESNI uses a decryption key schedule with the first decryption
|
||||
round key at the high end of the key schedule with the following
|
||||
round keys at lower positions in memory. So AES_REV_DKS must NOT
|
||||
be defined when AESNI will be used. Although it is unlikely that
|
||||
assembler code will be used with an AESNI build, if it is then
|
||||
AES_REV_DKS must NOT be defined when the assembler files are
|
||||
built (the definition of USE_INTEL_AES_IF_PRESENT in the assembler
|
||||
code files must match that here if they are used).
|
||||
*/
|
||||
|
||||
#if defined( INTEL_AES_POSSIBLE )
|
||||
# if 1 && !defined( USE_INTEL_AES_IF_PRESENT )
|
||||
# define USE_INTEL_AES_IF_PRESENT
|
||||
# endif
|
||||
#elif defined( USE_INTEL_AES_IF_PRESENT )
|
||||
# error: AES_NI is not available on this platform
|
||||
#endif
|
||||
|
||||
/* Define this option if support for the VIA ACE is required. This uses
|
||||
inline assembler instructions and is only implemented for the Microsoft,
|
||||
Intel and GCC compilers. If VIA ACE is known to be present, then defining
|
||||
@@ -189,10 +215,11 @@
|
||||
but there are very large performance gains if this can be arranged.
|
||||
VIA ACE also requires the decryption key schedule to be in reverse
|
||||
order (which later checks below ensure).
|
||||
|
||||
AES_REV_DKS must be set for assembler code used with a VIA ACE build
|
||||
*/
|
||||
|
||||
/* Disable VIA ACE cpu detection which crashes on x86 android devices */
|
||||
#if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( USE_VIA_ACE_IF_PRESENT )
|
||||
#if 1 && defined( VIA_ACE_POSSIBLE ) && !defined( USE_VIA_ACE_IF_PRESENT )
|
||||
# define USE_VIA_ACE_IF_PRESENT
|
||||
#endif
|
||||
|
||||
@@ -229,8 +256,14 @@
|
||||
# define ASM_AMD64_C
|
||||
#endif
|
||||
|
||||
#if defined( __i386 ) || defined( _M_IX86 )
|
||||
# define A32_
|
||||
#elif defined( __x86_64__ ) || defined( _M_X64 )
|
||||
# define A64_
|
||||
#endif
|
||||
|
||||
#if (defined ( ASM_X86_V1C ) || defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) \
|
||||
&& !defined( _M_IX86 ) || defined( ASM_AMD64_C ) && !defined( _M_X64 )
|
||||
&& !defined( A32_ ) || defined( ASM_AMD64_C ) && !defined( A64_ )
|
||||
# error Assembler code is only available for x86 and AMD64 systems
|
||||
#endif
|
||||
|
||||
@@ -256,7 +289,7 @@
|
||||
|
||||
/* 5. LOOP UNROLLING
|
||||
|
||||
The code for encryption and decrytpion cycles through a number of rounds
|
||||
The code for encryption and decryption cycles through a number of rounds
|
||||
that can be implemented either in a loop or by expanding the code into a
|
||||
long sequence of instructions, the latter producing a larger program but
|
||||
one that will often be much faster. The latter is called loop unrolling.
|
||||
@@ -292,7 +325,7 @@
|
||||
/* 6. FAST FINITE FIELD OPERATIONS
|
||||
|
||||
If this section is included, tables are used to provide faster finite
|
||||
field arithmetic (this has no effect if FIXED_TABLES is defined).
|
||||
field arithmetic (this has no effect if STATIC_TABLES is defined).
|
||||
*/
|
||||
#if 1
|
||||
# define FF_TABLES
|
||||
@@ -301,9 +334,9 @@
|
||||
/* 7. INTERNAL STATE VARIABLE FORMAT
|
||||
|
||||
The internal state of Rijndael is stored in a number of local 32-bit
|
||||
word varaibles which can be defined either as an array or as individual
|
||||
word variables which can be defined either as an array or as individual
|
||||
names variables. Include this section if you want to store these local
|
||||
varaibles in arrays. Otherwise individual local variables will be used.
|
||||
variables in arrays. Otherwise individual local variables will be used.
|
||||
*/
|
||||
#if 1
|
||||
# define ARRAYS
|
||||
@@ -316,7 +349,7 @@
|
||||
must be called to compute them before the code is first used.
|
||||
*/
|
||||
#if 1 && !(defined( _MSC_VER ) && ( _MSC_VER <= 800 ))
|
||||
# define FIXED_TABLES
|
||||
# define STATIC_TABLES
|
||||
#endif
|
||||
|
||||
/* 9. MASKING OR CASTING FROM LONGER VALUES TO BYTES
|
||||
@@ -325,17 +358,17 @@
|
||||
rather than using a cast. This option allows this choice.
|
||||
*/
|
||||
#if 0
|
||||
# define to_byte(x) ((uint_8t)(x))
|
||||
# define to_byte(x) ((uint8_t)(x))
|
||||
#else
|
||||
# define to_byte(x) ((x) & 0xff)
|
||||
#endif
|
||||
|
||||
/* 10. TABLE ALIGNMENT
|
||||
|
||||
On some sytsems speed will be improved by aligning the AES large lookup
|
||||
On some systems speed will be improved by aligning the AES large lookup
|
||||
tables on particular boundaries. This define should be set to a power of
|
||||
two giving the desired alignment. It can be left undefined if alignment
|
||||
is not needed. This option is specific to the Microsft VC++ compiler -
|
||||
is not needed. This option is specific to the Microsoft VC++ compiler -
|
||||
it seems to sometimes cause trouble for the VC++ version 6 compiler.
|
||||
*/
|
||||
|
||||
@@ -360,7 +393,7 @@
|
||||
up using tables. The basic tables are each 256 32-bit words, with either
|
||||
one or four tables being required for each round function depending on
|
||||
how much speed is required. The encryption and decryption round functions
|
||||
are different and the last encryption and decrytpion round functions are
|
||||
are different and the last encryption and decryption round functions are
|
||||
different again making four different round functions in all.
|
||||
|
||||
This means that:
|
||||
@@ -434,10 +467,16 @@
|
||||
# define USE_VIA_ACE_IF_PRESENT
|
||||
#endif
|
||||
|
||||
#if defined( USE_VIA_ACE_IF_PRESENT ) && !defined ( AES_REV_DKS )
|
||||
/* define to reverse decryption key schedule */
|
||||
#if 1 || defined( USE_VIA_ACE_IF_PRESENT ) && !defined ( AES_REV_DKS )
|
||||
# define AES_REV_DKS
|
||||
#endif
|
||||
|
||||
/* Intel AESNI uses a decryption key schedule in the encryption order */
|
||||
#if defined( USE_INTEL_AES_IF_PRESENT ) && defined ( AES_REV_DKS )
|
||||
# undef AES_REV_DKS
|
||||
#endif
|
||||
|
||||
/* Assembler support requires the use of platform byte order */
|
||||
|
||||
#if ( defined( ASM_X86_V1C ) || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) ) \
|
||||
@@ -453,7 +492,7 @@
|
||||
a column number c to the way the state array variable is to be held.
|
||||
The first define below maps the state into an array x[c] whereas the
|
||||
second form maps the state into a number of individual variables x0,
|
||||
x1, etc. Another form could map individual state colums to machine
|
||||
x1, etc. Another form could map individual state columns to machine
|
||||
register names.
|
||||
*/
|
||||
|
||||
@@ -530,7 +569,7 @@
|
||||
#elif defined( bswap_32 )
|
||||
# define aes_sw32 bswap_32
|
||||
#else
|
||||
# define brot(x,n) (((uint_32t)(x) << n) | ((uint_32t)(x) >> (32 - n)))
|
||||
# define brot(x,n) (((uint32_t)(x) << n) | ((uint32_t)(x) >> (32 - n)))
|
||||
# define aes_sw32(x) ((brot((x),8) & 0x00ff00ff) | (brot((x),24) & 0xff00ff00))
|
||||
#endif
|
||||
|
||||
@@ -546,32 +585,32 @@
|
||||
*/
|
||||
|
||||
#if ( ALGORITHM_BYTE_ORDER == IS_LITTLE_ENDIAN )
|
||||
# define upr(x,n) (((uint_32t)(x) << (8 * (n))) | ((uint_32t)(x) >> (32 - 8 * (n))))
|
||||
# define ups(x,n) ((uint_32t) (x) << (8 * (n)))
|
||||
# define upr(x,n) (((uint32_t)(x) << (8 * (n))) | ((uint32_t)(x) >> (32 - 8 * (n))))
|
||||
# define ups(x,n) ((uint32_t) (x) << (8 * (n)))
|
||||
# define bval(x,n) to_byte((x) >> (8 * (n)))
|
||||
# define bytes2word(b0, b1, b2, b3) \
|
||||
(((uint_32t)(b3) << 24) | ((uint_32t)(b2) << 16) | ((uint_32t)(b1) << 8) | (b0))
|
||||
(((uint32_t)(b3) << 24) | ((uint32_t)(b2) << 16) | ((uint32_t)(b1) << 8) | (b0))
|
||||
#endif
|
||||
|
||||
#if ( ALGORITHM_BYTE_ORDER == IS_BIG_ENDIAN )
|
||||
# define upr(x,n) (((uint_32t)(x) >> (8 * (n))) | ((uint_32t)(x) << (32 - 8 * (n))))
|
||||
# define ups(x,n) ((uint_32t) (x) >> (8 * (n)))
|
||||
# define upr(x,n) (((uint32_t)(x) >> (8 * (n))) | ((uint32_t)(x) << (32 - 8 * (n))))
|
||||
# define ups(x,n) ((uint32_t) (x) >> (8 * (n)))
|
||||
# define bval(x,n) to_byte((x) >> (24 - 8 * (n)))
|
||||
# define bytes2word(b0, b1, b2, b3) \
|
||||
(((uint_32t)(b0) << 24) | ((uint_32t)(b1) << 16) | ((uint_32t)(b2) << 8) | (b3))
|
||||
(((uint32_t)(b0) << 24) | ((uint32_t)(b1) << 16) | ((uint32_t)(b2) << 8) | (b3))
|
||||
#endif
|
||||
|
||||
#if defined( SAFE_IO )
|
||||
# define word_in(x,c) bytes2word(((const uint_8t*)(x)+4*c)[0], ((const uint_8t*)(x)+4*c)[1], \
|
||||
((const uint_8t*)(x)+4*c)[2], ((const uint_8t*)(x)+4*c)[3])
|
||||
# define word_out(x,c,v) { ((uint_8t*)(x)+4*c)[0] = bval(v,0); ((uint_8t*)(x)+4*c)[1] = bval(v,1); \
|
||||
((uint_8t*)(x)+4*c)[2] = bval(v,2); ((uint_8t*)(x)+4*c)[3] = bval(v,3); }
|
||||
# define word_in(x,c) bytes2word(((const uint8_t*)(x)+4*c)[0], ((const uint8_t*)(x)+4*c)[1], \
|
||||
((const uint8_t*)(x)+4*c)[2], ((const uint8_t*)(x)+4*c)[3])
|
||||
# define word_out(x,c,v) { ((uint8_t*)(x)+4*c)[0] = bval(v,0); ((uint8_t*)(x)+4*c)[1] = bval(v,1); \
|
||||
((uint8_t*)(x)+4*c)[2] = bval(v,2); ((uint8_t*)(x)+4*c)[3] = bval(v,3); }
|
||||
#elif ( ALGORITHM_BYTE_ORDER == PLATFORM_BYTE_ORDER )
|
||||
# define word_in(x,c) (*((uint_32t*)(x)+(c)))
|
||||
# define word_out(x,c,v) (*((uint_32t*)(x)+(c)) = (v))
|
||||
# define word_in(x,c) (*((uint32_t*)(x)+(c)))
|
||||
# define word_out(x,c,v) (*((uint32_t*)(x)+(c)) = (v))
|
||||
#else
|
||||
# define word_in(x,c) aes_sw32(*((uint_32t*)(x)+(c)))
|
||||
# define word_out(x,c,v) (*((uint_32t*)(x)+(c)) = aes_sw32(v))
|
||||
# define word_in(x,c) aes_sw32(*((uint32_t*)(x)+(c)))
|
||||
# define word_out(x,c,v) (*((uint32_t*)(x)+(c)) = aes_sw32(v))
|
||||
#endif
|
||||
|
||||
/* the finite field modular polynomial and elements */
|
||||
@@ -581,17 +620,17 @@
|
||||
|
||||
/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
|
||||
|
||||
#define m1 0x80808080
|
||||
#define m2 0x7f7f7f7f
|
||||
#define gf_mulx(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * BPOLY))
|
||||
#define gf_c1 0x80808080
|
||||
#define gf_c2 0x7f7f7f7f
|
||||
#define gf_mulx(x) ((((x) & gf_c2) << 1) ^ ((((x) & gf_c1) >> 7) * BPOLY))
|
||||
|
||||
/* The following defines provide alternative definitions of gf_mulx that might
|
||||
give improved performance if a fast 32-bit multiply is not available. Note
|
||||
that a temporary variable u needs to be defined where gf_mulx is used.
|
||||
|
||||
#define gf_mulx(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
|
||||
#define m4 (0x01010101 * BPOLY)
|
||||
#define gf_mulx(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
|
||||
#define gf_mulx(x) (u = (x) & gf_c1, u |= (u >> 1), ((x) & gf_c2) << 1) ^ ((u >> 3) | (u >> 6))
|
||||
#define gf_c4 (0x01010101 * BPOLY)
|
||||
#define gf_mulx(x) (u = (x) & gf_c1, ((x) & gf_c2) << 1) ^ ((u - (u >> 7)) & gf_c4)
|
||||
*/
|
||||
|
||||
/* Work out which tables are needed for the different options */
|
||||
@@ -712,7 +751,7 @@
|
||||
#elif defined( FM1_SET ) /* not currently used */
|
||||
# define fwd_mcol(x) one_table(x,upr,t_use(f,m),vf1,rf1,0)
|
||||
#else
|
||||
# define dec_fmvars uint_32t g2
|
||||
# define dec_fmvars uint32_t g2
|
||||
# define fwd_mcol(x) (g2 = gf_mulx(x), g2 ^ upr((x) ^ g2, 3) ^ upr((x), 2) ^ upr((x), 1))
|
||||
#endif
|
||||
|
||||
@@ -721,7 +760,7 @@
|
||||
#elif defined( IM1_SET )
|
||||
# define inv_mcol(x) one_table(x,upr,t_use(i,m),vf1,rf1,0)
|
||||
#else
|
||||
# define dec_imvars uint_32t g2, g4, g9
|
||||
# define dec_imvars uint32_t g2, g4, g9
|
||||
# define inv_mcol(x) (g2 = gf_mulx(x), g4 = gf_mulx(g2), g9 = (x) ^ gf_mulx(g4), g4 ^= g9, \
|
||||
(x) ^ g2 ^ g4 ^ upr(g2 ^ g9, 3) ^ upr(g4, 2) ^ upr(g9, 1))
|
||||
#endif
|
||||
|
||||
@@ -1,28 +1,21 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
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 Date: 20/12/2007
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#define DO_TABLES
|
||||
@@ -30,7 +23,7 @@
|
||||
#include "aes.h"
|
||||
#include "aesopt.h"
|
||||
|
||||
#if defined(FIXED_TABLES)
|
||||
#if defined(STATIC_TABLES)
|
||||
|
||||
#define sb_data(w) {\
|
||||
w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
|
||||
@@ -157,7 +150,7 @@
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(FIXED_TABLES) || !defined(FF_TABLES)
|
||||
#if defined(STATIC_TABLES) || !defined(FF_TABLES)
|
||||
|
||||
#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY))
|
||||
#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
|
||||
@@ -187,7 +180,7 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if defined(FIXED_TABLES)
|
||||
#if defined(STATIC_TABLES)
|
||||
|
||||
/* implemented in case of wrong call for fixed tables */
|
||||
|
||||
@@ -215,8 +208,8 @@ AES_RETURN aes_init(void)
|
||||
used so that locals within fi can be bytes rather than words
|
||||
*/
|
||||
|
||||
static uint_8t hibit(const uint_32t x)
|
||||
{ uint_8t r = (uint_8t)((x >> 1) | (x >> 2));
|
||||
static uint8_t hibit(const uint32_t x)
|
||||
{ uint8_t r = (uint8_t)((x >> 1) | (x >> 2));
|
||||
|
||||
r |= (r >> 2);
|
||||
r |= (r >> 4);
|
||||
@@ -225,8 +218,8 @@ static uint_8t hibit(const uint_32t x)
|
||||
|
||||
/* return the inverse of the finite field element x */
|
||||
|
||||
static uint_8t gf_inv(const uint_8t x)
|
||||
{ uint_8t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
|
||||
static uint8_t gf_inv(const uint8_t x)
|
||||
{ uint8_t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
|
||||
|
||||
if(x < 2)
|
||||
return x;
|
||||
@@ -260,14 +253,14 @@ static uint_8t gf_inv(const uint_8t x)
|
||||
#endif
|
||||
|
||||
/* The forward and inverse affine transformations used in the S-box */
|
||||
uint_8t fwd_affine(const uint_8t x)
|
||||
{ uint_32t w = x;
|
||||
uint8_t fwd_affine(const uint8_t x)
|
||||
{ uint32_t w = x;
|
||||
w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4);
|
||||
return 0x63 ^ ((w ^ (w >> 8)) & 0xff);
|
||||
}
|
||||
|
||||
uint_8t inv_affine(const uint_8t x)
|
||||
{ uint_32t w = x;
|
||||
uint8_t inv_affine(const uint8_t x)
|
||||
{ uint32_t w = x;
|
||||
w = (w << 1) ^ (w << 3) ^ (w << 6);
|
||||
return 0x05 ^ ((w ^ (w >> 8)) & 0xff);
|
||||
}
|
||||
@@ -275,11 +268,11 @@ uint_8t inv_affine(const uint_8t x)
|
||||
static int init = 0;
|
||||
|
||||
AES_RETURN aes_init(void)
|
||||
{ uint_32t i, w;
|
||||
{ uint32_t i, w;
|
||||
|
||||
#if defined(FF_TABLES)
|
||||
|
||||
uint_8t pow[512], log[256];
|
||||
uint8_t pow[512], log[256];
|
||||
|
||||
if(init)
|
||||
return EXIT_SUCCESS;
|
||||
@@ -291,9 +284,9 @@ AES_RETURN aes_init(void)
|
||||
i = 0; w = 1;
|
||||
do
|
||||
{
|
||||
pow[i] = (uint_8t)w;
|
||||
pow[i + 255] = (uint_8t)w;
|
||||
log[w] = (uint_8t)i++;
|
||||
pow[i] = (uint8_t)w;
|
||||
pow[i + 255] = (uint8_t)w;
|
||||
log[w] = (uint8_t)i++;
|
||||
w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0);
|
||||
}
|
||||
while (w != 1);
|
||||
@@ -310,9 +303,9 @@ AES_RETURN aes_init(void)
|
||||
}
|
||||
|
||||
for(i = 0; i < 256; ++i)
|
||||
{ uint_8t b;
|
||||
{ uint8_t b;
|
||||
|
||||
b = fwd_affine(gf_inv((uint_8t)i));
|
||||
b = fwd_affine(gf_inv((uint8_t)i));
|
||||
w = bytes2word(f2(b), b, b, f3(b));
|
||||
|
||||
#if defined( SBX_SET )
|
||||
@@ -350,7 +343,7 @@ AES_RETURN aes_init(void)
|
||||
t_set(l,s)[3][i] = upr(w,3);
|
||||
#endif
|
||||
|
||||
b = gf_inv(inv_affine((uint_8t)i));
|
||||
b = gf_inv(inv_affine((uint8_t)i));
|
||||
w = bytes2word(fe(b), f9(b), fd(b), fb(b));
|
||||
|
||||
#if defined( IM1_SET ) /* tables for the inverse mix column operation */
|
||||
@@ -390,6 +383,33 @@ AES_RETURN aes_init(void)
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
Automatic code initialisation (suggested by by Henrik S. Gaßmann)
|
||||
based on code provided by Joe Lowe and placed in the public domain at:
|
||||
http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#pragma section(".CRT$XCU", read)
|
||||
|
||||
__declspec(allocate(".CRT$XCU")) void (__cdecl *aes_startup)(void) = aes_init;
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
static void aes_startup(void) __attribute__((constructor));
|
||||
|
||||
static void aes_startup(void)
|
||||
{
|
||||
aes_init();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#pragma message( "dynamic tables must be initialised manually on your system" )
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
@@ -1,28 +1,21 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
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 Date: 20/12/2007
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
This file contains the code for declaring the tables needed to implement
|
||||
AES. The file aesopt.h is assumed to be included before this header file.
|
||||
@@ -36,7 +29,7 @@
|
||||
that control the calls to aes_init() and the aes_init() routine itself will
|
||||
have to be changed for a specific implementation. If global variables are
|
||||
available it will generally be preferable to use them with the precomputed
|
||||
FIXED_TABLES option that uses static global tables.
|
||||
STATIC_TABLES option that uses static global tables.
|
||||
|
||||
The following defines can be used to control the way the tables
|
||||
are defined, initialised and used in embedded environments that
|
||||
@@ -76,7 +69,7 @@ extern "C" {
|
||||
#define t_set(m,n) t_##m##n
|
||||
#define t_use(m,n) t_##m##n
|
||||
|
||||
#if defined(FIXED_TABLES)
|
||||
#if defined(STATIC_TABLES)
|
||||
# if !defined( __GNUC__ ) && (defined( __MSDOS__ ) || defined( __WIN16__ ))
|
||||
/* make tables far data to avoid using too much DGROUP space (PG) */
|
||||
# define CONST const far
|
||||
@@ -105,56 +98,56 @@ extern "C" {
|
||||
# define XP_DIR
|
||||
#endif
|
||||
|
||||
#if defined(DO_TABLES) && defined(FIXED_TABLES)
|
||||
#if defined(DO_TABLES) && defined(STATIC_TABLES)
|
||||
#define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256] = b(e)
|
||||
#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] = { b(e), b(f), b(g), b(h) }
|
||||
EXTERN ALIGN CONST uint_32t t_dec(r,c)[RC_LENGTH] = rc_data(w0);
|
||||
EXTERN ALIGN CONST uint32_t t_dec(r,c)[RC_LENGTH] = rc_data(w0);
|
||||
#else
|
||||
#define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256]
|
||||
#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256]
|
||||
EXTERN ALIGN CONST uint_32t t_dec(r,c)[RC_LENGTH];
|
||||
EXTERN ALIGN CONST uint32_t t_dec(r,c)[RC_LENGTH];
|
||||
#endif
|
||||
|
||||
#if defined( SBX_SET )
|
||||
d_1(uint_8t, t_dec(s,box), sb_data, h0);
|
||||
d_1(uint8_t, t_dec(s,box), sb_data, h0);
|
||||
#endif
|
||||
#if defined( ISB_SET )
|
||||
d_1(uint_8t, t_dec(i,box), isb_data, h0);
|
||||
d_1(uint8_t, t_dec(i,box), isb_data, h0);
|
||||
#endif
|
||||
|
||||
#if defined( FT1_SET )
|
||||
d_1(uint_32t, t_dec(f,n), sb_data, u0);
|
||||
d_1(uint32_t, t_dec(f,n), sb_data, u0);
|
||||
#endif
|
||||
#if defined( FT4_SET )
|
||||
d_4(uint_32t, t_dec(f,n), sb_data, u0, u1, u2, u3);
|
||||
d_4(uint32_t, t_dec(f,n), sb_data, u0, u1, u2, u3);
|
||||
#endif
|
||||
|
||||
#if defined( FL1_SET )
|
||||
d_1(uint_32t, t_dec(f,l), sb_data, w0);
|
||||
d_1(uint32_t, t_dec(f,l), sb_data, w0);
|
||||
#endif
|
||||
#if defined( FL4_SET )
|
||||
d_4(uint_32t, t_dec(f,l), sb_data, w0, w1, w2, w3);
|
||||
d_4(uint32_t, t_dec(f,l), sb_data, w0, w1, w2, w3);
|
||||
#endif
|
||||
|
||||
#if defined( IT1_SET )
|
||||
d_1(uint_32t, t_dec(i,n), isb_data, v0);
|
||||
d_1(uint32_t, t_dec(i,n), isb_data, v0);
|
||||
#endif
|
||||
#if defined( IT4_SET )
|
||||
d_4(uint_32t, t_dec(i,n), isb_data, v0, v1, v2, v3);
|
||||
d_4(uint32_t, t_dec(i,n), isb_data, v0, v1, v2, v3);
|
||||
#endif
|
||||
|
||||
#if defined( IL1_SET )
|
||||
d_1(uint_32t, t_dec(i,l), isb_data, w0);
|
||||
d_1(uint32_t, t_dec(i,l), isb_data, w0);
|
||||
#endif
|
||||
#if defined( IL4_SET )
|
||||
d_4(uint_32t, t_dec(i,l), isb_data, w0, w1, w2, w3);
|
||||
d_4(uint32_t, t_dec(i,l), isb_data, w0, w1, w2, w3);
|
||||
#endif
|
||||
|
||||
#if defined( LS1_SET )
|
||||
#if defined( FL1_SET )
|
||||
#undef LS1_SET
|
||||
#else
|
||||
d_1(uint_32t, t_dec(l,s), sb_data, w0);
|
||||
d_1(uint32_t, t_dec(l,s), sb_data, w0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -162,15 +155,15 @@ EXTERN ALIGN CONST uint_32t t_dec(r,c)[RC_LENGTH];
|
||||
#if defined( FL4_SET )
|
||||
#undef LS4_SET
|
||||
#else
|
||||
d_4(uint_32t, t_dec(l,s), sb_data, w0, w1, w2, w3);
|
||||
d_4(uint32_t, t_dec(l,s), sb_data, w0, w1, w2, w3);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined( IM1_SET )
|
||||
d_1(uint_32t, t_dec(i,m), mm_data, v0);
|
||||
d_1(uint32_t, t_dec(i,m), mm_data, v0);
|
||||
#endif
|
||||
#if defined( IM4_SET )
|
||||
d_4(uint_32t, t_dec(i,m), mm_data, v0, v1, v2, v3);
|
||||
d_4(uint32_t, t_dec(i,m), mm_data, v0, v1, v2, v3);
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
@@ -1,28 +1,21 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
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 Date: 20/12/2007
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 25/09/2018
|
||||
*/
|
||||
|
||||
// An example of the use of AES (Rijndael) for file encryption. This code
|
||||
@@ -124,6 +117,24 @@
|
||||
#include "aes.h"
|
||||
#include "rdtsc.h"
|
||||
|
||||
#if !defined( _MSC_VER )
|
||||
// substitute for MSVC fopen_s() on Unix/Linux
|
||||
int fopen_s(FILE** pFile, const char *filename, const char *mode)
|
||||
{
|
||||
char ul_name[64], *d = ul_name;
|
||||
const char *s = filename;
|
||||
FILE * fp;
|
||||
|
||||
do{
|
||||
*d++ = (char)(*s == '\\' ? '/' : *s);
|
||||
}
|
||||
while(*s++);
|
||||
|
||||
*pFile = fp = fopen(ul_name, mode);
|
||||
return fp == NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define BLOCK_LEN 16
|
||||
|
||||
#define OK 0
|
||||
@@ -166,8 +177,8 @@ int encfile(FILE *fin, FILE *fout, aes_encrypt_ctx ctx[1])
|
||||
{ unsigned char dbuf[3 * BLOCK_LEN];
|
||||
unsigned long i, len, wlen = BLOCK_LEN;
|
||||
|
||||
// When ciphertext stealing is used, we three ciphertext blocks so
|
||||
// we use a buffer that is three times the block length. The buffer
|
||||
// When ciphertext stealing is used, we need three ciphertext blocks
|
||||
// so we use a buffer that is three times the block length. The buffer
|
||||
// pointers b1, b2 and b3 point to the buffer positions of three
|
||||
// ciphertext blocks, b3 being the most recent and b1 being the
|
||||
// oldest. We start with the IV in b1 and the block to be decrypted
|
||||
@@ -254,8 +265,8 @@ int decfile(FILE *fin, FILE *fout, aes_decrypt_ctx ctx[1])
|
||||
{ unsigned char dbuf[3 * BLOCK_LEN], buf[BLOCK_LEN];
|
||||
unsigned long i, len, wlen = BLOCK_LEN;
|
||||
|
||||
// When ciphertext stealing is used, we three ciphertext blocks so
|
||||
// we use a buffer that is three times the block length. The buffer
|
||||
// When ciphertext stealing is used, we need three ciphertext blocks
|
||||
// so we use a buffer that is three times the block length. The buffer
|
||||
// pointers b1, b2 and b3 point to the buffer positions of three
|
||||
// ciphertext blocks, b3 being the most recent and b1 being the
|
||||
// oldest. We start with the IV in b1 and the block to be decrypted
|
||||
@@ -383,13 +394,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
key_len = i / 2;
|
||||
|
||||
if(!(fin = fopen(argv[1], "rb"))) // try to open the input file
|
||||
if(fopen_s(&fin, argv[1], "rb")) // try to open the input file
|
||||
{
|
||||
printf("The input file: %s could not be opened\n", argv[1]);
|
||||
err = -5; goto exit;
|
||||
}
|
||||
|
||||
if(!(fout = fopen(argv[2], "wb"))) // try to open the output file
|
||||
if(fopen_s(&fout, argv[2], "wb")) // try to open the output file
|
||||
{
|
||||
printf("The output file: %s could not be opened\n", argv[2]);
|
||||
err = -6; goto exit;
|
||||
|
||||
@@ -1,28 +1,21 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
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 Date: 20/12/2007
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 10/09/2018
|
||||
*/
|
||||
|
||||
#ifndef _BRG_ENDIAN_H
|
||||
@@ -31,6 +24,12 @@
|
||||
#define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
|
||||
#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
|
||||
|
||||
/* This is needed when using clang with MSVC to avoid including */
|
||||
/* endian.h and byteswap.h which are not present on Windows */
|
||||
#if defined( _MSC_VER ) && defined( __clang__ )
|
||||
# undef __GNUC__
|
||||
#endif
|
||||
|
||||
/* Include files where endian defines and byteswap functions may reside */
|
||||
#if defined( __sun )
|
||||
# include <sys/isa_defs.h>
|
||||
@@ -49,8 +48,20 @@
|
||||
#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 */
|
||||
/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, ... */
|
||||
/* which seem to encompass most endian symbol definitions */
|
||||
|
||||
#if defined( __ORDER_BIG_ENDIAN__ ) && defined( __ORDER_LITTLE_ENDIAN__ )
|
||||
# if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
# elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#elif defined( __ORDER_BIG_ENDIAN__ )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined( __ORDER_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
|
||||
|
||||
@@ -1,37 +1,21 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
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 Date: 20/12/2007
|
||||
|
||||
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.
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 30/09/2017
|
||||
*/
|
||||
|
||||
#ifndef _BRG_TYPES_H
|
||||
@@ -42,6 +26,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined( _MSC_VER ) && ( _MSC_VER >= 1300 )
|
||||
# include <stddef.h>
|
||||
@@ -49,93 +34,99 @@ extern "C" {
|
||||
#elif defined( __ECOS__ )
|
||||
# define intptr_t unsigned int
|
||||
# define ptrint_t intptr_t
|
||||
#elif defined( __GNUC__ ) && ( __GNUC__ >= 3 )
|
||||
# include <stdint.h>
|
||||
#elif defined( __GNUC__ ) && ( __GNUC__ >= 3 ) && !(defined( __HAIKU__ ) || defined( __VxWorks__ ))
|
||||
# define ptrint_t intptr_t
|
||||
#else
|
||||
# define ptrint_t int
|
||||
#endif
|
||||
|
||||
#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
|
||||
/* define unsigned 8-bit type if not available in stdint.h */
|
||||
#if !defined(UINT8_MAX)
|
||||
typedef unsigned char uint8_t;
|
||||
#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
|
||||
/* define unsigned 16-bit type if not available in stdint.h */
|
||||
#if !defined(UINT16_MAX)
|
||||
typedef unsigned short uint16_t;
|
||||
#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
|
||||
/* define unsigned 32-bit type if not available in stdint.h and define the
|
||||
macro li_32(h) which converts a sequence of eight hexadecimal characters
|
||||
into a 32 bit constant
|
||||
*/
|
||||
#if defined(UINT_MAX) && UINT_MAX == 4294967295u
|
||||
# define li_32(h) 0x##h##u
|
||||
# if !defined(UINT32_MAX)
|
||||
typedef unsigned int uint32_t;
|
||||
# endif
|
||||
#elif defined(ULONG_MAX) && ULONG_MAX == 4294967295u
|
||||
# define li_32(h) 0x##h##ul
|
||||
# if !defined(UINT32_MAX)
|
||||
typedef unsigned long uint32_t;
|
||||
# endif
|
||||
#elif defined( _CRAY )
|
||||
# error This code needs 32-bit data types, which Cray machines do not provide
|
||||
#else
|
||||
# error Please define uint32_t as a 32-bit unsigned integer type in brg_types.h
|
||||
#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 unsigned 64-bit type if not available in stdint.h and define the
|
||||
macro li_64(h) which converts a sequence of eight hexadecimal characters
|
||||
into a 64 bit constant
|
||||
*/
|
||||
#if defined( __BORLANDC__ ) && !defined( __MSDOS__ )
|
||||
# define li_64(h) 0x##h##ui64
|
||||
# if !defined(UINT64_MAX)
|
||||
typedef unsigned __int64 uint64_t;
|
||||
# endif
|
||||
#elif defined( _MSC_VER ) && ( _MSC_VER < 1300 ) /* 1300 == VC++ 7.0 */
|
||||
# define li_64(h) 0x##h##ui64
|
||||
# if !defined(UINT64_MAX)
|
||||
typedef unsigned __int64 uint64_t;
|
||||
# endif
|
||||
#elif defined( __sun ) && defined( ULONG_MAX ) && ULONG_MAX == 0xfffffffful
|
||||
# define li_64(h) 0x##h##ull
|
||||
# if !defined(UINT64_MAX)
|
||||
typedef unsigned long long uint64_t;
|
||||
# endif
|
||||
#elif defined( __MVS__ )
|
||||
# define li_64(h) 0x##h##ull
|
||||
# if !defined(UINT64_MAX)
|
||||
typedef unsigned long long uint64_t;
|
||||
# endif
|
||||
#elif defined( UINT_MAX ) && UINT_MAX > 4294967295u
|
||||
# if UINT_MAX == 18446744073709551615u
|
||||
# define li_64(h) 0x##h##u
|
||||
# if !defined(UINT64_MAX)
|
||||
typedef unsigned int uint64_t;
|
||||
# endif
|
||||
# endif
|
||||
#elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u
|
||||
# if ULONG_MAX == 18446744073709551615ul
|
||||
# define li_64(h) 0x##h##ul
|
||||
# if !defined(UINT64_MAX) && !defined(_UINT64_T)
|
||||
typedef unsigned long uint64_t;
|
||||
# endif
|
||||
# endif
|
||||
#elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u
|
||||
# if ULLONG_MAX == 18446744073709551615ull
|
||||
# define li_64(h) 0x##h##ull
|
||||
typedef unsigned long long uint_64t;
|
||||
# elif defined( __MVS__ )
|
||||
# define BRG_UI64
|
||||
# if !defined(UINT64_MAX) && !defined( __HAIKU__ )
|
||||
typedef unsigned long long uint64_t;
|
||||
# endif
|
||||
# endif
|
||||
#elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u
|
||||
# if ULONG_LONG_MAX == 18446744073709551615ull
|
||||
# define li_64(h) 0x##h##ull
|
||||
typedef unsigned int 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;
|
||||
# if !defined(UINT64_MAX)
|
||||
typedef unsigned long long uint64_t;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined( BRG_UI64 )
|
||||
#if !defined( li_64 )
|
||||
# if defined( NEED_UINT_64T )
|
||||
# error Please define uint_64t as an unsigned 64 bit type in brg_types.h
|
||||
# error Please define uint64_t as an unsigned 64 bit type in brg_types.h
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -173,25 +164,25 @@ extern "C" {
|
||||
/* These defines are used to detect and set the memory alignment of pointers.
|
||||
Note that offsets are in bytes.
|
||||
|
||||
ALIGN_OFFSET(x,n) return the positive or zero offset of
|
||||
the memory addressed by the pointer 'x'
|
||||
from an address that is aligned on an
|
||||
'n' byte boundary ('n' is a power of 2)
|
||||
ALIGN_OFFSET(x,n) return the positive or zero offset of
|
||||
the memory addressed by the pointer 'x'
|
||||
from an address that is aligned on an
|
||||
'n' byte boundary ('n' is a power of 2)
|
||||
|
||||
ALIGN_FLOOR(x,n) return a pointer that points to memory
|
||||
that is aligned on an 'n' byte boundary
|
||||
and is not higher than the memory address
|
||||
pointed to by 'x' ('n' is a power of 2)
|
||||
ALIGN_FLOOR(x,n) return a pointer that points to memory
|
||||
that is aligned on an 'n' byte boundary
|
||||
and is not higher than the memory address
|
||||
pointed to by 'x' ('n' is a power of 2)
|
||||
|
||||
ALIGN_CEIL(x,n) return a pointer that points to memory
|
||||
that is aligned on an 'n' byte boundary
|
||||
and is not lower than the memory address
|
||||
pointed to by 'x' ('n' is a power of 2)
|
||||
ALIGN_CEIL(x,n) return a pointer that points to memory
|
||||
that is aligned on an 'n' byte boundary
|
||||
and is not lower than the memory address
|
||||
pointed to by 'x' ('n' is a power of 2)
|
||||
*/
|
||||
|
||||
#define ALIGN_OFFSET(x,n) (((ptrint_t)(x)) & ((n) - 1))
|
||||
#define ALIGN_FLOOR(x,n) ((uint_8t*)(x) - ( ((ptrint_t)(x)) & ((n) - 1)))
|
||||
#define ALIGN_CEIL(x,n) ((uint_8t*)(x) + (-((ptrint_t)(x)) & ((n) - 1)))
|
||||
#define ALIGN_FLOOR(x,n) ((uint8_t*)(x) - ( ((ptrint_t)(x)) & ((n) - 1)))
|
||||
#define ALIGN_CEIL(x,n) ((uint8_t*)(x) + (-((ptrint_t)(x)) & ((n) - 1)))
|
||||
|
||||
/* These defines are used to declare buffers in a way that allows
|
||||
faster operations on longer variables to be used. In all these
|
||||
@@ -210,10 +201,10 @@ extern "C" {
|
||||
length 'size' bits
|
||||
|
||||
UPTR_CAST(x,size) casts a pointer to a pointer to a
|
||||
varaiable of length 'size' bits
|
||||
variable of length 'size' bits
|
||||
*/
|
||||
|
||||
#define UI_TYPE(size) uint_##size##t
|
||||
#define UI_TYPE(size) uint##size##_t
|
||||
#define UNIT_TYPEDEF(x,size) typedef UI_TYPE(size) x
|
||||
#define BUFR_TYPEDEF(x,size,bsize) typedef UI_TYPE(size) x[bsize / (size >> 3)]
|
||||
#define UNIT_CAST(x,size) ((UI_TYPE(size) )(x))
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/11/2013
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -312,16 +331,21 @@ void rfc3686_test(void)
|
||||
{ aes_encrypt_ctx aes_ctx[1];
|
||||
unsigned char ctr_buf[AES_BLOCK_SIZE];
|
||||
unsigned char obuf[36];
|
||||
unsigned int i;
|
||||
unsigned int i, err = 0;
|
||||
|
||||
for( i = 0 ; i < sizeof(tests) / sizeof(test_str) ; ++i )
|
||||
{
|
||||
aes_encrypt_key(tests[i].key, tests[i].k_len, aes_ctx);
|
||||
rfc3686_init(tests[i].nonce, tests[i].iv, ctr_buf);
|
||||
rfc3686_crypt(tests[i].p_txt, obuf, tests[i].m_len, ctr_buf, aes_ctx);
|
||||
if(memcmp(obuf, tests[i].c_txt, tests[i].m_len) != 0)
|
||||
printf("\nerror");
|
||||
if(memcmp(obuf, tests[i].c_txt, tests[i].m_len) != 0)
|
||||
{
|
||||
err++;
|
||||
printf("error\n");
|
||||
}
|
||||
}
|
||||
if(!err)
|
||||
printf("RFC3686 Tests Passed\n");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
|
||||
@@ -1,33 +1,27 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
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 Date: 20/12/2007
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#define DO_TABLES
|
||||
|
||||
#include <stdio.h>
|
||||
#include "aesaux.h"
|
||||
#include "aesopt.h"
|
||||
|
||||
#define sb_data(w) {\
|
||||
@@ -170,7 +164,7 @@
|
||||
void rtab(FILE *f, unsigned char *h, const unsigned int t[RC_LENGTH])
|
||||
{ int i;
|
||||
|
||||
fprintf(f, "\nuint_32t %s[RC_LENGTH] = \n{", h);
|
||||
fprintf(f, "\nuint32_t %s[RC_LENGTH] = \n{", h);
|
||||
|
||||
for(i = 0; i < RC_LENGTH; ++i)
|
||||
{
|
||||
@@ -188,7 +182,7 @@ void rtab(FILE *f, unsigned char *h, const unsigned int t[RC_LENGTH])
|
||||
void btab_1(FILE *f, unsigned char *h, const unsigned char t[256])
|
||||
{ int i;
|
||||
|
||||
fprintf(f, "\nuint_8t %s[256] = \n{", h);
|
||||
fprintf(f, "\nuint8_t %s[256] = \n{", h);
|
||||
|
||||
for(i = 0; i < 256; ++i)
|
||||
{
|
||||
@@ -206,7 +200,7 @@ void btab_1(FILE *f, unsigned char *h, const unsigned char t[256])
|
||||
void wtab_1(FILE *f, unsigned char *h, const unsigned int t[256])
|
||||
{ int i;
|
||||
|
||||
fprintf(f, "\nuint_32t %s[256] = \n{", h);
|
||||
fprintf(f, "\nuint32_t %s[256] = \n{", h);
|
||||
|
||||
for(i = 0; i < 256; ++i)
|
||||
{
|
||||
@@ -224,7 +218,7 @@ void wtab_1(FILE *f, unsigned char *h, const unsigned int t[256])
|
||||
void wtab_4(FILE *f, unsigned char *h, const unsigned int t[4][256])
|
||||
{ int i, j;
|
||||
|
||||
fprintf(f, "\nuint_32t %s[4][256] = \n{", h);
|
||||
fprintf(f, "\nuint32_t %s[4][256] = \n{", h);
|
||||
|
||||
for(i = 0; i < 4; ++i)
|
||||
{
|
||||
@@ -251,8 +245,13 @@ void wtab_4(FILE *f, unsigned char *h, const unsigned int t[4][256])
|
||||
|
||||
int main(void)
|
||||
{ FILE *f;
|
||||
char *fn = "aestab2.c";
|
||||
|
||||
f = fopen("aestab2.c", "w");
|
||||
if(fopen_s(&f, fn, "w"))
|
||||
{
|
||||
printf("\nCannot open %s for output\n", fn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(f, "\n#include \"aes.h\"\n");
|
||||
fprintf(f, "\n#define RC_LENGTH (5 * (AES_BLOCK_SIZE / 4 - 2))\n");
|
||||
|
||||
@@ -1,263 +0,0 @@
|
||||
|
||||
Private Const BlockLength = 16 ' maximum block length in bytes
|
||||
Private Const BlockLengthMax = 32 ' maximum block length in bytes
|
||||
Private Const KeyLengthMax = 32 ' maximum block length in bytes
|
||||
Private Const KeyScheduleLengthMax = 64 ' maximum key schedule length in bytes
|
||||
|
||||
Private Type EncCtx ' type to hold the AES encryption context data
|
||||
Ekey(0 To KeyScheduleLengthMax - 1) As Long
|
||||
End Type
|
||||
|
||||
Private Type DecCtx ' type to hold the AES decryption context data
|
||||
Ekey(0 To KeyScheduleLengthMax - 1) As Long
|
||||
End Type
|
||||
|
||||
Private Type Key ' type to hold user key data
|
||||
K(0 To KeyLengthMax - 1) As Byte
|
||||
End Type
|
||||
|
||||
Private Type InOut ' type to hold cipher input and output blocks
|
||||
IO(0 To BlockLength - 1) As Byte
|
||||
End Type
|
||||
|
||||
Private Type BigInOut ' type to hold cipher input and output blocks
|
||||
IO(0 To 128 * BlockLength - 1) As Byte
|
||||
End Type
|
||||
|
||||
Rem Change "c:\temp\" in the following lines to the directory path where the AES DLL is located
|
||||
Private Declare Function AesEncryptKey128 Lib "c:\temp\aes.dll" _
|
||||
Alias "_aes_encrypt_key128@8" (K As Key, C As EncCtx) As Integer
|
||||
Private Declare Function AesEncryptKey192 Lib "c:\temp\aes.dll" _
|
||||
Alias "_aes_encrypt_key192@8" (K As Key, C As EncCtx) As Integer
|
||||
Private Declare Function AesEncryptKey256 Lib "c:\temp\aes.dll" _
|
||||
Alias "_aes_encrypt_key256@8" (K As Key, C As EncCtx) As Integer
|
||||
Private Declare Function AesEncryptKey Lib "c:\temp\aes.dll" _
|
||||
Alias "_aes_encrypt_key@12" (K As Key, ByVal N As Integer, C As EncCtx) As Integer
|
||||
Private Declare Function AesEncrypt Lib "c:\temp\aes.dll" _
|
||||
Alias "_aes_encrypt@12" (Ib As InOut, Ob As InOut, C As EncCtx) As Integer
|
||||
Private Declare Function AesDecryptKey128 Lib "c:\temp\aes.dll" _
|
||||
Alias "_aes_decrypt_key128@8" (K As Key, C As DecCtx) As Integer
|
||||
Private Declare Function AesDecryptKey192 Lib "c:\temp\aes.dll" _
|
||||
Alias "_aes_decrypt_key192@8" (K As Key, C As DecCtx) As Integer
|
||||
Private Declare Function AesDecryptKey256 Lib "c:\temp\aes.dll" _
|
||||
Alias "_aes_decrypt_key256@8" (K As Key, C As DecCtx) As Integer
|
||||
Private Declare Function AesDecryptKey Lib "c:\temp\aes.dll" _
|
||||
Alias "_aes_decrypt_key@12" (K As Key, ByVal N As Long, C As DecCtx) As Integer
|
||||
Private Declare Function AesDecrypt Lib "c:\temp\aes.dll" _
|
||||
Alias "_aes_decrypt@12" (Ib As InOut, Ob As InOut, C As DecCtx) As Integer
|
||||
|
||||
Private Declare Function AesModeReset Lib "c:\temp\aes.dll" Alias "_aes_mode_reset@4" _
|
||||
(C As EncCtx) As Integer
|
||||
Private Declare Function AesEcbEncrypt Lib "c:\temp\aes.dll" Alias "_aes_ecb_encrypt@16" _
|
||||
(Ib As BigInOut, Ob As BigInOut, ByVal N As Long, C As EncCtx) As Integer
|
||||
Private Declare Function AesEcbDecrypt Lib "c:\temp\aes.dll" Alias "_aes_ecb_decrypt@16" _
|
||||
(Ib As BigInOut, Ob As BigInOut, ByVal N As Long, C As DecCtx) As Integer
|
||||
Private Declare Function AesCbcEncrypt Lib "c:\temp\aes.dll" Alias "_aes_cbc_encrypt@20" _
|
||||
(Ib As BigInOut, Ob As BigInOut, ByVal N As Long, Iv As InOut, C As EncCtx) As Integer
|
||||
Private Declare Function AesCbcDecrypt Lib "c:\temp\aes.dll" Alias "_aes_cbc_decrypt@20" _
|
||||
(Ib As BigInOut, Ob As BigInOut, ByVal N As Long, Iv As InOut, C As DecCtx) As Integer
|
||||
Private Declare Function AesCfbEncrypt Lib "c:\temp\aes.dll" Alias "_aes_cfb_encrypt@20" _
|
||||
(Ib As BigInOut, Ob As BigInOut, ByVal N As Long, Iv As InOut, C As EncCtx) As Integer
|
||||
Private Declare Function AesCfbDecrypt Lib "c:\temp\aes.dll" Alias "_aes_cfb_decrypt@20" _
|
||||
(Ib As BigInOut, Ob As BigInOut, ByVal N As Long, Iv As InOut, C As EncCtx) As Integer
|
||||
Private Declare Function AesOfbCrypt Lib "c:\temp\aes.dll" Alias "_aes_ofb_crypt@20" _
|
||||
(Ib As BigInOut, Ob As BigInOut, ByVal N As Long, Iv As InOut, C As EncCtx) As Integer
|
||||
Private Declare Function AesCtrCrypt Lib "c:\temp\aes.dll" Alias "_aes_ctr_crypt@24" _
|
||||
(Ib As BigInOut, Ob As BigInOut, ByVal N As Long, Iv As InOut, ByVal CtrFn As Long, C As EncCtx) As Integer
|
||||
|
||||
Private Sub Hex(X As Byte) ' output a byte in hexadecimal format
|
||||
Dim H As Byte
|
||||
H = Int(X / 16)
|
||||
If H < 10 Then Debug.Print Chr(48 + H); Else Debug.Print Chr(87 + H);
|
||||
H = Int(X Mod 16)
|
||||
If H < 10 Then Debug.Print Chr(48 + H); Else Debug.Print Chr(87 + H);
|
||||
End Sub
|
||||
|
||||
Private Sub OutKey(S As String, B As Key, ByVal KeyL As Integer) ' display a key value
|
||||
Debug.Print: Debug.Print S;
|
||||
For i = 0 To KeyL - 1
|
||||
Hex B.K(i)
|
||||
Next i
|
||||
End Sub
|
||||
|
||||
Private Sub OutBlock(S As String, B As InOut) ' display an input/output block
|
||||
Debug.Print: Debug.Print S;
|
||||
For i = 0 To BlockLength - 1
|
||||
Hex B.IO(i)
|
||||
Next i
|
||||
End Sub
|
||||
|
||||
Private Sub OutBigBlock(S As String, B As BigInOut) ' display an input/output block
|
||||
Debug.Print: Debug.Print S;
|
||||
For i = 0 To BlockLength - 1
|
||||
Hex B.IO(i)
|
||||
Next i
|
||||
Debug.Print " ... ";
|
||||
For i = 127 * BlockLength To 128 * BlockLength - 1
|
||||
Hex B.IO(i)
|
||||
Next i
|
||||
End Sub
|
||||
|
||||
Private Sub CtrInc(Ctr As InOut)
|
||||
Ctr.IO(0) = Ctr.IO(0) + 1
|
||||
If (Ctr.IO(0) = 0) Then
|
||||
Ctr.IO(1) = Ctr.IO(1) + 1
|
||||
If (Ctr.IO(1) = 0) Then
|
||||
Ctr.IO(2) = Ctr.IO(2) + 1
|
||||
If (Ctr.IO(3) = 0) Then
|
||||
Ctr.IO(3) = Ctr.IO(3) + 1
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Rem The following Main routine should output the following in the immediate window:
|
||||
Rem Variable Key Length ( 16 )
|
||||
Rem Key = 00000000000000000000000000000000
|
||||
Rem Input = 00000000000000000000000000000000
|
||||
Rem Encrypted Text = 66e94bd4ef8a2c3b884cfa59ca342b2e
|
||||
Rem Decrypted Text = 00000000000000000000000000000000
|
||||
Rem Variable Key Length ( 24 )
|
||||
Rem Key = 000000000000000000000000000000000000000000000000
|
||||
Rem Input = 00000000000000000000000000000000
|
||||
Rem Encrypted Text = aae06992acbf52a3e8f4a96ec9300bd7
|
||||
Rem Decrypted Text = 00000000000000000000000000000000
|
||||
Rem Variable Key Length ( 32 )
|
||||
Rem Key = 0000000000000000000000000000000000000000000000000000000000000000
|
||||
Rem Input = 00000000000000000000000000000000
|
||||
Rem Encrypted Text = dc95c078a2408989ad48a21492842087
|
||||
Rem Decrypted Text = 00000000000000000000000000000000
|
||||
Rem Fixed Key Length ( 128 )
|
||||
Rem Key = 00000000000000000000000000000000
|
||||
Rem Input = 00000000000000000000000000000000
|
||||
Rem Encrypted Text = 66e94bd4ef8a2c3b884cfa59ca342b2e
|
||||
Rem Decrypted Text = 00000000000000000000000000000000
|
||||
Rem Fixed Key Length ( 192 )
|
||||
Rem Key = 000000000000000000000000000000000000000000000000
|
||||
Rem Input = 00000000000000000000000000000000
|
||||
Rem Encrypted Text = aae06992acbf52a3e8f4a96ec9300bd7
|
||||
Rem Decrypted Text = 00000000000000000000000000000000
|
||||
Rem Fixed Key Length ( 256 )
|
||||
Rem Key = 0000000000000000000000000000000000000000000000000000000000000000
|
||||
Rem Input = 00000000000000000000000000000000
|
||||
Rem Encrypted Text = dc95c078a2408989ad48a21492842087
|
||||
Rem Decrypted Text = 00000000000000000000000000000000
|
||||
|
||||
Sub Main()
|
||||
Dim Key As Key ' all these variables are initialised
|
||||
Dim Ib As InOut, Ob As InOut, Rb As InOut ' to zero by VBA
|
||||
Dim Iv1 As InOut, Iv2 As InOut
|
||||
Dim Ecx As EncCtx
|
||||
Dim Dcx As DecCtx
|
||||
Dim RetVal As Integer
|
||||
|
||||
For KeyL = 16 To 32 Step 8
|
||||
Debug.Print "Variable Key Length ("; KeyL; ")";
|
||||
OutKey "Key = ", Key, KeyL
|
||||
OutBlock "Input = ", Ib
|
||||
RetVal = AesEncryptKey(Key, KeyL, Ecx) ' set an all zero encryption key
|
||||
RetVal = AesEncrypt(Ib, Ob, Ecx) ' encrypt Ib to Ob
|
||||
OutBlock "Encrypted Text = ", Ob
|
||||
RetVal = AesDecryptKey(Key, KeyL, Dcx) ' set an all zero decryption key
|
||||
RetVal = AesDecrypt(Ob, Rb, Dcx) ' decrypt Ob to Rb
|
||||
OutBlock "Decrypted Text = ", Rb
|
||||
Debug.Print
|
||||
Next KeyL
|
||||
|
||||
Debug.Print
|
||||
KeyL = 128: Debug.Print "Fixed Key Length ("; KeyL; ")";
|
||||
OutKey "Key = ", Key, 16
|
||||
OutBlock "Input = ", Ib
|
||||
RetVal = AesEncryptKey128(Key, Ecx) ' set an all zero encryption key
|
||||
RetVal = AesEncrypt(Ib, Ob, Ecx) ' encrypt Ib to Ob
|
||||
OutBlock "Encrypted Text = ", Ob
|
||||
RetVal = AesDecryptKey128(Key, Dcx) ' set an all zero decryption key
|
||||
RetVal = AesDecrypt(Ob, Rb, Dcx) ' decrypt Ob to Rb
|
||||
OutBlock "Decrypted Text = ", Rb
|
||||
Debug.Print
|
||||
|
||||
Debug.Print
|
||||
KeyL = 192: Debug.Print "Fixed Key Length ("; KeyL; ")";
|
||||
OutKey "Key = ", Key, 24
|
||||
OutBlock "Input = ", Ib
|
||||
RetVal = AesEncryptKey192(Key, Ecx) ' set an all zero encryption key
|
||||
RetVal = AesEncrypt(Ib, Ob, Ecx) ' encrypt Ib to Ob
|
||||
OutBlock "Encrypted Text = ", Ob
|
||||
RetVal = AesDecryptKey192(Key, Dcx) ' set an all zero decryption key
|
||||
RetVal = AesDecrypt(Ob, Rb, Dcx) ' decrypt Ob to Rb
|
||||
OutBlock "Decrypted Text = ", Rb
|
||||
Debug.Print
|
||||
|
||||
Debug.Print
|
||||
KeyL = 256: Debug.Print "Fixed Key Length ("; KeyL; ")";
|
||||
OutKey "Key = ", Key, 32
|
||||
OutBlock "Input = ", Ib
|
||||
RetVal = AesEncryptKey256(Key, Ecx) ' set an all zero encryption key
|
||||
RetVal = AesEncrypt(Ib, Ob, Ecx) ' encrypt Ib to Ob
|
||||
OutBlock "Encrypted Text = ", Ob
|
||||
RetVal = AesDecryptKey256(Key, Dcx) ' set an all zero decryption key
|
||||
RetVal = AesDecrypt(Ob, Rb, Dcx) ' decrypt Ob to Rb
|
||||
OutBlock "Decrypted Text = ", Rb
|
||||
Debug.Print
|
||||
|
||||
Debug.Print
|
||||
KeyL = 128: Debug.Print "Fixed Key Length ("; KeyL; ")";
|
||||
OutKey "Key = ", Key, 16
|
||||
OutBlock "Input = ", Ib
|
||||
RetVal = AesEncryptKey128(Key, Ecx) ' set an all zero encryption key
|
||||
OutBlock "Encrypted Text = ", Ob
|
||||
RetVal = AesDecryptKey128(Key, Dcx) ' set an all zero decryption key
|
||||
OutBlock "Decrypted Text = ", Rb
|
||||
Debug.Print
|
||||
|
||||
Debug.Print
|
||||
KeyL = 128: Debug.Print "Fixed Key Length ("; KeyL; ")";
|
||||
OutKey "Key = ", Key, 16
|
||||
RetVal = AesEncryptKey128(Key, Ecx) ' set an all zero encryption key
|
||||
RetVal = AesDecryptKey128(Key, Dcx) ' set an all zero decryption key
|
||||
Dim Pt1 As BigInOut, Pt2 As BigInOut, Ct As BigInOut
|
||||
|
||||
For i = 0 To 128 * BlockLength - 1
|
||||
Pt1.IO(i) = i Mod 256
|
||||
Next i
|
||||
|
||||
OutBigBlock "ECB Input = ", Pt1
|
||||
RetVal = AesEcbEncrypt(Pt1, Ct, 128 * BlockLength, Ecx)
|
||||
OutBigBlock "Encrypted Text = ", Ct
|
||||
RetVal = AesEcbDecrypt(Ct, Pt2, 128 * BlockLength, Dcx)
|
||||
OutBigBlock "Decrypted Text = ", Pt2
|
||||
Debug.Print
|
||||
|
||||
OutBigBlock "CBC Mode Input = ", Pt1
|
||||
RetVal = AesCbcEncrypt(Pt1, Ct, 128 * BlockLength, Iv1, Ecx)
|
||||
OutBigBlock "Encrypted Text = ", Ct
|
||||
RetVal = AesCbcDecrypt(Ct, Pt2, 128 * BlockLength, Iv2, Dcx)
|
||||
OutBigBlock "Decrypted Text = ", Pt2
|
||||
Debug.Print
|
||||
|
||||
OutBigBlock "CFB Mode Input = ", Pt1
|
||||
RetVal = AesCfbEncrypt(Pt1, Ct, 128 * BlockLength, Iv1, Ecx)
|
||||
OutBigBlock "Encrypted Text = ", Ct
|
||||
RetVal = AesCfbDecrypt(Ct, Pt2, 128 * BlockLength, Iv2, Ecx)
|
||||
OutBigBlock "Decrypted Text = ", Pt2
|
||||
Debug.Print
|
||||
|
||||
OutBigBlock "OFB Mode Input = ", Pt1
|
||||
RetVal = AesOfbCrypt(Pt1, Ct, 128 * BlockLength, Iv1, Ecx)
|
||||
OutBigBlock "Encrypted Text = ", Ct
|
||||
RetVal = AesOfbCrypt(Ct, Pt2, 128 * BlockLength, Iv2, Ecx)
|
||||
OutBigBlock "Decrypted Text = ", Pt2
|
||||
Debug.Print
|
||||
|
||||
#If False Then
|
||||
Rem CTR Mode is not working because of a problem with the 'AddressOf' operator
|
||||
OutBigBlock "CTR Mode Input = ", Pt1
|
||||
RetVal = AesCtrCrypt(Pt1, Ct, 128 * BlockLength, Iv1, AddressOf CtrInc, Ecx)
|
||||
OutBigBlock "Encrypted Text = ", Ct
|
||||
RetVal = AesCtrCrypt(Ct, Pt2, 128 * BlockLength, Iv2, AddressOf CtrInc, Ecx)
|
||||
OutBigBlock "Decrypted Text = ", Pt2
|
||||
Debug.Print
|
||||
#End If
|
||||
|
||||
Debug.Print
|
||||
End Sub
|
||||
Binary file not shown.
@@ -1,158 +0,0 @@
|
||||
|
||||
Support for the VIA Nehemiah Advanced Cryptography Engine (ACE)
|
||||
---------------------------------------------------------------
|
||||
|
||||
A. Introduction
|
||||
|
||||
The AES code now supports the VIA ACE engine. The engine is invoked by the
|
||||
multiple block AES modes calls in aes_modes.c and not by the basic AES code.
|
||||
|
||||
The define USE_VIA_ACE_IF_PRESENT is defined if VIA ACE detection and use is
|
||||
required with fallback to the normal AES code if it is not present.
|
||||
|
||||
The define ASSUME_VIA_ACE_PRESENT is used when it is known that the VIA ACE
|
||||
engine will always be present. Note, however, that this code will not work
|
||||
correctly if the VIA ACE engine is either not present or turned off.
|
||||
|
||||
To enable ACE support the appropriate defines in section 2 of the options in
|
||||
aesopt.h must be set. If ACE support is required then key scheduling must
|
||||
use the C code so only the generic C code in Win32 mode, ASM_X86_V1C and
|
||||
ASM_X86_V2C assembler code can be used (i.e ASM_X86_V2 and ASM_AMD64_C do
|
||||
NOT support VIA ACE).
|
||||
|
||||
B. Using ACE
|
||||
|
||||
ACE is used in the code that implements the subroutines used for the multiple
|
||||
block AES modes defined in aes_modes.h:
|
||||
|
||||
// used to reset modes to their start point without entering a new key
|
||||
AES_RETURN aes_mode_reset(aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, const aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, const aes_decrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, const aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, const aes_decrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
|
||||
|
||||
#define aes_ofb_encrypt aes_ofb_crypt
|
||||
#define aes_ofb_decrypt aes_ofb_crypt
|
||||
|
||||
AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
|
||||
|
||||
typedef void cbuf_inc(unsigned char *cbuf);
|
||||
|
||||
#define aes_ctr_encrypt aes_ctr_crypt
|
||||
#define aes_ctr_decrypt aes_ctr_crypt
|
||||
|
||||
AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1]);
|
||||
|
||||
Note that the single block AES calls defined in aes.h:
|
||||
|
||||
AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out,
|
||||
const aes_decrypt_ctx cx[1]);
|
||||
|
||||
do NOT provide ACE support and should not be used if the ACE engine is
|
||||
available and ACE support is required.
|
||||
|
||||
C. Constraints and Optimisation
|
||||
|
||||
There are several constraints that have to be observed when ACE is used if
|
||||
the best performance is to be achieved:
|
||||
|
||||
1. As usual the appropriate key set up subroutine must be called before any
|
||||
of the above subroutines are used.
|
||||
|
||||
2. The AES contexts - aes_encryption_ctx and aes_decryption_ctx - used with
|
||||
these subroutines MUST be 16 byte aligned. Failure to align AES contexts
|
||||
will often cause memory alignment exceptions.
|
||||
|
||||
3. The buffers used for inputs, outputs and IVs do not need to be 16 byte
|
||||
aligned but the speed that is achieved will be much higher if this can be
|
||||
arranged. In a flat address space (as now typical in 32-bit systems) this
|
||||
means that: (a) that the lower nibble of all buffer addresses must be
|
||||
zero, and (b) the compiler used must arrange to load the data and stack
|
||||
segments on 16 byte address boundaries. The Microsoft VC++ compiler can
|
||||
align all variables in this way (see the example macros for doing this in
|
||||
aes_via_ace.txt). However it seems that the GCC compiler will only do this
|
||||
for static global variables but not for variables placed on the stack, that
|
||||
is local variables.
|
||||
|
||||
4. The data length in bytes (len) in calls to the ECB and CBC subroutines
|
||||
must be a multiple of the 16 byte block length. An error return will
|
||||
occur if this is not so.
|
||||
|
||||
5. The data length in all calls to the CFB, OFB and CTR subroutines must also
|
||||
be a multiple of 16 bytes if the VIA ACE engine is to be used. Otherwise
|
||||
these lengths can be of any value but the subroutines will only proceed at
|
||||
full speed for lengths that are multiples of 16 bytes. The CFB, OFB and
|
||||
CTR subroutines are incremental, with subsequent calls continuing from
|
||||
where previous calls finished. The subroutine aes_mode_reset() can be used
|
||||
to restart a mode without a key change but is not needed after a new key is
|
||||
entered. Such a reset is not needed when the data lengths in all individual
|
||||
calls to the AES mode subroutines are multiples of 16 bytes.
|
||||
|
||||
6. Note that the AES context contains mode details so only one type of mode
|
||||
can be run from a context at any one time. A reset is necessary if a new
|
||||
mode is used without a new context or a new key.
|
||||
|
||||
D. Expected Speeds
|
||||
|
||||
The speeds that have been obtained using a 1.2 GHz VIA C3 processor with
|
||||
this code are given below (note that since CTR mode is not available in
|
||||
the VIA hardware it is not present in the aligned timing figures):
|
||||
|
||||
AES Timing (Cycles/Byte) with the VIA ACE Engine (aligned in C)
|
||||
Mode Blocks: 1 10 100 1000 Peak Throughput
|
||||
ecb encrypt 8.25 1.36 0.69 0.63 1.9 Gbytes/second
|
||||
ecb decrypt 8.75 1.41 0.70 0.64 1.9 Gbytes/second
|
||||
cbc encrypt 11.56 2.41 1.47 1.38 870 Mbytes/second
|
||||
cbc decrypt 12.37 2.38 1.47 1.38 870 Mbytes/second
|
||||
cfb encrypt 11.93 2.46 1.48 1.38 870 Mbytes/second
|
||||
cfb decrypt 12.18 2.36 1.47 1.38 870 Mbytes/second
|
||||
ofb encrypt 13.31 3.88 2.92 2.82 425 Mbytes/second
|
||||
ofb decrypt 13.31 3.88 2.92 2.82 425 Mbytes/second
|
||||
|
||||
AES Timing (Cycles/Byte) with the VIA ACE Engine (unaligned in C)
|
||||
Mode Blocks: 1 10 100 1000 Peak Throughput
|
||||
ecb encrypt 17.68 4.31 3.15 3.05 390 Mbytes/second
|
||||
ecb decrypt 18.12 4.36 3.17 3.06 390 Mbytes/second
|
||||
cbc encrypt 20.68 5.70 4.39 4.27 280 Mbytes/second
|
||||
cbc decrypt 21.87 5.75 4.34 4.21 285 Mbytes/second
|
||||
cfb encrypt 21.06 5.81 4.43 4.31 280 Mbytes/second
|
||||
cfb decrypt 21.37 5.72 4.36 4.24 285 Mbytes/second
|
||||
ofb encrypt 22.43 7.23 5.85 5.72 210 Mbytes/second
|
||||
ofb decrypt 22.43 7.34 5.86 5.73 210 Mbytes/second
|
||||
ctr encrypt 16.43 6.90 6.00 5.89 205 Mbytes/second
|
||||
ctr decrypt 16.43 6.90 6.00 5.89 205 Mbytes/second
|
||||
|
||||
AES Timing (Cycles/Byte) with the VIA ACE Engine (unaligned assembler)
|
||||
Mode Blocks: 1 10 100 1000 Peak Throughput
|
||||
ecb encrypt 11.87 2.89 1.91 1.83 660 Mbytes/second
|
||||
ecb decrypt 12.18 2.83 1.97 1.87 640 Mbytes/second
|
||||
cbc encrypt 14.87 4.13 3.11 3.01 400 Mbytes/second
|
||||
cbc decrypt 14.43 3.87 2.89 2.80 430 Mbytes/second
|
||||
cfb encrypt 14.75 4.12 3.10 3.01 400 Mbytes/second
|
||||
cfb decrypt 14.12 4.10 2.88 2.79 430 Mbytes/second
|
||||
ofb encrypt 15.25 5.36 4.37 4.27 280 Mbytes/second
|
||||
ofb decrypt 15.25 5.36 4.36 4.27 280 Mbytes/second
|
||||
ctr encrypt 13.31 4.79 4.01 3.94 305 Mbytes/second
|
||||
ctr decrypt 13.31 4.79 4.01 3.94 305 Mbytes/second
|
||||
|
||||
Brian Gladman, Worcester, UK
|
||||
@@ -1,14 +1,9 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := sha
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
sha1.c \
|
||||
sha2.c \
|
||||
hmac.c
|
||||
|
||||
LOCAL_CFLAGS := -DUSE_SHA256
|
||||
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
@@ -1,49 +1,45 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The free distribution and use of this software in both source and binary
|
||||
form is allowed (with or without changes) provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. distributions of this source code include the above copyright
|
||||
notice, this list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
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
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#ifndef BRG_ENDIAN_H
|
||||
#define BRG_ENDIAN_H
|
||||
#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) */
|
||||
|
||||
/* This is needed when using clang with MSVC to avoid including */
|
||||
/* endian.h and byteswap.h which are not present on Windows */
|
||||
#if defined( _MSC_VER ) && defined( __clang__ )
|
||||
# undef __GNUC__
|
||||
#endif
|
||||
|
||||
/* Include files where endian defines and byteswap functions may reside */
|
||||
#if defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )
|
||||
#if defined( __sun )
|
||||
# include <sys/isa_defs.h>
|
||||
#elif 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__ )
|
||||
# if !defined( __MINGW32__ ) && !defined( _AIX )
|
||||
# include <endian.h>
|
||||
# if !defined( __BEOS__ )
|
||||
# include <byteswap.h>
|
||||
@@ -120,7 +116,7 @@
|
||||
defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \
|
||||
defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \
|
||||
defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \
|
||||
defined( THINK_C ) || defined( __VMCMS__ )
|
||||
defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
|
||||
#elif 0 /* **** EDIT HERE IF NECESSARY **** */
|
||||
|
||||
@@ -1,128 +1,133 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2006, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The free distribution and use of this software in both source and binary
|
||||
form is allowed (with or without changes) provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. distributions of this source code include the above copyright
|
||||
notice, this list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
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.
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 30/09/2017
|
||||
*/
|
||||
|
||||
#ifndef BRG_TYPES_H
|
||||
#define BRG_TYPES_H
|
||||
#ifndef _BRG_TYPES_H
|
||||
#define _BRG_TYPES_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.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
|
||||
#if defined( _MSC_VER ) && ( _MSC_VER >= 1300 )
|
||||
# include <stddef.h>
|
||||
# define ptrint_t intptr_t
|
||||
#elif defined( __ECOS__ )
|
||||
# define intptr_t unsigned int
|
||||
# define ptrint_t intptr_t
|
||||
#elif defined( __GNUC__ ) && ( __GNUC__ >= 3 ) && !(defined( __HAIKU__ ) || defined( __VxWorks__ ))
|
||||
# define ptrint_t intptr_t
|
||||
#else
|
||||
# define ptrint_t int
|
||||
#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
|
||||
/* define unsigned 8-bit type if not available in stdint.h */
|
||||
#if !defined(UINT8_MAX)
|
||||
typedef unsigned char uint8_t;
|
||||
#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
|
||||
/* define unsigned 16-bit type if not available in stdint.h */
|
||||
#if !defined(UINT16_MAX)
|
||||
typedef unsigned short uint16_t;
|
||||
#endif
|
||||
|
||||
#ifndef BRG_UI64
|
||||
# if defined( __BORLANDC__ ) && !defined( __MSDOS__ )
|
||||
# define BRG_UI64
|
||||
/* define unsigned 32-bit type if not available in stdint.h and define the
|
||||
macro li_32(h) which converts a sequence of eight hexadecimal characters
|
||||
into a 32 bit constant
|
||||
*/
|
||||
#if defined(UINT_MAX) && UINT_MAX == 4294967295u
|
||||
# define li_32(h) 0x##h##u
|
||||
# if !defined(UINT32_MAX)
|
||||
typedef unsigned int uint32_t;
|
||||
# endif
|
||||
#elif defined(ULONG_MAX) && ULONG_MAX == 4294967295u
|
||||
# define li_32(h) 0x##h##ul
|
||||
# if !defined(UINT32_MAX)
|
||||
typedef unsigned long uint32_t;
|
||||
# endif
|
||||
#elif defined( _CRAY )
|
||||
# error This code needs 32-bit data types, which Cray machines do not provide
|
||||
#else
|
||||
# error Please define uint32_t as a 32-bit unsigned integer type in brg_types.h
|
||||
#endif
|
||||
|
||||
/* define unsigned 64-bit type if not available in stdint.h and define the
|
||||
macro li_64(h) which converts a sequence of eight hexadecimal characters
|
||||
into a 64 bit constant
|
||||
*/
|
||||
#if defined( __BORLANDC__ ) && !defined( __MSDOS__ )
|
||||
# define li_64(h) 0x##h##ui64
|
||||
# if !defined(UINT64_MAX)
|
||||
typedef unsigned __int64 uint64_t;
|
||||
# endif
|
||||
#elif defined( _MSC_VER ) && ( _MSC_VER < 1300 ) /* 1300 == VC++ 7.0 */
|
||||
# define li_64(h) 0x##h##ui64
|
||||
# if !defined(UINT64_MAX)
|
||||
typedef unsigned __int64 uint64_t;
|
||||
# endif
|
||||
#elif defined( __sun ) && defined( ULONG_MAX ) && ULONG_MAX == 0xfffffffful
|
||||
# define li_64(h) 0x##h##ull
|
||||
# if !defined(UINT64_MAX)
|
||||
typedef unsigned long long uint64_t;
|
||||
# endif
|
||||
#elif defined( __MVS__ )
|
||||
# define li_64(h) 0x##h##ull
|
||||
# if !defined(UINT64_MAX)
|
||||
typedef unsigned long long uint64_t;
|
||||
# endif
|
||||
#elif defined( UINT_MAX ) && UINT_MAX > 4294967295u
|
||||
# if UINT_MAX == 18446744073709551615u
|
||||
# define li_64(h) 0x##h##u
|
||||
# if !defined(UINT64_MAX)
|
||||
typedef unsigned int uint64_t;
|
||||
# endif
|
||||
# endif
|
||||
#elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u
|
||||
# if ULONG_MAX == 18446744073709551615ul
|
||||
# define li_64(h) 0x##h##ul
|
||||
# if !defined(UINT64_MAX) && !defined(_UINT64_T)
|
||||
typedef unsigned long uint64_t;
|
||||
# endif
|
||||
# endif
|
||||
#elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u
|
||||
# if ULLONG_MAX == 18446744073709551615ull
|
||||
# define li_64(h) 0x##h##ull
|
||||
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
|
||||
# if !defined(UINT64_MAX) && !defined( __HAIKU__ )
|
||||
typedef unsigned long long uint64_t;
|
||||
# endif
|
||||
# endif
|
||||
#elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u
|
||||
# if ULONG_LONG_MAX == 18446744073709551615ull
|
||||
# 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;
|
||||
# if !defined(UINT64_MAX)
|
||||
typedef unsigned long long uint64_t;
|
||||
# endif
|
||||
# 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
|
||||
#if !defined( li_64 )
|
||||
# if defined( NEED_UINT_64T )
|
||||
# error Please define uint64_t as an unsigned 64 bit type in brg_types.h
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef RETURN_VALUES
|
||||
@@ -156,26 +161,54 @@ extern "C" {
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* These defines are used to detect and set the memory alignment of pointers.
|
||||
Note that offsets are in bytes.
|
||||
|
||||
ALIGN_OFFSET(x,n) return the positive or zero offset of
|
||||
the memory addressed by the pointer 'x'
|
||||
from an address that is aligned on an
|
||||
'n' byte boundary ('n' is a power of 2)
|
||||
|
||||
ALIGN_FLOOR(x,n) return a pointer that points to memory
|
||||
that is aligned on an 'n' byte boundary
|
||||
and is not higher than the memory address
|
||||
pointed to by 'x' ('n' is a power of 2)
|
||||
|
||||
ALIGN_CEIL(x,n) return a pointer that points to memory
|
||||
that is aligned on an 'n' byte boundary
|
||||
and is not lower than the memory address
|
||||
pointed to by 'x' ('n' is a power of 2)
|
||||
*/
|
||||
|
||||
#define ALIGN_OFFSET(x,n) (((ptrint_t)(x)) & ((n) - 1))
|
||||
#define ALIGN_FLOOR(x,n) ((uint8_t*)(x) - ( ((ptrint_t)(x)) & ((n) - 1)))
|
||||
#define ALIGN_CEIL(x,n) ((uint8_t*)(x) + (-((ptrint_t)(x)) & ((n) - 1)))
|
||||
|
||||
/* 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
|
||||
defines 'size' must be a power of 2 and >= 8. NOTE that the
|
||||
buffer size is in bytes but the type length is in bits
|
||||
|
||||
dec_unit_type(size,x) declares a variable 'x' of length
|
||||
UNIT_TYPEDEF(x,size) declares a variable 'x' of length
|
||||
'size' bits
|
||||
|
||||
dec_bufr_type(size,bsize,x) declares a buffer 'x' of length 'bsize'
|
||||
BUFR_TYPEDEF(x,size,bsize) 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
|
||||
UNIT_CAST(x,size) casts a variable to a type of
|
||||
length 'size' bits
|
||||
|
||||
UPTR_CAST(x,size) casts a pointer to a pointer to a
|
||||
variable 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))
|
||||
#define UI_TYPE(size) uint##size##_t
|
||||
#define UNIT_TYPEDEF(x,size) typedef UI_TYPE(size) x
|
||||
#define BUFR_TYPEDEF(x,size,bsize) typedef UI_TYPE(size) x[bsize / (size >> 3)]
|
||||
#define UNIT_CAST(x,size) ((UI_TYPE(size) )(x))
|
||||
#define UPTR_CAST(x,size) ((UI_TYPE(size)*)(x))
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
||||
@@ -1,35 +1,23 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The free distribution and use of this software in both source and binary
|
||||
form is allowed (with or without changes) provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. distributions of this source code include the above copyright
|
||||
notice, this list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
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;
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
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 Date: 26/08/2003
|
||||
|
||||
This is an implementation of HMAC, the FIPS standard keyed hash function
|
||||
This is an implementation of HMAC, the FIPS standard keyed hash function
|
||||
*/
|
||||
|
||||
#include "hmac.h"
|
||||
@@ -40,32 +28,109 @@ extern "C"
|
||||
#endif
|
||||
|
||||
/* initialise the HMAC context to zero */
|
||||
void hmac_sha_begin(hmac_ctx cx[1])
|
||||
int hmac_sha_begin(enum hmac_hash hash, hmac_ctx cx[1])
|
||||
{
|
||||
memset(cx, 0, sizeof(hmac_ctx));
|
||||
switch(hash)
|
||||
{
|
||||
#ifdef SHA_1
|
||||
case HMAC_SHA1:
|
||||
cx->f_begin = sha1_begin;
|
||||
cx->f_hash = sha1_hash;
|
||||
cx->f_end = sha1_end;
|
||||
cx->input_len = SHA1_BLOCK_SIZE;
|
||||
cx->output_len = SHA1_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef SHA_224
|
||||
case HMAC_SHA224:
|
||||
cx->f_begin = sha224_begin;
|
||||
cx->f_hash = sha224_hash;
|
||||
cx->f_end = sha224_end;
|
||||
cx->input_len = SHA224_BLOCK_SIZE;
|
||||
cx->output_len = SHA224_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef SHA_256
|
||||
case HMAC_SHA256:
|
||||
cx->f_begin = sha256_begin;
|
||||
cx->f_hash = sha256_hash;
|
||||
cx->f_end = sha256_end;
|
||||
cx->input_len = SHA256_BLOCK_SIZE;
|
||||
cx->output_len = SHA256_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef SHA_384
|
||||
case HMAC_SHA384:
|
||||
cx->f_begin = sha384_begin;
|
||||
cx->f_hash = sha384_hash;
|
||||
cx->f_end = sha384_end;
|
||||
cx->input_len = SHA384_BLOCK_SIZE;
|
||||
cx->output_len = SHA384_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef SHA_512
|
||||
case HMAC_SHA512:
|
||||
cx->f_begin = sha512_begin;
|
||||
cx->f_hash = sha512_hash;
|
||||
cx->f_end = sha512_end;
|
||||
cx->input_len = SHA512_BLOCK_SIZE;
|
||||
cx->output_len = SHA512_DIGEST_SIZE;
|
||||
break;
|
||||
case HMAC_SHA512_256:
|
||||
cx->f_begin = sha512_256_begin;
|
||||
cx->f_hash = sha512_256_hash;
|
||||
cx->f_end = sha512_256_end;
|
||||
cx->input_len = SHA512_256_BLOCK_SIZE;
|
||||
cx->output_len = SHA512_256_DIGEST_SIZE;
|
||||
break;
|
||||
case HMAC_SHA512_224:
|
||||
cx->f_begin = sha512_224_begin;
|
||||
cx->f_hash = sha512_224_hash;
|
||||
cx->f_end = sha512_224_end;
|
||||
cx->input_len = SHA512_224_BLOCK_SIZE;
|
||||
cx->output_len = SHA512_224_DIGEST_SIZE;
|
||||
break;
|
||||
case HMAC_SHA512_192:
|
||||
cx->f_begin = sha512_192_begin;
|
||||
cx->f_hash = sha512_192_hash;
|
||||
cx->f_end = sha512_192_end;
|
||||
cx->input_len = SHA512_192_BLOCK_SIZE;
|
||||
cx->output_len = SHA512_192_DIGEST_SIZE;
|
||||
break;
|
||||
case HMAC_SHA512_128:
|
||||
cx->f_begin = sha512_128_begin;
|
||||
cx->f_hash = sha512_128_hash;
|
||||
cx->f_end = sha512_128_end;
|
||||
cx->input_len = SHA512_128_BLOCK_SIZE;
|
||||
cx->output_len = SHA512_128_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
return cx->output_len;
|
||||
}
|
||||
|
||||
/* input the HMAC key (can be called multiple times) */
|
||||
int hmac_sha_key(const unsigned char key[], unsigned long key_len, hmac_ctx cx[1])
|
||||
{
|
||||
if(cx->klen == HMAC_IN_DATA) /* error if further key input */
|
||||
return HMAC_BAD_MODE; /* is attempted in data mode */
|
||||
return EXIT_FAILURE; /* is attempted in data mode */
|
||||
|
||||
if(cx->klen + key_len > HASH_INPUT_SIZE) /* if the key has to be hashed */
|
||||
if(cx->klen + key_len > cx->input_len) /* if the key has to be hashed */
|
||||
{
|
||||
if(cx->klen <= HASH_INPUT_SIZE) /* if the hash has not yet been */
|
||||
if(cx->klen <= cx->input_len) /* if the hash has not yet been */
|
||||
{ /* started, initialise it and */
|
||||
sha_begin(cx->ctx); /* hash stored key characters */
|
||||
sha_hash(cx->key, cx->klen, cx->ctx);
|
||||
cx->f_begin(cx->sha_ctx); /* hash stored key characters */
|
||||
cx->f_hash(cx->key, cx->klen, cx->sha_ctx);
|
||||
}
|
||||
|
||||
sha_hash(key, key_len, cx->ctx); /* hash long key data into hash */
|
||||
cx->f_hash(key, key_len, cx->sha_ctx); /* hash long key data into hash */
|
||||
}
|
||||
else /* otherwise store key data */
|
||||
memcpy(cx->key + cx->klen, key, key_len);
|
||||
|
||||
cx->klen += key_len; /* update the key length count */
|
||||
return HMAC_OK;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* input the HMAC data (can be called multiple times) - */
|
||||
@@ -75,22 +140,22 @@ void hmac_sha_data(const unsigned char data[], unsigned long data_len, hmac_ctx
|
||||
|
||||
if(cx->klen != HMAC_IN_DATA) /* if not yet in data phase */
|
||||
{
|
||||
if(cx->klen > HASH_INPUT_SIZE) /* if key is being hashed */
|
||||
if(cx->klen > cx->input_len) /* if key is being hashed */
|
||||
{ /* complete the hash and */
|
||||
sha_end(cx->key, cx->ctx); /* store the result as the */
|
||||
cx->klen = HASH_OUTPUT_SIZE; /* key and set new length */
|
||||
cx->f_end(cx->key, cx->sha_ctx); /* store the result as the */
|
||||
cx->klen = cx->output_len; /* key and set new length */
|
||||
}
|
||||
|
||||
/* pad the key if necessary */
|
||||
memset(cx->key + cx->klen, 0, HASH_INPUT_SIZE - cx->klen);
|
||||
memset(cx->key + cx->klen, 0, cx->input_len - cx->klen);
|
||||
|
||||
/* xor ipad into key value */
|
||||
for(i = 0; i < (HASH_INPUT_SIZE >> 2); ++i)
|
||||
((uint_32t*)cx->key)[i] ^= 0x36363636;
|
||||
for(i = 0; i < (cx->input_len >> 2); ++i)
|
||||
((uint32_t*)cx->key)[i] ^= 0x36363636;
|
||||
|
||||
/* and start hash operation */
|
||||
sha_begin(cx->ctx);
|
||||
sha_hash(cx->key, HASH_INPUT_SIZE, cx->ctx);
|
||||
cx->f_begin(cx->sha_ctx);
|
||||
cx->f_hash(cx->key, cx->input_len, cx->sha_ctx);
|
||||
|
||||
/* mark as now in data mode */
|
||||
cx->klen = HMAC_IN_DATA;
|
||||
@@ -98,29 +163,29 @@ void hmac_sha_data(const unsigned char data[], unsigned long data_len, hmac_ctx
|
||||
|
||||
/* hash the data (if any) */
|
||||
if(data_len)
|
||||
sha_hash(data, data_len, cx->ctx);
|
||||
cx->f_hash(data, data_len, cx->sha_ctx);
|
||||
}
|
||||
|
||||
/* compute and output the MAC value */
|
||||
void hmac_sha_end(unsigned char mac[], unsigned long mac_len, hmac_ctx cx[1])
|
||||
{ unsigned char dig[HASH_OUTPUT_SIZE];
|
||||
{ unsigned char dig[HMAC_MAX_OUTPUT_SIZE];
|
||||
unsigned int i;
|
||||
|
||||
/* if no data has been entered perform a null data phase */
|
||||
if(cx->klen != HMAC_IN_DATA)
|
||||
hmac_sha_data((const unsigned char*)0, 0, cx);
|
||||
|
||||
sha_end(dig, cx->ctx); /* complete the inner hash */
|
||||
cx->f_end(dig, cx->sha_ctx); /* complete the inner hash */
|
||||
|
||||
/* set outer key value using opad and removing ipad */
|
||||
for(i = 0; i < (HASH_INPUT_SIZE >> 2); ++i)
|
||||
((uint_32t*)cx->key)[i] ^= 0x36363636 ^ 0x5c5c5c5c;
|
||||
for(i = 0; i < (cx->input_len >> 2); ++i)
|
||||
((uint32_t*)cx->key)[i] ^= 0x36363636 ^ 0x5c5c5c5c;
|
||||
|
||||
/* perform the outer hash operation */
|
||||
sha_begin(cx->ctx);
|
||||
sha_hash(cx->key, HASH_INPUT_SIZE, cx->ctx);
|
||||
sha_hash(dig, HASH_OUTPUT_SIZE, cx->ctx);
|
||||
sha_end(dig, cx->ctx);
|
||||
cx->f_begin(cx->sha_ctx);
|
||||
cx->f_hash(cx->key, cx->input_len, cx->sha_ctx);
|
||||
cx->f_hash(dig, cx->output_len, cx->sha_ctx);
|
||||
cx->f_end(dig, cx->sha_ctx);
|
||||
|
||||
/* output the hash value */
|
||||
for(i = 0; i < mac_len; ++i)
|
||||
@@ -128,12 +193,12 @@ void hmac_sha_end(unsigned char mac[], unsigned long mac_len, hmac_ctx cx[1])
|
||||
}
|
||||
|
||||
/* 'do it all in one go' subroutine */
|
||||
void hmac_sha(const unsigned char key[], unsigned long key_len,
|
||||
void hmac_sha(enum hmac_hash hash, const unsigned char key[], unsigned long key_len,
|
||||
const unsigned char data[], unsigned long data_len,
|
||||
unsigned char mac[], unsigned long mac_len)
|
||||
{ hmac_ctx cx[1];
|
||||
|
||||
hmac_sha_begin(cx);
|
||||
hmac_sha_begin(hash, cx);
|
||||
hmac_sha_key(key, key_len, cx);
|
||||
hmac_sha_data(data, data_len, cx);
|
||||
hmac_sha_end(mac, mac_len, cx);
|
||||
|
||||
@@ -1,40 +1,29 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The free distribution and use of this software in both source and binary
|
||||
form is allowed (with or without changes) provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. distributions of this source code include the above copyright
|
||||
notice, this list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
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;
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
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 Date: 26/08/2003
|
||||
|
||||
This is an implementation of HMAC, the FIPS standard keyed hash function
|
||||
This is an implementation of HMAC, the FIPS standard keyed hash function
|
||||
*/
|
||||
|
||||
#ifndef _HMAC_H
|
||||
#define _HMAC_H
|
||||
#ifndef _HMAC2_H
|
||||
#define _HMAC2_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
@@ -42,47 +31,86 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if !defined(USE_SHA1) && !defined(USE_SHA256)
|
||||
#error define USE_SHA1 or USE_SHA256 to set the HMAC hash algorithm
|
||||
#if !defined(_SHA1_H)
|
||||
# include "sha1.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_SHA1
|
||||
|
||||
#include "sha1.h"
|
||||
|
||||
#define HASH_INPUT_SIZE SHA1_BLOCK_SIZE
|
||||
#define HASH_OUTPUT_SIZE SHA1_DIGEST_SIZE
|
||||
#define sha_ctx sha1_ctx
|
||||
#define sha_begin sha1_begin
|
||||
#define sha_hash sha1_hash
|
||||
#define sha_end sha1_end
|
||||
|
||||
#if !defined(_SHA2_H)
|
||||
# include "sha2.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_SHA256
|
||||
|
||||
#include "sha2.h"
|
||||
|
||||
#define HASH_INPUT_SIZE SHA256_BLOCK_SIZE
|
||||
#define HASH_OUTPUT_SIZE SHA256_DIGEST_SIZE
|
||||
#define sha_ctx sha256_ctx
|
||||
#define sha_begin sha256_begin
|
||||
#define sha_hash sha256_hash
|
||||
#define sha_end sha256_end
|
||||
|
||||
#if !defined(_SHA2_H)
|
||||
#define HMAC_BLOCK_SIZE SHA1_BLOCK_SIZE
|
||||
#define HMAC_MAX_OUTPUT_SIZE SHA1_DIGEST_SIZE
|
||||
#else
|
||||
#define HMAC_BLOCK_SIZE SHA2_MAX_BLOCK_SIZE
|
||||
#define HMAC_MAX_OUTPUT_SIZE SHA2_MAX_DIGEST_SIZE
|
||||
#endif
|
||||
|
||||
#define HMAC_OK 0
|
||||
#define HMAC_BAD_MODE -1
|
||||
#define HMAC_IN_DATA 0xffffffff
|
||||
|
||||
enum hmac_hash
|
||||
{
|
||||
#ifdef _SHA1_H
|
||||
HMAC_SHA1,
|
||||
#endif
|
||||
#ifdef _SHA2_H
|
||||
# ifdef SHA_224
|
||||
HMAC_SHA224,
|
||||
# endif
|
||||
# ifdef SHA_256
|
||||
HMAC_SHA256,
|
||||
# endif
|
||||
# ifdef SHA_384
|
||||
HMAC_SHA384,
|
||||
# endif
|
||||
# ifdef SHA_512
|
||||
HMAC_SHA512,
|
||||
HMAC_SHA512_256,
|
||||
HMAC_SHA512_224,
|
||||
HMAC_SHA512_192,
|
||||
HMAC_SHA512_128
|
||||
# endif
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef VOID_RETURN hf_begin(void*);
|
||||
typedef VOID_RETURN hf_hash(const void*, unsigned long len, void*);
|
||||
typedef VOID_RETURN hf_end(void*, void*);
|
||||
|
||||
typedef struct
|
||||
{ unsigned char key[HASH_INPUT_SIZE];
|
||||
sha_ctx ctx[1];
|
||||
{ hf_begin *f_begin;
|
||||
hf_hash *f_hash;
|
||||
hf_end *f_end;
|
||||
unsigned char key[HMAC_BLOCK_SIZE];
|
||||
union
|
||||
{
|
||||
#ifdef _SHA1_H
|
||||
sha1_ctx u_sha1;
|
||||
#endif
|
||||
#ifdef _SHA2_H
|
||||
# ifdef SHA_224
|
||||
sha224_ctx u_sha224;
|
||||
# endif
|
||||
# ifdef SHA_256
|
||||
sha256_ctx u_sha256;
|
||||
# endif
|
||||
# ifdef SHA_384
|
||||
sha384_ctx u_sha384;
|
||||
# endif
|
||||
# ifdef SHA_512
|
||||
sha512_ctx u_sha512;
|
||||
# endif
|
||||
#endif
|
||||
} sha_ctx[1];
|
||||
unsigned long input_len;
|
||||
unsigned long output_len;
|
||||
unsigned long klen;
|
||||
} hmac_ctx;
|
||||
|
||||
void hmac_sha_begin(hmac_ctx cx[1]);
|
||||
/* returns the length of hash digest for the hash used */
|
||||
/* mac_len must not be greater than this */
|
||||
int hmac_sha_begin(enum hmac_hash hash, hmac_ctx cx[1]);
|
||||
|
||||
int hmac_sha_key(const unsigned char key[], unsigned long key_len, hmac_ctx cx[1]);
|
||||
|
||||
@@ -90,7 +118,7 @@ void hmac_sha_data(const unsigned char data[], unsigned long data_len, hmac_ctx
|
||||
|
||||
void hmac_sha_end(unsigned char mac[], unsigned long mac_len, hmac_ctx cx[1]);
|
||||
|
||||
void hmac_sha(const unsigned char key[], unsigned long key_len,
|
||||
void hmac_sha(enum hmac_hash hash, const unsigned char key[], unsigned long key_len,
|
||||
const unsigned char data[], unsigned long data_len,
|
||||
unsigned char mac[], unsigned long mac_len);
|
||||
|
||||
|
||||
@@ -1,36 +1,24 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The free distribution and use of this software in both source and binary
|
||||
form is allowed (with or without changes) provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. distributions of this source code include the above copyright
|
||||
notice, this list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
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;
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
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 Date: 26/08/2003
|
||||
|
||||
This is an implementation of RFC2898, which specifies key derivation from
|
||||
a password and a salt value.
|
||||
This is an implementation of RFC2898, which specifies key derivation from
|
||||
a password and a salt value.
|
||||
*/
|
||||
|
||||
#include <memory.h>
|
||||
@@ -49,12 +37,12 @@ void derive_key(const unsigned char pwd[], /* the PASSWORD */
|
||||
unsigned char key[], /* space for the output key */
|
||||
unsigned int key_len)/* and its required length */
|
||||
{
|
||||
unsigned int i, j, k, n_blk;
|
||||
unsigned char uu[HASH_OUTPUT_SIZE], ux[HASH_OUTPUT_SIZE];
|
||||
unsigned int i, j, k, n_blk, h_size;
|
||||
unsigned char uu[HMAC_MAX_OUTPUT_SIZE], ux[HMAC_MAX_OUTPUT_SIZE];
|
||||
hmac_ctx c1[1], c2[1], c3[1];
|
||||
|
||||
/* set HMAC context (c1) for password */
|
||||
hmac_sha_begin(c1);
|
||||
h_size = hmac_sha_begin(HMAC_SHA1, c1);
|
||||
hmac_sha_key(pwd, pwd_len, c1);
|
||||
|
||||
/* set HMAC context (c2) for password and salt */
|
||||
@@ -62,12 +50,12 @@ void derive_key(const unsigned char pwd[], /* the PASSWORD */
|
||||
hmac_sha_data(salt, salt_len, c2);
|
||||
|
||||
/* find the number of SHA blocks in the key */
|
||||
n_blk = 1 + (key_len - 1) / HASH_OUTPUT_SIZE;
|
||||
n_blk = 1 + (key_len - 1) / h_size;
|
||||
|
||||
for(i = 0; i < n_blk; ++i) /* for each block in key */
|
||||
{
|
||||
/* ux[] holds the running xor value */
|
||||
memset(ux, 0, HASH_OUTPUT_SIZE);
|
||||
memset(ux, 0, h_size);
|
||||
|
||||
/* set HMAC context (c3) for password and salt */
|
||||
memcpy(c3, c2, sizeof(hmac_ctx));
|
||||
@@ -85,10 +73,10 @@ void derive_key(const unsigned char pwd[], /* the PASSWORD */
|
||||
hmac_sha_data(uu, k, c3);
|
||||
|
||||
/* obtain HMAC for uu[] */
|
||||
hmac_sha_end(uu, HASH_OUTPUT_SIZE, c3);
|
||||
hmac_sha_end(uu, h_size, c3);
|
||||
|
||||
/* xor into the running xor block */
|
||||
for(k = 0; k < HASH_OUTPUT_SIZE; ++k)
|
||||
for(k = 0; k < h_size; ++k)
|
||||
ux[k] ^= uu[k];
|
||||
|
||||
/* set HMAC context (c3) for password */
|
||||
@@ -96,8 +84,8 @@ void derive_key(const unsigned char pwd[], /* the PASSWORD */
|
||||
}
|
||||
|
||||
/* compile key blocks into the key output */
|
||||
j = 0; k = i * HASH_OUTPUT_SIZE;
|
||||
while(j < HASH_OUTPUT_SIZE && k < key_len)
|
||||
j = 0; k = i * h_size;
|
||||
while(j < h_size && k < key_len)
|
||||
key[k++] = ux[j++];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +1,24 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The free distribution and use of this software in both source and binary
|
||||
form is allowed (with or without changes) provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. distributions of this source code include the above copyright
|
||||
notice, this list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
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;
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
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 Date: 26/08/2003
|
||||
|
||||
This is an implementation of RFC2898, which specifies key derivation from
|
||||
a password and a salt value.
|
||||
This is an implementation of RFC2898, which specifies key derivation from
|
||||
a password and a salt value.
|
||||
*/
|
||||
|
||||
#ifndef PWD2KEY_H
|
||||
|
||||
@@ -1,36 +1,21 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The free distribution and use of this software in both source and binary
|
||||
form is allowed (with or without changes) provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. distributions of this source code include the above copyright
|
||||
notice, this list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
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 Date: 01/08/2005
|
||||
|
||||
This is a byte oriented version of SHA1 that operates on arrays of bytes
|
||||
stored in memory.
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#include <string.h> /* for memcpy() etc. */
|
||||
@@ -45,6 +30,7 @@ extern "C"
|
||||
|
||||
#if defined( _MSC_VER ) && ( _MSC_VER > 800 )
|
||||
#pragma intrinsic(memcpy)
|
||||
#pragma intrinsic(memset)
|
||||
#endif
|
||||
|
||||
#if 0 && defined(_MSC_VER)
|
||||
@@ -67,7 +53,7 @@ extern "C"
|
||||
|
||||
#if defined(SWAP_BYTES)
|
||||
#define bsw_32(p,n) \
|
||||
{ int _i = (n); while(_i--) ((uint_32t*)p)[_i] = bswap_32(((uint_32t*)p)[_i]); }
|
||||
{ int _i = (n); while(_i--) ((uint32_t*)p)[_i] = bswap_32(((uint32_t*)p)[_i]); }
|
||||
#else
|
||||
#define bsw_32(p,n)
|
||||
#endif
|
||||
@@ -114,13 +100,13 @@ extern "C"
|
||||
one_cycle(v, 1,2,3,4,0, f,k,hf(i+4))
|
||||
|
||||
VOID_RETURN sha1_compile(sha1_ctx ctx[1])
|
||||
{ uint_32t *w = ctx->wbuf;
|
||||
{ uint32_t *w = ctx->wbuf;
|
||||
|
||||
#ifdef ARRAY
|
||||
uint_32t v[5];
|
||||
memcpy(v, ctx->hash, 5 * sizeof(uint_32t));
|
||||
uint32_t v[5];
|
||||
memcpy(v, ctx->hash, sizeof(ctx->hash));
|
||||
#else
|
||||
uint_32t v0, v1, v2, v3, v4;
|
||||
uint32_t v0, v1, v2, v3, v4;
|
||||
v0 = ctx->hash[0]; v1 = ctx->hash[1];
|
||||
v2 = ctx->hash[2]; v3 = ctx->hash[3];
|
||||
v4 = ctx->hash[4];
|
||||
@@ -171,7 +157,7 @@ VOID_RETURN sha1_compile(sha1_ctx ctx[1])
|
||||
|
||||
VOID_RETURN sha1_begin(sha1_ctx ctx[1])
|
||||
{
|
||||
ctx->count[0] = ctx->count[1] = 0;
|
||||
memset(ctx, 0, sizeof(sha1_ctx));
|
||||
ctx->hash[0] = 0x67452301;
|
||||
ctx->hash[1] = 0xefcdab89;
|
||||
ctx->hash[2] = 0x98badcfe;
|
||||
@@ -180,43 +166,78 @@ VOID_RETURN sha1_begin(sha1_ctx ctx[1])
|
||||
}
|
||||
|
||||
/* SHA1 hash data in an array of bytes into hash buffer and */
|
||||
/* call the hash_compile function as required. */
|
||||
/* call the hash_compile function as required. For both the */
|
||||
/* bit and byte orientated versions, the block length 'len' */
|
||||
/* must not be greater than 2^32 - 1 bits (2^29 - 1 bytes) */
|
||||
|
||||
VOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1])
|
||||
{ uint_32t pos = (uint_32t)(ctx->count[0] & SHA1_MASK),
|
||||
space = SHA1_BLOCK_SIZE - pos;
|
||||
{ uint32_t pos = (uint32_t)((ctx->count[0] >> 3) & SHA1_MASK);
|
||||
const unsigned char *sp = data;
|
||||
|
||||
unsigned char *w = (unsigned char*)ctx->wbuf;
|
||||
#if SHA1_BITS == 1
|
||||
uint32_t ofs = (ctx->count[0] & 7);
|
||||
#else
|
||||
len <<= 3;
|
||||
#endif
|
||||
if((ctx->count[0] += len) < len)
|
||||
++(ctx->count[1]);
|
||||
|
||||
while(len >= space) /* tranfer whole blocks if possible */
|
||||
#if SHA1_BITS == 1
|
||||
if(ofs) /* if not on a byte boundary */
|
||||
{
|
||||
memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
|
||||
sp += space; len -= space; space = SHA1_BLOCK_SIZE; pos = 0;
|
||||
bsw_32(ctx->wbuf, SHA1_BLOCK_SIZE >> 2);
|
||||
sha1_compile(ctx);
|
||||
}
|
||||
if(ofs + len < 8) /* if no added bytes are needed */
|
||||
{
|
||||
w[pos] |= (*sp >> ofs);
|
||||
}
|
||||
else /* otherwise and add bytes */
|
||||
{ unsigned char part = w[pos];
|
||||
|
||||
memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);
|
||||
while((int)(ofs + (len -= 8)) >= 0)
|
||||
{
|
||||
w[pos++] = part | (*sp >> ofs);
|
||||
part = *sp++ << (8 - ofs);
|
||||
if(pos == SHA1_BLOCK_SIZE)
|
||||
{
|
||||
bsw_32(w, SHA1_BLOCK_SIZE >> 2);
|
||||
sha1_compile(ctx); pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
w[pos] = part;
|
||||
}
|
||||
}
|
||||
else /* data is byte aligned */
|
||||
#endif
|
||||
{ uint32_t space = SHA1_BLOCK_SIZE - pos;
|
||||
|
||||
while(len >= (space << 3))
|
||||
{
|
||||
memcpy(w + pos, sp, space);
|
||||
bsw_32(w, SHA1_BLOCK_SIZE >> 2);
|
||||
sha1_compile(ctx);
|
||||
sp += space; len -= (space << 3);
|
||||
space = SHA1_BLOCK_SIZE; pos = 0;
|
||||
}
|
||||
memcpy(w + pos, sp, (len + 7 * SHA1_BITS) >> 3);
|
||||
}
|
||||
}
|
||||
|
||||
/* SHA1 final padding and digest calculation */
|
||||
|
||||
VOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1])
|
||||
{ uint_32t i = (uint_32t)(ctx->count[0] & SHA1_MASK);
|
||||
{ uint32_t i = (uint32_t)((ctx->count[0] >> 3) & SHA1_MASK), m1;
|
||||
|
||||
/* put bytes in the buffer in an order in which references to */
|
||||
/* 32-bit words will put bytes with lower addresses into the */
|
||||
/* top of 32 bit words on BOTH big and little endian machines */
|
||||
bsw_32(ctx->wbuf, (i + 3) >> 2);
|
||||
bsw_32(ctx->wbuf, (i + 3 + SHA1_BITS) >> 2);
|
||||
|
||||
/* we now need to mask valid bytes and add the padding which is */
|
||||
/* a single 1 bit and as many zero bits as necessary. Note that */
|
||||
/* we can always add the first padding byte here because the */
|
||||
/* buffer always has at least one empty slot */
|
||||
ctx->wbuf[i >> 2] &= 0xffffff80 << 8 * (~i & 3);
|
||||
ctx->wbuf[i >> 2] |= 0x00000080 << 8 * (~i & 3);
|
||||
m1 = (unsigned char)0x80 >> (ctx->count[0] & 7);
|
||||
ctx->wbuf[i >> 2] &= ((0xffffff00 | (~m1 + 1)) << 8 * (~i & 3));
|
||||
ctx->wbuf[i >> 2] |= (m1 << 8 * (~i & 3));
|
||||
|
||||
/* we need 9 or more empty positions, one for the padding byte */
|
||||
/* (above) and eight for the length count. If there is not */
|
||||
@@ -237,14 +258,14 @@ VOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1])
|
||||
/* wrong byte order on little endian machines but this is */
|
||||
/* corrected later since they are only ever used as 32-bit */
|
||||
/* word values. */
|
||||
ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29);
|
||||
ctx->wbuf[15] = ctx->count[0] << 3;
|
||||
ctx->wbuf[14] = ctx->count[1];
|
||||
ctx->wbuf[15] = ctx->count[0];
|
||||
sha1_compile(ctx);
|
||||
|
||||
/* extract the hash value as bytes in case the hash buffer is */
|
||||
/* misaligned for 32-bit words */
|
||||
for(i = 0; i < SHA1_DIGEST_SIZE; ++i)
|
||||
hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3)));
|
||||
hval[i] = ((ctx->hash[i >> 2] >> (8 * (~i & 3))) & 0xff);
|
||||
}
|
||||
|
||||
VOID_RETURN sha1(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||
|
||||
@@ -1,38 +1,35 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The free distribution and use of this software in both source and binary
|
||||
form is allowed (with or without changes) provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. distributions of this source code include the above copyright
|
||||
notice, this list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
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 Date: 01/08/2005
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#ifndef _SHA1_H
|
||||
#define _SHA1_H
|
||||
|
||||
/* define for bit or byte oriented SHA */
|
||||
#if 1
|
||||
# define SHA1_BITS 0 /* byte oriented */
|
||||
#else
|
||||
# define SHA1_BITS 1 /* bit oriented */
|
||||
#endif
|
||||
|
||||
#define SHA_1
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "brg_types.h"
|
||||
|
||||
@@ -47,9 +44,9 @@ extern "C"
|
||||
/* type to hold the SHA256 context */
|
||||
|
||||
typedef struct
|
||||
{ uint_32t count[2];
|
||||
uint_32t hash[5];
|
||||
uint_32t wbuf[16];
|
||||
{ uint32_t count[2];
|
||||
uint32_t hash[SHA1_DIGEST_SIZE >> 2];
|
||||
uint32_t wbuf[SHA1_BLOCK_SIZE >> 2];
|
||||
} sha1_ctx;
|
||||
|
||||
/* Note that these prototypes are the same for both bit and */
|
||||
@@ -57,7 +54,9 @@ typedef struct
|
||||
/* are in bytes or bits as appropriate for the version used */
|
||||
/* and bit sequences are input as arrays of bytes in which */
|
||||
/* bit sequences run from the most to the least significant */
|
||||
/* end of each byte */
|
||||
/* end of each byte. The value 'len' in sha1_hash for the */
|
||||
/* byte oriented version of SHA1 is limited to 2^29 bytes, */
|
||||
/* but multiple calls will handle longer data blocks. */
|
||||
|
||||
VOID_RETURN sha1_compile(sha1_ctx ctx[1]);
|
||||
|
||||
|
||||
@@ -1,287 +0,0 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2002, 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 Date: 01/08/2005
|
||||
|
||||
This is a bit oriented version of SHA1 that operates on arrays of bytes
|
||||
stored in memory.
|
||||
*/
|
||||
|
||||
#include <string.h> /* for memcpy() etc. */
|
||||
|
||||
#include "sha1.h"
|
||||
#include "brg_endian.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if defined( _MSC_VER ) && ( _MSC_VER > 800 )
|
||||
#pragma intrinsic(memcpy)
|
||||
#endif
|
||||
|
||||
#if 0 && defined(_MSC_VER)
|
||||
#define rotl32 _lrotl
|
||||
#define rotr32 _lrotr
|
||||
#else
|
||||
#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
|
||||
#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n)))
|
||||
#endif
|
||||
|
||||
#if !defined(bswap_32)
|
||||
#define bswap_32(x) (rotr32((x), 24) & 0x00ff00ff | rotr32((x), 8) & 0xff00ff00)
|
||||
#endif
|
||||
|
||||
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
|
||||
#define SWAP_BYTES
|
||||
#else
|
||||
#undef SWAP_BYTES
|
||||
#endif
|
||||
|
||||
#if defined(SWAP_BYTES)
|
||||
#define bsw_32(p,n) \
|
||||
{ int _i = (n); while(_i--) ((uint_32t*)p)[_i] = bswap_32(((uint_32t*)p)[_i]); }
|
||||
#else
|
||||
#define bsw_32(p,n)
|
||||
#endif
|
||||
|
||||
#define SHA1_MASK (SHA1_BLOCK_SIZE - 1)
|
||||
|
||||
#if 0
|
||||
|
||||
#define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
|
||||
#define parity(x,y,z) ((x) ^ (y) ^ (z))
|
||||
#define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||
|
||||
#else /* Discovered by Rich Schroeppel and Colin Plumb */
|
||||
|
||||
#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
|
||||
#define parity(x,y,z) ((x) ^ (y) ^ (z))
|
||||
#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y))))
|
||||
|
||||
#endif
|
||||
|
||||
/* Compile 64 bytes of hash data into SHA1 context. Note */
|
||||
/* that this routine assumes that the byte order in the */
|
||||
/* ctx->wbuf[] at this point is in such an order that low */
|
||||
/* address bytes in the ORIGINAL byte stream in this buffer */
|
||||
/* will go to the high end of 32-bit words on BOTH big and */
|
||||
/* little endian systems */
|
||||
|
||||
#ifdef ARRAY
|
||||
#define q(n) v[n]
|
||||
#else
|
||||
#define q(n) v##n
|
||||
#endif
|
||||
|
||||
#define one_cycle(a,b,c,d,e,f,k,h) \
|
||||
q(e) += rotr32(q(a),27) + f(q(b),q(c),q(d)) + k + h;\
|
||||
q(b) = rotr32(q(b), 2)
|
||||
|
||||
#define five_cycle(f,k,i) \
|
||||
one_cycle(0,1,2,3,4, f,k,hf(i )); \
|
||||
one_cycle(4,0,1,2,3, f,k,hf(i+1)); \
|
||||
one_cycle(3,4,0,1,2, f,k,hf(i+2)); \
|
||||
one_cycle(2,3,4,0,1, f,k,hf(i+3)); \
|
||||
one_cycle(1,2,3,4,0, f,k,hf(i+4))
|
||||
|
||||
VOID_RETURN sha1_compile(sha1_ctx ctx[1])
|
||||
{ uint_32t *w = ctx->wbuf;
|
||||
|
||||
#ifdef ARRAY
|
||||
uint_32t v[5];
|
||||
memcpy(v, ctx->hash, 5 * sizeof(uint_32t));
|
||||
#else
|
||||
uint_32t v0, v1, v2, v3, v4;
|
||||
v0 = ctx->hash[0]; v1 = ctx->hash[1];
|
||||
v2 = ctx->hash[2]; v3 = ctx->hash[3];
|
||||
v4 = ctx->hash[4];
|
||||
#endif
|
||||
|
||||
#define hf(i) w[i]
|
||||
|
||||
five_cycle(ch, 0x5a827999, 0);
|
||||
five_cycle(ch, 0x5a827999, 5);
|
||||
five_cycle(ch, 0x5a827999, 10);
|
||||
one_cycle(0,1,2,3,4, ch, 0x5a827999, hf(15)); \
|
||||
|
||||
#undef hf
|
||||
#define hf(i) \
|
||||
(w[(i) & 15] = rotl32(w[((i) + 13) & 15] ^ w[((i) + 8) & 15] \
|
||||
^ w[((i) + 2) & 15] ^ w[(i) & 15], 1))
|
||||
|
||||
one_cycle(4,0,1,2,3, ch, 0x5a827999, hf(16));
|
||||
one_cycle(3,4,0,1,2, ch, 0x5a827999, hf(17));
|
||||
one_cycle(2,3,4,0,1, ch, 0x5a827999, hf(18));
|
||||
one_cycle(1,2,3,4,0, ch, 0x5a827999, hf(19));
|
||||
|
||||
five_cycle(parity, 0x6ed9eba1, 20);
|
||||
five_cycle(parity, 0x6ed9eba1, 25);
|
||||
five_cycle(parity, 0x6ed9eba1, 30);
|
||||
five_cycle(parity, 0x6ed9eba1, 35);
|
||||
|
||||
five_cycle(maj, 0x8f1bbcdc, 40);
|
||||
five_cycle(maj, 0x8f1bbcdc, 45);
|
||||
five_cycle(maj, 0x8f1bbcdc, 50);
|
||||
five_cycle(maj, 0x8f1bbcdc, 55);
|
||||
|
||||
five_cycle(parity, 0xca62c1d6, 60);
|
||||
five_cycle(parity, 0xca62c1d6, 65);
|
||||
five_cycle(parity, 0xca62c1d6, 70);
|
||||
five_cycle(parity, 0xca62c1d6, 75);
|
||||
|
||||
#ifdef ARRAY
|
||||
ctx->hash[0] += v[0]; ctx->hash[1] += v[1];
|
||||
ctx->hash[2] += v[2]; ctx->hash[3] += v[3];
|
||||
ctx->hash[4] += v[4];
|
||||
#else
|
||||
ctx->hash[0] += v0; ctx->hash[1] += v1;
|
||||
ctx->hash[2] += v2; ctx->hash[3] += v3;
|
||||
ctx->hash[4] += v4;
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID_RETURN sha1_begin(sha1_ctx ctx[1])
|
||||
{
|
||||
ctx->count[0] = ctx->count[1] = 0;
|
||||
ctx->hash[0] = 0x67452301;
|
||||
ctx->hash[1] = 0xefcdab89;
|
||||
ctx->hash[2] = 0x98badcfe;
|
||||
ctx->hash[3] = 0x10325476;
|
||||
ctx->hash[4] = 0xc3d2e1f0;
|
||||
}
|
||||
|
||||
/* SHA1 hash data in an array of bytes into hash buffer and */
|
||||
/* call the hash_compile function as required. */
|
||||
|
||||
VOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1])
|
||||
{ uint_32t pos = (uint_32t)((ctx->count[0] >> 3) & SHA1_MASK),
|
||||
ofs = (ctx->count[0] & 7);
|
||||
const unsigned char *sp = data;
|
||||
unsigned char *w = (unsigned char*)ctx->wbuf;
|
||||
|
||||
if((ctx->count[0] += len) < len)
|
||||
++(ctx->count[1]);
|
||||
|
||||
if(ofs) /* if not on a byte boundary */
|
||||
{
|
||||
if(ofs + len < 8) /* if no added bytes are needed */
|
||||
{
|
||||
w[pos] |= (*sp >> ofs);
|
||||
}
|
||||
else /* otherwise and add bytes */
|
||||
{ unsigned char part = w[pos];
|
||||
|
||||
while((int)(ofs + (len -= 8)) >= 0)
|
||||
{
|
||||
w[pos++] = part | (*sp >> ofs);
|
||||
part = *sp++ << (8 - ofs);
|
||||
if(pos == SHA1_BLOCK_SIZE)
|
||||
{
|
||||
bsw_32(w, SHA1_BLOCK_SIZE >> 2);
|
||||
sha1_compile(ctx); pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
w[pos] = part;
|
||||
}
|
||||
}
|
||||
else /* data is byte aligned */
|
||||
{ uint_32t space = SHA1_BLOCK_SIZE - pos;
|
||||
|
||||
while((int)(len - 8 * space) >= 0)
|
||||
{
|
||||
len -= 8 * space;
|
||||
memcpy(w + pos, sp, space);
|
||||
sp += space;
|
||||
space = SHA1_BLOCK_SIZE;
|
||||
bsw_32(w, SHA1_BLOCK_SIZE >> 2);
|
||||
sha1_compile(ctx); pos = 0;
|
||||
}
|
||||
memcpy(w + pos, sp, (len + 7) >> 3);
|
||||
}
|
||||
}
|
||||
|
||||
/* SHA1 final padding and digest calculation */
|
||||
|
||||
VOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1])
|
||||
{ uint_32t i = (uint_32t)((ctx->count[0] >> 3) & SHA1_MASK), m1;
|
||||
|
||||
/* put bytes in the buffer in an order in which references to */
|
||||
/* 32-bit words will put bytes with lower addresses into the */
|
||||
/* top of 32 bit words on BOTH big and little endian machines */
|
||||
bsw_32(ctx->wbuf, (i + 4) >> 2);
|
||||
|
||||
/* we now need to mask valid bytes and add the padding which is */
|
||||
/* a single 1 bit and as many zero bits as necessary. Note that */
|
||||
/* we can always add the first padding byte here because the */
|
||||
/* buffer always has at least one empty slot */
|
||||
m1 = (unsigned char)0x80 >> (ctx->count[0] & 7);
|
||||
ctx->wbuf[i >> 2] &= ((0xffffff00 | (~m1 + 1)) << 8 * (~i & 3));
|
||||
ctx->wbuf[i >> 2] |= (m1 << 8 * (~i & 3));
|
||||
|
||||
/* we need 9 or more empty positions, one for the padding byte */
|
||||
/* (above) and eight for the length count. If there is not */
|
||||
/* enough space, pad and empty the buffer */
|
||||
if(i > SHA1_BLOCK_SIZE - 9)
|
||||
{
|
||||
if(i < 60) ctx->wbuf[15] = 0;
|
||||
sha1_compile(ctx);
|
||||
i = 0;
|
||||
}
|
||||
else /* compute a word index for the empty buffer positions */
|
||||
i = (i >> 2) + 1;
|
||||
|
||||
while(i < 14) /* and zero pad all but last two positions */
|
||||
ctx->wbuf[i++] = 0;
|
||||
|
||||
/* the following 32-bit length fields are assembled in the */
|
||||
/* wrong byte order on little endian machines but this is */
|
||||
/* corrected later since they are only ever used as 32-bit */
|
||||
/* word values. */
|
||||
ctx->wbuf[14] = ctx->count[1];
|
||||
ctx->wbuf[15] = ctx->count[0];
|
||||
sha1_compile(ctx);
|
||||
|
||||
/* extract the hash value as bytes in case the hash buffer is */
|
||||
/* misaligned for 32-bit words */
|
||||
for(i = 0; i < SHA1_DIGEST_SIZE; ++i)
|
||||
hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3)));
|
||||
}
|
||||
|
||||
VOID_RETURN sha1(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||
{ sha1_ctx cx[1];
|
||||
|
||||
sha1_begin(cx); sha1_hash(data, len, cx); sha1_end(hval, cx);
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
@@ -1,83 +1,73 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The free distribution and use of this software in both source and binary
|
||||
form is allowed (with or without changes) provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. distributions of this source code include the above copyright
|
||||
notice, this list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
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;
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
3. the copyright holder's name is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
This code implements sha256, sha384 and sha512 but the latter two
|
||||
functions rely on efficient 64-bit integer operations that may not be
|
||||
very efficient on 32-bit machines
|
||||
|
||||
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.
|
||||
The sha256 functions use a type 'sha256_ctx' to hold details of the
|
||||
current hash state and uses the following three calls:
|
||||
|
||||
DISCLAIMER
|
||||
void sha256_begin( sha256_ctx ctx[1] )
|
||||
void sha256_hash( const unsigned char data[],
|
||||
unsigned long len, sha256_ctx ctx[1] )
|
||||
void sha_end1( unsigned char hval[], sha256_ctx ctx[1] )
|
||||
|
||||
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 Date: 01/08/2005
|
||||
The first subroutine initialises a hash computation by setting up the
|
||||
context in the sha256_ctx context. The second subroutine hashes 8-bit
|
||||
bytes from array data[] into the hash state withinh sha256_ctx context,
|
||||
the number of bytes to be hashed being given by the the unsigned long
|
||||
integer len. The third subroutine completes the hash calculation and
|
||||
places the resulting digest value in the array of 8-bit bytes hval[].
|
||||
|
||||
This is a byte oriented version of SHA2 that operates on arrays of bytes
|
||||
stored in memory. This code implements sha256, sha384 and sha512 but the
|
||||
latter two functions rely on efficient 64-bit integer operations that
|
||||
may not be very efficient on 32-bit machines
|
||||
The sha384 and sha512 functions are similar and use the interfaces:
|
||||
|
||||
The sha256 functions use a type 'sha256_ctx' to hold details of the
|
||||
current hash state and uses the following three calls:
|
||||
void sha384_begin( sha384_ctx ctx[1] );
|
||||
void sha384_hash( const unsigned char data[],
|
||||
unsigned long len, sha384_ctx ctx[1] );
|
||||
void sha384_end( unsigned char hval[], sha384_ctx ctx[1] );
|
||||
|
||||
void sha256_begin(sha256_ctx ctx[1])
|
||||
void sha256_hash(const unsigned char data[],
|
||||
unsigned long len, sha256_ctx ctx[1])
|
||||
void sha_end1(unsigned char hval[], sha256_ctx ctx[1])
|
||||
void sha512_begin( sha512_ctx ctx[1] );
|
||||
void sha512_hash( const unsigned char data[],
|
||||
unsigned long len, sha512_ctx ctx[1] );
|
||||
void sha512_end( unsigned char hval[], sha512_ctx ctx[1] );
|
||||
|
||||
The first subroutine initialises a hash computation by setting up the
|
||||
context in the sha256_ctx context. The second subroutine hashes 8-bit
|
||||
bytes from array data[] into the hash state withinh sha256_ctx context,
|
||||
the number of bytes to be hashed being given by the the unsigned long
|
||||
integer len. The third subroutine completes the hash calculation and
|
||||
places the resulting digest value in the array of 8-bit bytes hval[].
|
||||
In addition there is a function sha2 that can be used to call all these
|
||||
functions using a call with a hash length parameter as follows:
|
||||
|
||||
The sha384 and sha512 functions are similar and use the interfaces:
|
||||
int sha2_begin( unsigned long len, sha2_ctx ctx[1] );
|
||||
void sha2_hash( const unsigned char data[],
|
||||
unsigned long len, sha2_ctx ctx[1] );
|
||||
void sha2_end( unsigned char hval[], sha2_ctx ctx[1] );
|
||||
|
||||
void sha384_begin(sha384_ctx ctx[1]);
|
||||
void sha384_hash(const unsigned char data[],
|
||||
unsigned long len, sha384_ctx ctx[1]);
|
||||
void sha384_end(unsigned char hval[], sha384_ctx ctx[1]);
|
||||
The data block length in any one call to any of these hash functions must
|
||||
be no more than 2^32 - 1 bits or 2^29 - 1 bytes.
|
||||
|
||||
void sha512_begin(sha512_ctx ctx[1]);
|
||||
void sha512_hash(const unsigned char data[],
|
||||
unsigned long len, sha512_ctx ctx[1]);
|
||||
void sha512_end(unsigned char hval[], sha512_ctx ctx[1]);
|
||||
|
||||
In addition there is a function sha2 that can be used to call all these
|
||||
functions using a call with a hash length parameter as follows:
|
||||
|
||||
int sha2_begin(unsigned long len, sha2_ctx ctx[1]);
|
||||
void sha2_hash(const unsigned char data[],
|
||||
unsigned long len, sha2_ctx ctx[1]);
|
||||
void sha2_end(unsigned char hval[], sha2_ctx ctx[1]);
|
||||
|
||||
My thanks to Erik Andersen <andersen@codepoet.org> for testing this code
|
||||
on big-endian systems and for his assistance with corrections
|
||||
My thanks to Erik Andersen <andersen@codepoet.org> for testing this code
|
||||
on big-endian systems and for his assistance with corrections
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#define UNROLL_SHA2 /* for SHA2 loop unroll */
|
||||
#if 1
|
||||
#define UNROLL_SHA2 /* for SHA2 loop unroll */
|
||||
#endif
|
||||
|
||||
#include <string.h> /* for memcpy() etc. */
|
||||
#include <string.h> /* for memcpy() etc. */
|
||||
|
||||
#include "sha2.h"
|
||||
#include "brg_endian.h"
|
||||
@@ -89,6 +79,7 @@ extern "C"
|
||||
|
||||
#if defined( _MSC_VER ) && ( _MSC_VER > 800 )
|
||||
#pragma intrinsic(memcpy)
|
||||
#pragma intrinsic(memset)
|
||||
#endif
|
||||
|
||||
#if 0 && defined(_MSC_VER)
|
||||
@@ -140,7 +131,7 @@ extern "C"
|
||||
|
||||
#if defined(SWAP_BYTES)
|
||||
#define bsw_32(p,n) \
|
||||
{ int _i = (n); while(_i--) ((uint_32t*)p)[_i] = bswap_32(((uint_32t*)p)[_i]); }
|
||||
{ int _i = (n); while(_i--) ((uint32_t*)p)[_i] = bswap_32(((uint32_t*)p)[_i]); }
|
||||
#else
|
||||
#define bsw_32(p,n)
|
||||
#endif
|
||||
@@ -163,7 +154,7 @@ extern "C"
|
||||
|
||||
/* SHA256 mixing data */
|
||||
|
||||
const uint_32t k256[64] =
|
||||
const uint32_t k256[64] =
|
||||
{ 0x428a2f98ul, 0x71374491ul, 0xb5c0fbcful, 0xe9b5dba5ul,
|
||||
0x3956c25bul, 0x59f111f1ul, 0x923f82a4ul, 0xab1c5ed5ul,
|
||||
0xd807aa98ul, 0x12835b01ul, 0x243185beul, 0x550c7dc3ul,
|
||||
@@ -192,9 +183,9 @@ VOID_RETURN sha256_compile(sha256_ctx ctx[1])
|
||||
{
|
||||
#if !defined(UNROLL_SHA2)
|
||||
|
||||
uint_32t j, *p = ctx->wbuf, v[8];
|
||||
uint32_t j, *p = ctx->wbuf, v[8];
|
||||
|
||||
memcpy(v, ctx->hash, 8 * sizeof(uint_32t));
|
||||
memcpy(v, ctx->hash, sizeof(ctx->hash));
|
||||
|
||||
for(j = 0; j < 64; j += 16)
|
||||
{
|
||||
@@ -215,7 +206,7 @@ VOID_RETURN sha256_compile(sha256_ctx ctx[1])
|
||||
|
||||
#else
|
||||
|
||||
uint_32t *p = ctx->wbuf,v0,v1,v2,v3,v4,v5,v6,v7;
|
||||
uint32_t *p = ctx->wbuf,v0,v1,v2,v3,v4,v5,v6,v7;
|
||||
|
||||
v0 = ctx->hash[0]; v1 = ctx->hash[1];
|
||||
v2 = ctx->hash[2]; v3 = ctx->hash[3];
|
||||
@@ -301,40 +292,74 @@ VOID_RETURN sha256_compile(sha256_ctx ctx[1])
|
||||
/* and call the hash_compile function as required. */
|
||||
|
||||
VOID_RETURN sha256_hash(const unsigned char data[], unsigned long len, sha256_ctx ctx[1])
|
||||
{ uint_32t pos = (uint_32t)(ctx->count[0] & SHA256_MASK),
|
||||
space = SHA256_BLOCK_SIZE - pos;
|
||||
{ uint32_t pos = (uint32_t)((ctx->count[0] >> 3) & SHA256_MASK);
|
||||
const unsigned char *sp = data;
|
||||
|
||||
unsigned char *w = (unsigned char*)ctx->wbuf;
|
||||
#if SHA2_BITS == 1
|
||||
uint32_t ofs = (ctx->count[0] & 7);
|
||||
#else
|
||||
len <<= 3;
|
||||
#endif
|
||||
if((ctx->count[0] += len) < len)
|
||||
++(ctx->count[1]);
|
||||
|
||||
while(len >= space) /* tranfer whole blocks while possible */
|
||||
#if SHA2_BITS == 1
|
||||
if(ofs) /* if not on a byte boundary */
|
||||
{
|
||||
memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
|
||||
sp += space; len -= space; space = SHA256_BLOCK_SIZE; pos = 0;
|
||||
bsw_32(ctx->wbuf, SHA256_BLOCK_SIZE >> 2)
|
||||
sha256_compile(ctx);
|
||||
}
|
||||
if(ofs + len < 8) /* if no added bytes are needed */
|
||||
{
|
||||
w[pos] |= (*sp >> ofs);
|
||||
}
|
||||
else /* otherwise and add bytes */
|
||||
{ unsigned char part = w[pos];
|
||||
|
||||
memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);
|
||||
while((int)(ofs + (len -= 8)) >= 0)
|
||||
{
|
||||
w[pos++] = part | (*sp >> ofs);
|
||||
part = *sp++ << (8 - ofs);
|
||||
if(pos == SHA256_BLOCK_SIZE)
|
||||
{
|
||||
bsw_32(w, SHA256_BLOCK_SIZE >> 2);
|
||||
sha256_compile(ctx); pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
w[pos] = part;
|
||||
}
|
||||
}
|
||||
else /* data is byte aligned */
|
||||
#endif
|
||||
{ uint32_t space = SHA256_BLOCK_SIZE - pos;
|
||||
|
||||
while(len >= (space << 3))
|
||||
{
|
||||
memcpy(w + pos, sp, space);
|
||||
bsw_32(w, SHA256_BLOCK_SIZE >> 2);
|
||||
sha256_compile(ctx);
|
||||
sp += space; len -= (space << 3);
|
||||
space = SHA256_BLOCK_SIZE; pos = 0;
|
||||
}
|
||||
memcpy(w + pos, sp, (len + 7 * SHA2_BITS) >> 3);
|
||||
}
|
||||
}
|
||||
|
||||
/* SHA256 Final padding and digest calculation */
|
||||
|
||||
static void sha_end1(unsigned char hval[], sha256_ctx ctx[1], const unsigned int hlen)
|
||||
{ uint_32t i = (uint_32t)(ctx->count[0] & SHA256_MASK);
|
||||
{ uint32_t i = (uint32_t)((ctx->count[0] >> 3) & SHA256_MASK), m1;
|
||||
|
||||
/* put bytes in the buffer in an order in which references to */
|
||||
/* 32-bit words will put bytes with lower addresses into the */
|
||||
/* top of 32 bit words on BOTH big and little endian machines */
|
||||
bsw_32(ctx->wbuf, (i + 3) >> 2)
|
||||
bsw_32(ctx->wbuf, (i + 3 + SHA2_BITS) >> 2)
|
||||
|
||||
/* we now need to mask valid bytes and add the padding which is */
|
||||
/* a single 1 bit and as many zero bits as necessary. Note that */
|
||||
/* we can always add the first padding byte here because the */
|
||||
/* buffer always has at least one empty slot */
|
||||
ctx->wbuf[i >> 2] &= 0xffffff80 << 8 * (~i & 3);
|
||||
ctx->wbuf[i >> 2] |= 0x00000080 << 8 * (~i & 3);
|
||||
m1 = (unsigned char)0x80 >> (ctx->count[0] & 7);
|
||||
ctx->wbuf[i >> 2] &= ((0xffffff00 | (~m1 + 1)) << 8 * (~i & 3));
|
||||
ctx->wbuf[i >> 2] |= (m1 << 8 * (~i & 3));
|
||||
|
||||
/* we need 9 or more empty positions, one for the padding byte */
|
||||
/* (above) and eight for the length count. If there is not */
|
||||
@@ -355,21 +380,21 @@ static void sha_end1(unsigned char hval[], sha256_ctx ctx[1], const unsigned int
|
||||
/* wrong byte order on little endian machines but this is */
|
||||
/* corrected later since they are only ever used as 32-bit */
|
||||
/* word values. */
|
||||
ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29);
|
||||
ctx->wbuf[15] = ctx->count[0] << 3;
|
||||
ctx->wbuf[14] = ctx->count[1];
|
||||
ctx->wbuf[15] = ctx->count[0];
|
||||
sha256_compile(ctx);
|
||||
|
||||
/* extract the hash value as bytes in case the hash buffer is */
|
||||
/* mislaigned for 32-bit words */
|
||||
/* misaligned for 32-bit words */
|
||||
for(i = 0; i < hlen; ++i)
|
||||
hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3)));
|
||||
hval[i] = ((ctx->hash[i >> 2] >> (8 * (~i & 3))) & 0xff);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(SHA_224)
|
||||
|
||||
const uint_32t i224[8] =
|
||||
const uint32_t i224[8] =
|
||||
{
|
||||
0xc1059ed8ul, 0x367cd507ul, 0x3070dd17ul, 0xf70e5939ul,
|
||||
0xffc00b31ul, 0x68581511ul, 0x64f98fa7ul, 0xbefa4fa4ul
|
||||
@@ -377,8 +402,8 @@ const uint_32t i224[8] =
|
||||
|
||||
VOID_RETURN sha224_begin(sha224_ctx ctx[1])
|
||||
{
|
||||
ctx->count[0] = ctx->count[1] = 0;
|
||||
memcpy(ctx->hash, i224, 8 * sizeof(uint_32t));
|
||||
memset(ctx, 0, sizeof(sha224_ctx));
|
||||
memcpy(ctx->hash, i224, sizeof(ctx->hash));
|
||||
}
|
||||
|
||||
VOID_RETURN sha224_end(unsigned char hval[], sha224_ctx ctx[1])
|
||||
@@ -398,7 +423,7 @@ VOID_RETURN sha224(unsigned char hval[], const unsigned char data[], unsigned lo
|
||||
|
||||
#if defined(SHA_256)
|
||||
|
||||
const uint_32t i256[8] =
|
||||
const uint32_t i256[8] =
|
||||
{
|
||||
0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul,
|
||||
0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul
|
||||
@@ -406,8 +431,8 @@ const uint_32t i256[8] =
|
||||
|
||||
VOID_RETURN sha256_begin(sha256_ctx ctx[1])
|
||||
{
|
||||
ctx->count[0] = ctx->count[1] = 0;
|
||||
memcpy(ctx->hash, i256, 8 * sizeof(uint_32t));
|
||||
memset(ctx, 0, sizeof(sha256_ctx));
|
||||
memcpy(ctx->hash, i256, sizeof(ctx->hash));
|
||||
}
|
||||
|
||||
VOID_RETURN sha256_end(unsigned char hval[], sha256_ctx ctx[1])
|
||||
@@ -432,12 +457,12 @@ VOID_RETURN sha256(unsigned char hval[], const unsigned char data[], unsigned lo
|
||||
#define rotr64(x,n) (((x) >> n) | ((x) << (64 - n)))
|
||||
|
||||
#if !defined(bswap_64)
|
||||
#define bswap_64(x) (((uint_64t)(bswap_32((uint_32t)(x)))) << 32 | bswap_32((uint_32t)((x) >> 32)))
|
||||
#define bswap_64(x) (((uint64_t)(bswap_32((uint32_t)(x)))) << 32 | bswap_32((uint32_t)((x) >> 32)))
|
||||
#endif
|
||||
|
||||
#if defined(SWAP_BYTES)
|
||||
#define bsw_64(p,n) \
|
||||
{ int _i = (n); while(_i--) ((uint_64t*)p)[_i] = bswap_64(((uint_64t*)p)[_i]); }
|
||||
{ int _i = (n); while(_i--) ((uint64_t*)p)[_i] = bswap_64(((uint64_t*)p)[_i]); }
|
||||
#else
|
||||
#define bsw_64(p,n)
|
||||
#endif
|
||||
@@ -460,7 +485,7 @@ VOID_RETURN sha256(unsigned char hval[], const unsigned char data[], unsigned lo
|
||||
|
||||
/* SHA384/SHA512 mixing data */
|
||||
|
||||
const uint_64t k512[80] =
|
||||
const uint64_t k512[80] =
|
||||
{
|
||||
li_64(428a2f98d728ae22), li_64(7137449123ef65cd),
|
||||
li_64(b5c0fbcfec4d3b2f), li_64(e9b5dba58189dbbc),
|
||||
@@ -511,10 +536,10 @@ const uint_64t k512[80] =
|
||||
/* words on BOTH big and little endian systems */
|
||||
|
||||
VOID_RETURN sha512_compile(sha512_ctx ctx[1])
|
||||
{ uint_64t v[8], *p = ctx->wbuf;
|
||||
uint_32t j;
|
||||
{ uint64_t v[8], *p = ctx->wbuf;
|
||||
uint32_t j;
|
||||
|
||||
memcpy(v, ctx->hash, 8 * sizeof(uint_64t));
|
||||
memcpy(v, ctx->hash, sizeof(ctx->hash));
|
||||
|
||||
for(j = 0; j < 80; j += 16)
|
||||
{
|
||||
@@ -542,40 +567,76 @@ VOID_RETURN sha512_compile(sha512_ctx ctx[1])
|
||||
/* and little endian systems */
|
||||
|
||||
VOID_RETURN sha512_hash(const unsigned char data[], unsigned long len, sha512_ctx ctx[1])
|
||||
{ uint_32t pos = (uint_32t)(ctx->count[0] & SHA512_MASK),
|
||||
space = SHA512_BLOCK_SIZE - pos;
|
||||
{ uint32_t pos = (uint32_t)(ctx->count[0] >> 3) & SHA512_MASK;
|
||||
const unsigned char *sp = data;
|
||||
unsigned char *w = (unsigned char*)ctx->wbuf;
|
||||
#if SHA2_BITS == 1
|
||||
uint32_t ofs = (ctx->count[0] & 7);
|
||||
#else
|
||||
len <<= 3;
|
||||
#endif
|
||||
|
||||
if((ctx->count[0] += len) < len)
|
||||
++(ctx->count[1]);
|
||||
|
||||
while(len >= space) /* tranfer whole blocks while possible */
|
||||
#if SHA2_BITS == 1
|
||||
if(ofs) /* if not on a byte boundary */
|
||||
{
|
||||
memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
|
||||
sp += space; len -= space; space = SHA512_BLOCK_SIZE; pos = 0;
|
||||
bsw_64(ctx->wbuf, SHA512_BLOCK_SIZE >> 3);
|
||||
sha512_compile(ctx);
|
||||
}
|
||||
if(ofs + len < 8) /* if no added bytes are needed */
|
||||
{
|
||||
w[pos] |= (*sp >> ofs);
|
||||
}
|
||||
else /* otherwise and add bytes */
|
||||
{ unsigned char part = w[pos];
|
||||
|
||||
memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);
|
||||
while((int)(ofs + (len -= 8)) >= 0)
|
||||
{
|
||||
w[pos++] = part | (*sp >> ofs);
|
||||
part = *sp++ << (8 - ofs);
|
||||
if(pos == SHA512_BLOCK_SIZE)
|
||||
{
|
||||
bsw_64(w, SHA512_BLOCK_SIZE >> 3);
|
||||
sha512_compile(ctx); pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
w[pos] = part;
|
||||
}
|
||||
}
|
||||
else /* data is byte aligned */
|
||||
#endif
|
||||
{ uint32_t space = SHA512_BLOCK_SIZE - pos;
|
||||
|
||||
while(len >= (space << 3))
|
||||
{
|
||||
memcpy(w + pos, sp, space);
|
||||
bsw_64(w, SHA512_BLOCK_SIZE >> 3);
|
||||
sha512_compile(ctx);
|
||||
sp += space; len -= (space << 3);
|
||||
space = SHA512_BLOCK_SIZE; pos = 0;
|
||||
}
|
||||
memcpy(w + pos, sp, (len + 7 * SHA2_BITS) >> 3);
|
||||
}
|
||||
}
|
||||
|
||||
/* SHA384/512 Final padding and digest calculation */
|
||||
|
||||
static void sha_end2(unsigned char hval[], sha512_ctx ctx[1], const unsigned int hlen)
|
||||
{ uint_32t i = (uint_32t)(ctx->count[0] & SHA512_MASK);
|
||||
{ uint32_t i = (uint32_t)((ctx->count[0] >> 3) & SHA512_MASK);
|
||||
uint64_t m1;
|
||||
|
||||
/* put bytes in the buffer in an order in which references to */
|
||||
/* 32-bit words will put bytes with lower addresses into the */
|
||||
/* top of 32 bit words on BOTH big and little endian machines */
|
||||
bsw_64(ctx->wbuf, (i + 7) >> 3);
|
||||
bsw_64(ctx->wbuf, (i + 7 + SHA2_BITS) >> 3);
|
||||
|
||||
/* we now need to mask valid bytes and add the padding which is */
|
||||
/* a single 1 bit and as many zero bits as necessary. Note that */
|
||||
/* we can always add the first padding byte here because the */
|
||||
/* buffer always has at least one empty slot */
|
||||
ctx->wbuf[i >> 3] &= li_64(ffffffffffffff00) << 8 * (~i & 7);
|
||||
ctx->wbuf[i >> 3] |= li_64(0000000000000080) << 8 * (~i & 7);
|
||||
m1 = (unsigned char)0x80 >> (ctx->count[0] & 7);
|
||||
ctx->wbuf[i >> 3] &= ((li_64(ffffffffffffff00) | (~m1 + 1)) << 8 * (~i & 7));
|
||||
ctx->wbuf[i >> 3] |= (m1 << 8 * (~i & 7));
|
||||
|
||||
/* we need 17 or more empty byte positions, one for the padding */
|
||||
/* byte (above) and sixteen for the length count. If there is */
|
||||
@@ -596,14 +657,14 @@ static void sha_end2(unsigned char hval[], sha512_ctx ctx[1], const unsigned int
|
||||
/* wrong byte order on little endian machines but this is */
|
||||
/* corrected later since they are only ever used as 64-bit */
|
||||
/* word values. */
|
||||
ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 61);
|
||||
ctx->wbuf[15] = ctx->count[0] << 3;
|
||||
ctx->wbuf[14] = ctx->count[1];
|
||||
ctx->wbuf[15] = ctx->count[0];
|
||||
sha512_compile(ctx);
|
||||
|
||||
/* extract the hash value as bytes in case the hash buffer is */
|
||||
/* misaligned for 32-bit words */
|
||||
for(i = 0; i < hlen; ++i)
|
||||
hval[i] = (unsigned char)(ctx->hash[i >> 3] >> (8 * (~i & 7)));
|
||||
hval[i] = ((ctx->hash[i >> 3] >> (8 * (~i & 7))) & 0xff);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -612,7 +673,7 @@ static void sha_end2(unsigned char hval[], sha512_ctx ctx[1], const unsigned int
|
||||
|
||||
/* SHA384 initialisation data */
|
||||
|
||||
const uint_64t i384[80] =
|
||||
const uint64_t i384[80] =
|
||||
{
|
||||
li_64(cbbb9d5dc1059ed8), li_64(629a292a367cd507),
|
||||
li_64(9159015a3070dd17), li_64(152fecd8f70e5939),
|
||||
@@ -622,8 +683,8 @@ const uint_64t i384[80] =
|
||||
|
||||
VOID_RETURN sha384_begin(sha384_ctx ctx[1])
|
||||
{
|
||||
ctx->count[0] = ctx->count[1] = 0;
|
||||
memcpy(ctx->hash, i384, 8 * sizeof(uint_64t));
|
||||
memset(ctx, 0, sizeof(sha384_ctx));
|
||||
memcpy(ctx->hash, i384, sizeof(ctx->hash));
|
||||
}
|
||||
|
||||
VOID_RETURN sha384_end(unsigned char hval[], sha384_ctx ctx[1])
|
||||
@@ -645,7 +706,7 @@ VOID_RETURN sha384(unsigned char hval[], const unsigned char data[], unsigned lo
|
||||
|
||||
/* SHA512 initialisation data */
|
||||
|
||||
const uint_64t i512[80] =
|
||||
static const uint64_t i512[SHA512_DIGEST_SIZE >> 3] =
|
||||
{
|
||||
li_64(6a09e667f3bcc908), li_64(bb67ae8584caa73b),
|
||||
li_64(3c6ef372fe94f82b), li_64(a54ff53a5f1d36f1),
|
||||
@@ -653,10 +714,74 @@ const uint_64t i512[80] =
|
||||
li_64(1f83d9abfb41bd6b), li_64(5be0cd19137e2179)
|
||||
};
|
||||
|
||||
/* FIPS PUB 180-4: SHA-512/256 */
|
||||
|
||||
static const uint64_t i512_256[SHA512_DIGEST_SIZE >> 3] =
|
||||
{
|
||||
li_64(22312194fc2bf72c), li_64(9f555fa3c84c64c2),
|
||||
li_64(2393b86b6f53b151), li_64(963877195940eabd),
|
||||
li_64(96283ee2a88effe3), li_64(be5e1e2553863992),
|
||||
li_64(2b0199fc2c85b8aa), li_64(0eb72ddc81c52ca2),
|
||||
};
|
||||
|
||||
/* FIPS PUB 180-4: SHA-512/224 */
|
||||
|
||||
static const uint64_t i512_224[SHA512_DIGEST_SIZE >> 3] =
|
||||
{
|
||||
li_64(8c3d37c819544da2), li_64(73e1996689dcd4d6),
|
||||
li_64(1dfab7ae32ff9c82), li_64(679dd514582f9fcf),
|
||||
li_64(0f6d2b697bd44da8), li_64(77e36f7304c48942),
|
||||
li_64(3f9d85a86a1d36c8), li_64(1112e6ad91d692a1),
|
||||
};
|
||||
|
||||
/* FIPS PUB 180-4: SHA-512/192 (unsanctioned; facilitates using AES-192) */
|
||||
|
||||
static const uint64_t i512_192[SHA512_DIGEST_SIZE >> 3] =
|
||||
{
|
||||
li_64(010176140648b233), li_64(db92aeb1eebadd6f),
|
||||
li_64(83a9e27aa1d5ea62), li_64(ec95f77eb609b4e1),
|
||||
li_64(71a99185c75caefa), li_64(006e8f08baf32e3c),
|
||||
li_64(6a2b21abd2db2aec), li_64(24926cdbd918a27f),
|
||||
};
|
||||
|
||||
/* FIPS PUB 180-4: SHA-512/128 (unsanctioned; facilitates using AES-128) */
|
||||
|
||||
static const uint64_t i512_128[SHA512_DIGEST_SIZE >> 3] =
|
||||
{
|
||||
li_64(c953a21464c3e8cc), li_64(06cc9cfd166a34b5),
|
||||
li_64(647e88dabf8b24ab), li_64(8513e4dc05a078ac),
|
||||
li_64(7266fcfb7cba0534), li_64(854a78e2ecd19b93),
|
||||
li_64(8618061711cec2dd), li_64(b20d8506efb929b1),
|
||||
};
|
||||
|
||||
VOID_RETURN sha512_begin(sha512_ctx ctx[1])
|
||||
{
|
||||
ctx->count[0] = ctx->count[1] = 0;
|
||||
memcpy(ctx->hash, i512, 8 * sizeof(uint_64t));
|
||||
memset(ctx, 0, sizeof(sha512_ctx));
|
||||
memcpy(ctx->hash, i512, sizeof(ctx->hash));
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_256_begin(sha512_ctx ctx[1])
|
||||
{
|
||||
memset(ctx, 0, sizeof(sha512_ctx));
|
||||
memcpy(ctx->hash, i512_256, sizeof(ctx->hash));
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_224_begin(sha512_ctx ctx[1])
|
||||
{
|
||||
memset(ctx, 0, sizeof(sha512_ctx));
|
||||
memcpy(ctx->hash, i512_224, sizeof(ctx->hash));
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_192_begin(sha512_ctx ctx[1])
|
||||
{
|
||||
memset(ctx, 0, sizeof(sha512_ctx));
|
||||
memcpy(ctx->hash, i512_192, sizeof(ctx->hash));
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_128_begin(sha512_ctx ctx[1])
|
||||
{
|
||||
memset(ctx, 0, sizeof(sha512_ctx));
|
||||
memcpy(ctx->hash, i512_128, sizeof(ctx->hash));
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_end(unsigned char hval[], sha512_ctx ctx[1])
|
||||
@@ -664,12 +789,64 @@ VOID_RETURN sha512_end(unsigned char hval[], sha512_ctx ctx[1])
|
||||
sha_end2(hval, ctx, SHA512_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_256_end(unsigned char hval[], sha512_ctx ctx[1])
|
||||
{
|
||||
sha_end2(hval, ctx, SHA512_256_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_224_end(unsigned char hval[], sha512_ctx ctx[1])
|
||||
{
|
||||
sha_end2(hval, ctx, SHA512_224_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_192_end(unsigned char hval[], sha512_ctx ctx[1])
|
||||
{
|
||||
sha_end2(hval, ctx, SHA512_192_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_128_end(unsigned char hval[], sha512_ctx ctx[1])
|
||||
{
|
||||
sha_end2(hval, ctx, SHA512_128_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
VOID_RETURN sha512(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||
{ sha512_ctx cx[1];
|
||||
|
||||
sha512_begin(cx);
|
||||
sha512_hash(data, len, cx);
|
||||
sha_end2(hval, cx, SHA512_DIGEST_SIZE);
|
||||
sha512_end(hval, cx);
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_256(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||
{ sha512_ctx cx[1];
|
||||
|
||||
sha512_256_begin(cx);
|
||||
sha512_256_hash(data, len, cx);
|
||||
sha512_256_end(hval, cx);
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_224(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||
{ sha512_ctx cx[1];
|
||||
|
||||
sha512_224_begin(cx);
|
||||
sha512_224_hash(data, len, cx);
|
||||
sha512_224_end(hval, cx);
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_192(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||
{ sha512_ctx cx[1];
|
||||
|
||||
sha512_192_begin(cx);
|
||||
sha512_192_hash(data, len, cx);
|
||||
sha512_192_end(hval, cx);
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_128(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||
{ sha512_ctx cx[1];
|
||||
|
||||
sha512_128_begin(cx);
|
||||
sha512_128_hash(data, len, cx);
|
||||
sha512_128_end(hval, cx);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,33 +1,21 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved.
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
The free distribution and use of this software in both source and binary
|
||||
form is allowed (with or without changes) provided that:
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
1. distributions of this source code include the above copyright
|
||||
notice, this list of conditions and the following disclaimer;
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
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 Date: 01/08/2005
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#ifndef _SHA2_H
|
||||
@@ -35,18 +23,28 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define SHA_64BIT
|
||||
/* define for bit or byte oriented SHA */
|
||||
#if 1
|
||||
# define SHA2_BITS 0 /* byte oriented */
|
||||
#else
|
||||
# define SHA2_BITS 1 /* bit oriented */
|
||||
#endif
|
||||
|
||||
/* define the hash functions that you need */
|
||||
/* define for 64-bit SHA384 and SHA512 */
|
||||
#define SHA_64BIT
|
||||
#define SHA_2 /* for dynamic hash length */
|
||||
#define SHA_224
|
||||
#define SHA_256
|
||||
#ifdef SHA_64BIT
|
||||
# define SHA_384
|
||||
# define SHA_512
|
||||
# define NEED_UINT_64T
|
||||
# define NEED_uint64_t
|
||||
#endif
|
||||
|
||||
#define SHA2_MAX_DIGEST_SIZE 64
|
||||
#define SHA2_MAX_BLOCK_SIZE 128
|
||||
|
||||
#include "brg_types.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
@@ -59,19 +57,23 @@ extern "C"
|
||||
/* the length fields are in bytes or bits as is appropriate */
|
||||
/* for the version used. Bit sequences are arrays of bytes */
|
||||
/* in which bit sequence indexes increase from the most to */
|
||||
/* the least significant end of each byte */
|
||||
/* the least significant end of each byte. The value 'len' */
|
||||
/* in sha<nnn>_hash for the byte oriented versions of SHA2 */
|
||||
/* is limited to 2^29 bytes, but multiple calls will handle */
|
||||
/* longer data blocks. */
|
||||
|
||||
#define SHA224_DIGEST_SIZE 28
|
||||
#define SHA224_BLOCK_SIZE 64
|
||||
|
||||
#define SHA256_DIGEST_SIZE 32
|
||||
#define SHA256_BLOCK_SIZE 64
|
||||
|
||||
/* type to hold the SHA256 (and SHA224) context */
|
||||
|
||||
typedef struct
|
||||
{ uint_32t count[2];
|
||||
uint_32t hash[8];
|
||||
uint_32t wbuf[16];
|
||||
{ uint32_t count[2];
|
||||
uint32_t hash[SHA256_DIGEST_SIZE >> 2];
|
||||
uint32_t wbuf[SHA256_BLOCK_SIZE >> 2];
|
||||
} sha256_ctx;
|
||||
|
||||
typedef sha256_ctx sha224_ctx;
|
||||
@@ -94,25 +96,35 @@ typedef struct
|
||||
{ union
|
||||
{ sha256_ctx ctx256[1];
|
||||
} uu[1];
|
||||
uint_32t sha2_len;
|
||||
uint32_t sha2_len;
|
||||
} sha2_ctx;
|
||||
|
||||
#define SHA2_MAX_DIGEST_SIZE SHA256_DIGEST_SIZE
|
||||
|
||||
#else
|
||||
|
||||
#define SHA384_DIGEST_SIZE 48
|
||||
#define SHA384_BLOCK_SIZE 128
|
||||
|
||||
#define SHA512_DIGEST_SIZE 64
|
||||
#define SHA512_BLOCK_SIZE 128
|
||||
#define SHA2_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
|
||||
|
||||
#define SHA512_128_DIGEST_SIZE 16
|
||||
#define SHA512_128_BLOCK_SIZE SHA512_BLOCK_SIZE
|
||||
|
||||
#define SHA512_192_DIGEST_SIZE 24
|
||||
#define SHA512_192_BLOCK_SIZE SHA512_BLOCK_SIZE
|
||||
|
||||
#define SHA512_224_DIGEST_SIZE 28
|
||||
#define SHA512_224_BLOCK_SIZE SHA512_BLOCK_SIZE
|
||||
|
||||
#define SHA512_256_DIGEST_SIZE 32
|
||||
#define SHA512_256_BLOCK_SIZE SHA512_BLOCK_SIZE
|
||||
|
||||
/* type to hold the SHA384 (and SHA512) context */
|
||||
|
||||
typedef struct
|
||||
{ uint_64t count[2];
|
||||
uint_64t hash[8];
|
||||
uint_64t wbuf[16];
|
||||
{ uint64_t count[2];
|
||||
uint64_t hash[SHA512_DIGEST_SIZE >> 3];
|
||||
uint64_t wbuf[SHA512_BLOCK_SIZE >> 3];
|
||||
} sha512_ctx;
|
||||
|
||||
typedef sha512_ctx sha384_ctx;
|
||||
@@ -122,7 +134,7 @@ typedef struct
|
||||
{ sha256_ctx ctx256[1];
|
||||
sha512_ctx ctx512[1];
|
||||
} uu[1];
|
||||
uint_32t sha2_len;
|
||||
uint32_t sha2_len;
|
||||
} sha2_ctx;
|
||||
|
||||
VOID_RETURN sha512_compile(sha512_ctx ctx[1]);
|
||||
@@ -137,6 +149,26 @@ VOID_RETURN sha512_hash(const unsigned char data[], unsigned long len, sha512_ct
|
||||
VOID_RETURN sha512_end(unsigned char hval[], sha512_ctx ctx[1]);
|
||||
VOID_RETURN sha512(unsigned char hval[], const unsigned char data[], unsigned long len);
|
||||
|
||||
VOID_RETURN sha512_256_begin(sha512_ctx ctx[1]);
|
||||
#define sha512_256_hash sha512_hash
|
||||
VOID_RETURN sha512_256_end(unsigned char hval[], sha512_ctx ctx[1]);
|
||||
VOID_RETURN sha512_256(unsigned char hval[], const unsigned char data[], unsigned long len);
|
||||
|
||||
VOID_RETURN sha512_224_begin(sha512_ctx ctx[1]);
|
||||
#define sha512_224_hash sha512_hash
|
||||
VOID_RETURN sha512_224_end(unsigned char hval[], sha512_ctx ctx[1]);
|
||||
VOID_RETURN sha512_224(unsigned char hval[], const unsigned char data[], unsigned long len);
|
||||
|
||||
VOID_RETURN sha512_192_begin(sha512_ctx ctx[1]);
|
||||
#define sha512_192_hash sha512_hash
|
||||
VOID_RETURN sha512_192_end(unsigned char hval[], sha512_ctx ctx[1]);
|
||||
VOID_RETURN sha512_192(unsigned char hval[], const unsigned char data[], unsigned long len);
|
||||
|
||||
VOID_RETURN sha512_128_begin(sha512_ctx ctx[1]);
|
||||
#define sha512_128_hash sha512_hash
|
||||
VOID_RETURN sha512_128_end(unsigned char hval[], sha512_ctx ctx[1]);
|
||||
VOID_RETURN sha512_128(unsigned char hval[], const unsigned char data[], unsigned long len);
|
||||
|
||||
INT_RETURN sha2_begin(unsigned long size, sha2_ctx ctx[1]);
|
||||
VOID_RETURN sha2_hash(const unsigned char data[], unsigned long len, sha2_ctx ctx[1]);
|
||||
VOID_RETURN sha2_end(unsigned char hval[], sha2_ctx ctx[1]);
|
||||
|
||||
@@ -1,833 +0,0 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2002, 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 Date: 01/08/2005
|
||||
|
||||
This is a bit oriented version of SHA2 that operates on arrays of bytes
|
||||
stored in memory. This code implements sha256, sha384 and sha512 but the
|
||||
latter two functions rely on efficient 64-bit integer operations that
|
||||
may not be very efficient on 32-bit machines
|
||||
|
||||
The sha256 functions use a type 'sha256_ctx' to hold details of the
|
||||
current hash state and uses the following three calls:
|
||||
|
||||
void sha256_begin(sha256_ctx ctx[1])
|
||||
void sha256_hash(const unsigned char data[],
|
||||
unsigned long len, sha256_ctx ctx[1])
|
||||
void sha_end1(unsigned char hval[], sha256_ctx ctx[1])
|
||||
|
||||
The first subroutine initialises a hash computation by setting up the
|
||||
context in the sha256_ctx context. The second subroutine hashes 8-bit
|
||||
bytes from array data[] into the hash state withinh sha256_ctx context,
|
||||
the number of bytes to be hashed being given by the the unsigned long
|
||||
integer len. The third subroutine completes the hash calculation and
|
||||
places the resulting digest value in the array of 8-bit bytes hval[].
|
||||
|
||||
The sha384 and sha512 functions are similar and use the interfaces:
|
||||
|
||||
void sha384_begin(sha384_ctx ctx[1]);
|
||||
void sha384_hash(const unsigned char data[],
|
||||
unsigned long len, sha384_ctx ctx[1]);
|
||||
void sha384_end(unsigned char hval[], sha384_ctx ctx[1]);
|
||||
|
||||
void sha512_begin(sha512_ctx ctx[1]);
|
||||
void sha512_hash(const unsigned char data[],
|
||||
unsigned long len, sha512_ctx ctx[1]);
|
||||
void sha512_end(unsigned char hval[], sha512_ctx ctx[1]);
|
||||
|
||||
In addition there is a function sha2 that can be used to call all these
|
||||
functions using a call with a hash length parameter as follows:
|
||||
|
||||
int sha2_begin(unsigned long len, sha2_ctx ctx[1]);
|
||||
void sha2_hash(const unsigned char data[],
|
||||
unsigned long len, sha2_ctx ctx[1]);
|
||||
void sha2_end(unsigned char hval[], sha2_ctx ctx[1]);
|
||||
|
||||
My thanks to Erik Andersen <andersen@codepoet.org> for testing this code
|
||||
on big-endian systems and for his assistance with corrections
|
||||
*/
|
||||
|
||||
#if 1
|
||||
#define UNROLL_SHA2 /* for SHA2 loop unroll */
|
||||
#endif
|
||||
|
||||
#include <string.h> /* for memcpy() etc. */
|
||||
|
||||
#include "sha2.h"
|
||||
#include "brg_endian.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if defined( _MSC_VER ) && ( _MSC_VER > 800 )
|
||||
#pragma intrinsic(memcpy)
|
||||
#endif
|
||||
|
||||
#if 0 && defined(_MSC_VER)
|
||||
#define rotl32 _lrotl
|
||||
#define rotr32 _lrotr
|
||||
#else
|
||||
#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
|
||||
#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n)))
|
||||
#endif
|
||||
|
||||
#if !defined(bswap_32)
|
||||
#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00))
|
||||
#endif
|
||||
|
||||
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
|
||||
#define SWAP_BYTES
|
||||
#else
|
||||
#undef SWAP_BYTES
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
#define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
|
||||
#define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||
|
||||
#else /* Thanks to Rich Schroeppel and Colin Plumb for the following */
|
||||
|
||||
#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
|
||||
#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y))))
|
||||
|
||||
#endif
|
||||
|
||||
/* round transforms for SHA256 and SHA512 compression functions */
|
||||
|
||||
#define vf(n,i) v[(n - i) & 7]
|
||||
|
||||
#define hf(i) (p[i & 15] += \
|
||||
g_1(p[(i + 14) & 15]) + p[(i + 9) & 15] + g_0(p[(i + 1) & 15]))
|
||||
|
||||
#define v_cycle(i,j) \
|
||||
vf(7,i) += (j ? hf(i) : p[i]) + k_0[i+j] \
|
||||
+ s_1(vf(4,i)) + ch(vf(4,i),vf(5,i),vf(6,i)); \
|
||||
vf(3,i) += vf(7,i); \
|
||||
vf(7,i) += s_0(vf(0,i))+ maj(vf(0,i),vf(1,i),vf(2,i))
|
||||
|
||||
#if defined(SHA_224) || defined(SHA_256)
|
||||
|
||||
#define SHA256_MASK (SHA256_BLOCK_SIZE - 1)
|
||||
|
||||
#if defined(SWAP_BYTES)
|
||||
#define bsw_32(p,n) \
|
||||
{ int _i = (n); while(_i--) ((uint_32t*)p)[_i] = bswap_32(((uint_32t*)p)[_i]); }
|
||||
#else
|
||||
#define bsw_32(p,n)
|
||||
#endif
|
||||
|
||||
#define s_0(x) (rotr32((x), 2) ^ rotr32((x), 13) ^ rotr32((x), 22))
|
||||
#define s_1(x) (rotr32((x), 6) ^ rotr32((x), 11) ^ rotr32((x), 25))
|
||||
#define g_0(x) (rotr32((x), 7) ^ rotr32((x), 18) ^ ((x) >> 3))
|
||||
#define g_1(x) (rotr32((x), 17) ^ rotr32((x), 19) ^ ((x) >> 10))
|
||||
#define k_0 k256
|
||||
|
||||
/* rotated SHA256 round definition. Rather than swapping variables as in */
|
||||
/* FIPS-180, different variables are 'rotated' on each round, returning */
|
||||
/* to their starting positions every eight rounds */
|
||||
|
||||
#define q(n) v##n
|
||||
|
||||
#define one_cycle(a,b,c,d,e,f,g,h,k,w) \
|
||||
q(h) += s_1(q(e)) + ch(q(e), q(f), q(g)) + k + w; \
|
||||
q(d) += q(h); q(h) += s_0(q(a)) + maj(q(a), q(b), q(c))
|
||||
|
||||
/* SHA256 mixing data */
|
||||
|
||||
const uint_32t k256[64] =
|
||||
{ 0x428a2f98ul, 0x71374491ul, 0xb5c0fbcful, 0xe9b5dba5ul,
|
||||
0x3956c25bul, 0x59f111f1ul, 0x923f82a4ul, 0xab1c5ed5ul,
|
||||
0xd807aa98ul, 0x12835b01ul, 0x243185beul, 0x550c7dc3ul,
|
||||
0x72be5d74ul, 0x80deb1feul, 0x9bdc06a7ul, 0xc19bf174ul,
|
||||
0xe49b69c1ul, 0xefbe4786ul, 0x0fc19dc6ul, 0x240ca1ccul,
|
||||
0x2de92c6ful, 0x4a7484aaul, 0x5cb0a9dcul, 0x76f988daul,
|
||||
0x983e5152ul, 0xa831c66dul, 0xb00327c8ul, 0xbf597fc7ul,
|
||||
0xc6e00bf3ul, 0xd5a79147ul, 0x06ca6351ul, 0x14292967ul,
|
||||
0x27b70a85ul, 0x2e1b2138ul, 0x4d2c6dfcul, 0x53380d13ul,
|
||||
0x650a7354ul, 0x766a0abbul, 0x81c2c92eul, 0x92722c85ul,
|
||||
0xa2bfe8a1ul, 0xa81a664bul, 0xc24b8b70ul, 0xc76c51a3ul,
|
||||
0xd192e819ul, 0xd6990624ul, 0xf40e3585ul, 0x106aa070ul,
|
||||
0x19a4c116ul, 0x1e376c08ul, 0x2748774cul, 0x34b0bcb5ul,
|
||||
0x391c0cb3ul, 0x4ed8aa4aul, 0x5b9cca4ful, 0x682e6ff3ul,
|
||||
0x748f82eeul, 0x78a5636ful, 0x84c87814ul, 0x8cc70208ul,
|
||||
0x90befffaul, 0xa4506cebul, 0xbef9a3f7ul, 0xc67178f2ul,
|
||||
};
|
||||
|
||||
/* Compile 64 bytes of hash data into SHA256 digest value */
|
||||
/* NOTE: this routine assumes that the byte order in the */
|
||||
/* ctx->wbuf[] at this point is such that low address bytes */
|
||||
/* in the ORIGINAL byte stream will go into the high end of */
|
||||
/* words on BOTH big and little endian systems */
|
||||
|
||||
VOID_RETURN sha256_compile(sha256_ctx ctx[1])
|
||||
{
|
||||
#if !defined(UNROLL_SHA2)
|
||||
|
||||
uint_32t j, *p = ctx->wbuf, v[8];
|
||||
|
||||
memcpy(v, ctx->hash, 8 * sizeof(uint_32t));
|
||||
|
||||
for(j = 0; j < 64; j += 16)
|
||||
{
|
||||
v_cycle( 0, j); v_cycle( 1, j);
|
||||
v_cycle( 2, j); v_cycle( 3, j);
|
||||
v_cycle( 4, j); v_cycle( 5, j);
|
||||
v_cycle( 6, j); v_cycle( 7, j);
|
||||
v_cycle( 8, j); v_cycle( 9, j);
|
||||
v_cycle(10, j); v_cycle(11, j);
|
||||
v_cycle(12, j); v_cycle(13, j);
|
||||
v_cycle(14, j); v_cycle(15, j);
|
||||
}
|
||||
|
||||
ctx->hash[0] += v[0]; ctx->hash[1] += v[1];
|
||||
ctx->hash[2] += v[2]; ctx->hash[3] += v[3];
|
||||
ctx->hash[4] += v[4]; ctx->hash[5] += v[5];
|
||||
ctx->hash[6] += v[6]; ctx->hash[7] += v[7];
|
||||
|
||||
#else
|
||||
|
||||
uint_32t *p = ctx->wbuf,v0,v1,v2,v3,v4,v5,v6,v7;
|
||||
|
||||
v0 = ctx->hash[0]; v1 = ctx->hash[1];
|
||||
v2 = ctx->hash[2]; v3 = ctx->hash[3];
|
||||
v4 = ctx->hash[4]; v5 = ctx->hash[5];
|
||||
v6 = ctx->hash[6]; v7 = ctx->hash[7];
|
||||
|
||||
one_cycle(0,1,2,3,4,5,6,7,k256[ 0],p[ 0]);
|
||||
one_cycle(7,0,1,2,3,4,5,6,k256[ 1],p[ 1]);
|
||||
one_cycle(6,7,0,1,2,3,4,5,k256[ 2],p[ 2]);
|
||||
one_cycle(5,6,7,0,1,2,3,4,k256[ 3],p[ 3]);
|
||||
one_cycle(4,5,6,7,0,1,2,3,k256[ 4],p[ 4]);
|
||||
one_cycle(3,4,5,6,7,0,1,2,k256[ 5],p[ 5]);
|
||||
one_cycle(2,3,4,5,6,7,0,1,k256[ 6],p[ 6]);
|
||||
one_cycle(1,2,3,4,5,6,7,0,k256[ 7],p[ 7]);
|
||||
one_cycle(0,1,2,3,4,5,6,7,k256[ 8],p[ 8]);
|
||||
one_cycle(7,0,1,2,3,4,5,6,k256[ 9],p[ 9]);
|
||||
one_cycle(6,7,0,1,2,3,4,5,k256[10],p[10]);
|
||||
one_cycle(5,6,7,0,1,2,3,4,k256[11],p[11]);
|
||||
one_cycle(4,5,6,7,0,1,2,3,k256[12],p[12]);
|
||||
one_cycle(3,4,5,6,7,0,1,2,k256[13],p[13]);
|
||||
one_cycle(2,3,4,5,6,7,0,1,k256[14],p[14]);
|
||||
one_cycle(1,2,3,4,5,6,7,0,k256[15],p[15]);
|
||||
|
||||
one_cycle(0,1,2,3,4,5,6,7,k256[16],hf( 0));
|
||||
one_cycle(7,0,1,2,3,4,5,6,k256[17],hf( 1));
|
||||
one_cycle(6,7,0,1,2,3,4,5,k256[18],hf( 2));
|
||||
one_cycle(5,6,7,0,1,2,3,4,k256[19],hf( 3));
|
||||
one_cycle(4,5,6,7,0,1,2,3,k256[20],hf( 4));
|
||||
one_cycle(3,4,5,6,7,0,1,2,k256[21],hf( 5));
|
||||
one_cycle(2,3,4,5,6,7,0,1,k256[22],hf( 6));
|
||||
one_cycle(1,2,3,4,5,6,7,0,k256[23],hf( 7));
|
||||
one_cycle(0,1,2,3,4,5,6,7,k256[24],hf( 8));
|
||||
one_cycle(7,0,1,2,3,4,5,6,k256[25],hf( 9));
|
||||
one_cycle(6,7,0,1,2,3,4,5,k256[26],hf(10));
|
||||
one_cycle(5,6,7,0,1,2,3,4,k256[27],hf(11));
|
||||
one_cycle(4,5,6,7,0,1,2,3,k256[28],hf(12));
|
||||
one_cycle(3,4,5,6,7,0,1,2,k256[29],hf(13));
|
||||
one_cycle(2,3,4,5,6,7,0,1,k256[30],hf(14));
|
||||
one_cycle(1,2,3,4,5,6,7,0,k256[31],hf(15));
|
||||
|
||||
one_cycle(0,1,2,3,4,5,6,7,k256[32],hf( 0));
|
||||
one_cycle(7,0,1,2,3,4,5,6,k256[33],hf( 1));
|
||||
one_cycle(6,7,0,1,2,3,4,5,k256[34],hf( 2));
|
||||
one_cycle(5,6,7,0,1,2,3,4,k256[35],hf( 3));
|
||||
one_cycle(4,5,6,7,0,1,2,3,k256[36],hf( 4));
|
||||
one_cycle(3,4,5,6,7,0,1,2,k256[37],hf( 5));
|
||||
one_cycle(2,3,4,5,6,7,0,1,k256[38],hf( 6));
|
||||
one_cycle(1,2,3,4,5,6,7,0,k256[39],hf( 7));
|
||||
one_cycle(0,1,2,3,4,5,6,7,k256[40],hf( 8));
|
||||
one_cycle(7,0,1,2,3,4,5,6,k256[41],hf( 9));
|
||||
one_cycle(6,7,0,1,2,3,4,5,k256[42],hf(10));
|
||||
one_cycle(5,6,7,0,1,2,3,4,k256[43],hf(11));
|
||||
one_cycle(4,5,6,7,0,1,2,3,k256[44],hf(12));
|
||||
one_cycle(3,4,5,6,7,0,1,2,k256[45],hf(13));
|
||||
one_cycle(2,3,4,5,6,7,0,1,k256[46],hf(14));
|
||||
one_cycle(1,2,3,4,5,6,7,0,k256[47],hf(15));
|
||||
|
||||
one_cycle(0,1,2,3,4,5,6,7,k256[48],hf( 0));
|
||||
one_cycle(7,0,1,2,3,4,5,6,k256[49],hf( 1));
|
||||
one_cycle(6,7,0,1,2,3,4,5,k256[50],hf( 2));
|
||||
one_cycle(5,6,7,0,1,2,3,4,k256[51],hf( 3));
|
||||
one_cycle(4,5,6,7,0,1,2,3,k256[52],hf( 4));
|
||||
one_cycle(3,4,5,6,7,0,1,2,k256[53],hf( 5));
|
||||
one_cycle(2,3,4,5,6,7,0,1,k256[54],hf( 6));
|
||||
one_cycle(1,2,3,4,5,6,7,0,k256[55],hf( 7));
|
||||
one_cycle(0,1,2,3,4,5,6,7,k256[56],hf( 8));
|
||||
one_cycle(7,0,1,2,3,4,5,6,k256[57],hf( 9));
|
||||
one_cycle(6,7,0,1,2,3,4,5,k256[58],hf(10));
|
||||
one_cycle(5,6,7,0,1,2,3,4,k256[59],hf(11));
|
||||
one_cycle(4,5,6,7,0,1,2,3,k256[60],hf(12));
|
||||
one_cycle(3,4,5,6,7,0,1,2,k256[61],hf(13));
|
||||
one_cycle(2,3,4,5,6,7,0,1,k256[62],hf(14));
|
||||
one_cycle(1,2,3,4,5,6,7,0,k256[63],hf(15));
|
||||
|
||||
ctx->hash[0] += v0; ctx->hash[1] += v1;
|
||||
ctx->hash[2] += v2; ctx->hash[3] += v3;
|
||||
ctx->hash[4] += v4; ctx->hash[5] += v5;
|
||||
ctx->hash[6] += v6; ctx->hash[7] += v7;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* SHA256 hash data in an array of bytes into hash buffer */
|
||||
/* and call the hash_compile function as required. */
|
||||
|
||||
VOID_RETURN sha256_hash(const unsigned char data[], unsigned long len, sha256_ctx ctx[1])
|
||||
{ uint_32t pos = (uint_32t)((ctx->count[0] >> 3) & SHA256_MASK),
|
||||
ofs = (ctx->count[0] & 7);
|
||||
const unsigned char *sp = data;
|
||||
unsigned char *w = (unsigned char*)ctx->wbuf;
|
||||
|
||||
if((ctx->count[0] += len) < len)
|
||||
++(ctx->count[1]);
|
||||
|
||||
if(ofs) /* if not on a byte boundary */
|
||||
{
|
||||
if(ofs + len < 8) /* if no added bytes are needed */
|
||||
{
|
||||
w[pos] |= (*sp >> ofs);
|
||||
}
|
||||
else /* otherwise and add bytes */
|
||||
{ unsigned char part = w[pos];
|
||||
|
||||
while((int)(ofs + (len -= 8)) >= 0)
|
||||
{
|
||||
w[pos++] = part | (*sp >> ofs);
|
||||
part = *sp++ << (8 - ofs);
|
||||
if(pos == SHA256_BLOCK_SIZE)
|
||||
{
|
||||
bsw_32(w, SHA256_BLOCK_SIZE >> 2);
|
||||
sha256_compile(ctx); pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
w[pos] = part;
|
||||
}
|
||||
}
|
||||
else /* data is byte aligned */
|
||||
{ uint_32t space = SHA256_BLOCK_SIZE - pos;
|
||||
|
||||
while((int)(len - 8 * space) >= 0)
|
||||
{
|
||||
len -= 8 * space;
|
||||
memcpy(w + pos, sp, space);
|
||||
sp += space;
|
||||
space = SHA256_BLOCK_SIZE;
|
||||
bsw_32(w, SHA256_BLOCK_SIZE >> 2);
|
||||
sha256_compile(ctx); pos = 0;
|
||||
}
|
||||
memcpy(w + pos, sp, (len + 7) >> 3);
|
||||
}
|
||||
}
|
||||
|
||||
/* SHA256 Final padding and digest calculation */
|
||||
|
||||
static void sha_end1(unsigned char hval[], sha256_ctx ctx[1], const unsigned int hlen)
|
||||
{ uint_32t i = (uint_32t)((ctx->count[0] >> 3) & SHA256_MASK), m1;
|
||||
|
||||
/* put bytes in the buffer in an order in which references to */
|
||||
/* 32-bit words will put bytes with lower addresses into the */
|
||||
/* top of 32 bit words on BOTH big and little endian machines */
|
||||
bsw_32(ctx->wbuf, (i + 4) >> 2)
|
||||
|
||||
/* we now need to mask valid bytes and add the padding which is */
|
||||
/* a single 1 bit and as many zero bits as necessary. Note that */
|
||||
/* we can always add the first padding byte here because the */
|
||||
/* buffer always has at least one empty slot */
|
||||
m1 = (unsigned char)0x80 >> (ctx->count[0] & 7);
|
||||
ctx->wbuf[i >> 2] &= ((0xffffff00 | (~m1 + 1)) << 8 * (~i & 3));
|
||||
ctx->wbuf[i >> 2] |= (m1 << 8 * (~i & 3));
|
||||
|
||||
/* we need 9 or more empty positions, one for the padding byte */
|
||||
/* (above) and eight for the length count. If there is not */
|
||||
/* enough space pad and empty the buffer */
|
||||
if(i > SHA256_BLOCK_SIZE - 9)
|
||||
{
|
||||
if(i < 60) ctx->wbuf[15] = 0;
|
||||
sha256_compile(ctx);
|
||||
i = 0;
|
||||
}
|
||||
else /* compute a word index for the empty buffer positions */
|
||||
i = (i >> 2) + 1;
|
||||
|
||||
while(i < 14) /* and zero pad all but last two positions */
|
||||
ctx->wbuf[i++] = 0;
|
||||
|
||||
/* the following 32-bit length fields are assembled in the */
|
||||
/* wrong byte order on little endian machines but this is */
|
||||
/* corrected later since they are only ever used as 32-bit */
|
||||
/* word values. */
|
||||
ctx->wbuf[14] = ctx->count[1];
|
||||
ctx->wbuf[15] = ctx->count[0];
|
||||
sha256_compile(ctx);
|
||||
|
||||
/* extract the hash value as bytes in case the hash buffer is */
|
||||
/* mislaigned for 32-bit words */
|
||||
for(i = 0; i < hlen; ++i)
|
||||
hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3)));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(SHA_224)
|
||||
|
||||
const uint_32t i224[8] =
|
||||
{
|
||||
0xc1059ed8ul, 0x367cd507ul, 0x3070dd17ul, 0xf70e5939ul,
|
||||
0xffc00b31ul, 0x68581511ul, 0x64f98fa7ul, 0xbefa4fa4ul
|
||||
};
|
||||
|
||||
VOID_RETURN sha224_begin(sha224_ctx ctx[1])
|
||||
{
|
||||
ctx->count[0] = ctx->count[1] = 0;
|
||||
memcpy(ctx->hash, i224, 8 * sizeof(uint_32t));
|
||||
}
|
||||
|
||||
VOID_RETURN sha224_end(unsigned char hval[], sha224_ctx ctx[1])
|
||||
{
|
||||
sha_end1(hval, ctx, SHA224_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
VOID_RETURN sha224(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||
{ sha224_ctx cx[1];
|
||||
|
||||
sha224_begin(cx);
|
||||
sha224_hash(data, len, cx);
|
||||
sha_end1(hval, cx, SHA224_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(SHA_256)
|
||||
|
||||
const uint_32t i256[8] =
|
||||
{
|
||||
0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul,
|
||||
0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul
|
||||
};
|
||||
|
||||
VOID_RETURN sha256_begin(sha256_ctx ctx[1])
|
||||
{
|
||||
ctx->count[0] = ctx->count[1] = 0;
|
||||
memcpy(ctx->hash, i256, 8 * sizeof(uint_32t));
|
||||
}
|
||||
|
||||
VOID_RETURN sha256_end(unsigned char hval[], sha256_ctx ctx[1])
|
||||
{
|
||||
sha_end1(hval, ctx, SHA256_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
VOID_RETURN sha256(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||
{ sha256_ctx cx[1];
|
||||
|
||||
sha256_begin(cx);
|
||||
sha256_hash(data, len, cx);
|
||||
sha_end1(hval, cx, SHA256_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(SHA_384) || defined(SHA_512)
|
||||
|
||||
#define SHA512_MASK (SHA512_BLOCK_SIZE - 1)
|
||||
|
||||
#define rotr64(x,n) (((x) >> n) | ((x) << (64 - n)))
|
||||
|
||||
#if !defined(bswap_64)
|
||||
#define bswap_64(x) (((uint_64t)(bswap_32((uint_32t)(x)))) << 32 | bswap_32((uint_32t)((x) >> 32)))
|
||||
#endif
|
||||
|
||||
#if defined(SWAP_BYTES)
|
||||
#define bsw_64(p,n) \
|
||||
{ int _i = (n); while(_i--) ((uint_64t*)p)[_i] = bswap_64(((uint_64t*)p)[_i]); }
|
||||
#else
|
||||
#define bsw_64(p,n)
|
||||
#endif
|
||||
|
||||
/* SHA512 mixing function definitions */
|
||||
|
||||
#ifdef s_0
|
||||
# undef s_0
|
||||
# undef s_1
|
||||
# undef g_0
|
||||
# undef g_1
|
||||
# undef k_0
|
||||
#endif
|
||||
|
||||
#define s_0(x) (rotr64((x), 28) ^ rotr64((x), 34) ^ rotr64((x), 39))
|
||||
#define s_1(x) (rotr64((x), 14) ^ rotr64((x), 18) ^ rotr64((x), 41))
|
||||
#define g_0(x) (rotr64((x), 1) ^ rotr64((x), 8) ^ ((x) >> 7))
|
||||
#define g_1(x) (rotr64((x), 19) ^ rotr64((x), 61) ^ ((x) >> 6))
|
||||
#define k_0 k512
|
||||
|
||||
/* SHA384/SHA512 mixing data */
|
||||
|
||||
const uint_64t k512[80] =
|
||||
{
|
||||
li_64(428a2f98d728ae22), li_64(7137449123ef65cd),
|
||||
li_64(b5c0fbcfec4d3b2f), li_64(e9b5dba58189dbbc),
|
||||
li_64(3956c25bf348b538), li_64(59f111f1b605d019),
|
||||
li_64(923f82a4af194f9b), li_64(ab1c5ed5da6d8118),
|
||||
li_64(d807aa98a3030242), li_64(12835b0145706fbe),
|
||||
li_64(243185be4ee4b28c), li_64(550c7dc3d5ffb4e2),
|
||||
li_64(72be5d74f27b896f), li_64(80deb1fe3b1696b1),
|
||||
li_64(9bdc06a725c71235), li_64(c19bf174cf692694),
|
||||
li_64(e49b69c19ef14ad2), li_64(efbe4786384f25e3),
|
||||
li_64(0fc19dc68b8cd5b5), li_64(240ca1cc77ac9c65),
|
||||
li_64(2de92c6f592b0275), li_64(4a7484aa6ea6e483),
|
||||
li_64(5cb0a9dcbd41fbd4), li_64(76f988da831153b5),
|
||||
li_64(983e5152ee66dfab), li_64(a831c66d2db43210),
|
||||
li_64(b00327c898fb213f), li_64(bf597fc7beef0ee4),
|
||||
li_64(c6e00bf33da88fc2), li_64(d5a79147930aa725),
|
||||
li_64(06ca6351e003826f), li_64(142929670a0e6e70),
|
||||
li_64(27b70a8546d22ffc), li_64(2e1b21385c26c926),
|
||||
li_64(4d2c6dfc5ac42aed), li_64(53380d139d95b3df),
|
||||
li_64(650a73548baf63de), li_64(766a0abb3c77b2a8),
|
||||
li_64(81c2c92e47edaee6), li_64(92722c851482353b),
|
||||
li_64(a2bfe8a14cf10364), li_64(a81a664bbc423001),
|
||||
li_64(c24b8b70d0f89791), li_64(c76c51a30654be30),
|
||||
li_64(d192e819d6ef5218), li_64(d69906245565a910),
|
||||
li_64(f40e35855771202a), li_64(106aa07032bbd1b8),
|
||||
li_64(19a4c116b8d2d0c8), li_64(1e376c085141ab53),
|
||||
li_64(2748774cdf8eeb99), li_64(34b0bcb5e19b48a8),
|
||||
li_64(391c0cb3c5c95a63), li_64(4ed8aa4ae3418acb),
|
||||
li_64(5b9cca4f7763e373), li_64(682e6ff3d6b2b8a3),
|
||||
li_64(748f82ee5defb2fc), li_64(78a5636f43172f60),
|
||||
li_64(84c87814a1f0ab72), li_64(8cc702081a6439ec),
|
||||
li_64(90befffa23631e28), li_64(a4506cebde82bde9),
|
||||
li_64(bef9a3f7b2c67915), li_64(c67178f2e372532b),
|
||||
li_64(ca273eceea26619c), li_64(d186b8c721c0c207),
|
||||
li_64(eada7dd6cde0eb1e), li_64(f57d4f7fee6ed178),
|
||||
li_64(06f067aa72176fba), li_64(0a637dc5a2c898a6),
|
||||
li_64(113f9804bef90dae), li_64(1b710b35131c471b),
|
||||
li_64(28db77f523047d84), li_64(32caab7b40c72493),
|
||||
li_64(3c9ebe0a15c9bebc), li_64(431d67c49c100d4c),
|
||||
li_64(4cc5d4becb3e42b6), li_64(597f299cfc657e2a),
|
||||
li_64(5fcb6fab3ad6faec), li_64(6c44198c4a475817)
|
||||
};
|
||||
|
||||
/* Compile 128 bytes of hash data into SHA384/512 digest */
|
||||
/* NOTE: this routine assumes that the byte order in the */
|
||||
/* ctx->wbuf[] at this point is such that low address bytes */
|
||||
/* in the ORIGINAL byte stream will go into the high end of */
|
||||
/* words on BOTH big and little endian systems */
|
||||
|
||||
VOID_RETURN sha512_compile(sha512_ctx ctx[1])
|
||||
{ uint_64t v[8], *p = ctx->wbuf;
|
||||
uint_32t j;
|
||||
|
||||
memcpy(v, ctx->hash, 8 * sizeof(uint_64t));
|
||||
|
||||
for(j = 0; j < 80; j += 16)
|
||||
{
|
||||
v_cycle( 0, j); v_cycle( 1, j);
|
||||
v_cycle( 2, j); v_cycle( 3, j);
|
||||
v_cycle( 4, j); v_cycle( 5, j);
|
||||
v_cycle( 6, j); v_cycle( 7, j);
|
||||
v_cycle( 8, j); v_cycle( 9, j);
|
||||
v_cycle(10, j); v_cycle(11, j);
|
||||
v_cycle(12, j); v_cycle(13, j);
|
||||
v_cycle(14, j); v_cycle(15, j);
|
||||
}
|
||||
|
||||
ctx->hash[0] += v[0]; ctx->hash[1] += v[1];
|
||||
ctx->hash[2] += v[2]; ctx->hash[3] += v[3];
|
||||
ctx->hash[4] += v[4]; ctx->hash[5] += v[5];
|
||||
ctx->hash[6] += v[6]; ctx->hash[7] += v[7];
|
||||
}
|
||||
|
||||
/* Compile 128 bytes of hash data into SHA256 digest value */
|
||||
/* NOTE: this routine assumes that the byte order in the */
|
||||
/* ctx->wbuf[] at this point is in such an order that low */
|
||||
/* address bytes in the ORIGINAL byte stream placed in this */
|
||||
/* buffer will now go to the high end of words on BOTH big */
|
||||
/* and little endian systems */
|
||||
|
||||
VOID_RETURN sha512_hash(const unsigned char data[], unsigned long len, sha512_ctx ctx[1])
|
||||
{ uint_32t pos = (uint_32t)(ctx->count[0] >> 3) & SHA512_MASK,
|
||||
ofs = (uint_32t)(ctx->count[0] & 7);
|
||||
const unsigned char *sp = data;
|
||||
unsigned char *w = (unsigned char*)ctx->wbuf;
|
||||
|
||||
if((ctx->count[0] += len) < len)
|
||||
++(ctx->count[1]);
|
||||
|
||||
if(ofs) /* if not on a byte boundary */
|
||||
{
|
||||
if(ofs + len < 8) /* if no added bytes are needed */
|
||||
{
|
||||
w[pos] |= (*sp >> ofs);
|
||||
}
|
||||
else /* otherwise and add bytes */
|
||||
{ unsigned char part = w[pos];
|
||||
|
||||
while((int)(ofs + (len -= 8)) >= 0)
|
||||
{
|
||||
w[pos++] = part | (*sp >> ofs);
|
||||
part = *sp++ << (8 - ofs);
|
||||
if(pos == SHA512_BLOCK_SIZE)
|
||||
{
|
||||
bsw_64(w, SHA512_BLOCK_SIZE >> 3);
|
||||
sha512_compile(ctx); pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
w[pos] = part;
|
||||
}
|
||||
}
|
||||
else /* data is byte aligned */
|
||||
{ uint_32t space = SHA512_BLOCK_SIZE - pos;
|
||||
|
||||
while((int)(len - 8 * space) >= 0)
|
||||
{
|
||||
len -= 8 * space;
|
||||
memcpy(w + pos, sp, space);
|
||||
sp += space;
|
||||
space = SHA512_BLOCK_SIZE;
|
||||
bsw_64(w, SHA512_BLOCK_SIZE >> 3);
|
||||
sha512_compile(ctx); pos = 0;
|
||||
}
|
||||
memcpy(w + pos, sp, (len + 7) >> 3);
|
||||
}
|
||||
}
|
||||
|
||||
/* SHA384/512 Final padding and digest calculation */
|
||||
|
||||
static void sha_end2(unsigned char hval[], sha512_ctx ctx[1], const unsigned int hlen)
|
||||
{ uint_32t i = (uint_32t)((ctx->count[0] >> 3) & SHA512_MASK);
|
||||
uint_64t m1;
|
||||
|
||||
/* put bytes in the buffer in an order in which references to */
|
||||
/* 32-bit words will put bytes with lower addresses into the */
|
||||
/* top of 32 bit words on BOTH big and little endian machines */
|
||||
bsw_64(ctx->wbuf, (i + 8) >> 3);
|
||||
|
||||
/* we now need to mask valid bytes and add the padding which is */
|
||||
/* a single 1 bit and as many zero bits as necessary. Note that */
|
||||
/* we can always add the first padding byte here because the */
|
||||
/* buffer always has at least one empty slot */
|
||||
m1 = (unsigned char)0x80 >> (ctx->count[0] & 7);
|
||||
ctx->wbuf[i >> 3] &= ((li_64(ffffffffffffff00) | (~m1 + 1)) << 8 * (~i & 7));
|
||||
ctx->wbuf[i >> 3] |= (m1 << 8 * (~i & 7));
|
||||
|
||||
/* we need 17 or more empty byte positions, one for the padding */
|
||||
/* byte (above) and sixteen for the length count. If there is */
|
||||
/* not enough space pad and empty the buffer */
|
||||
if(i > SHA512_BLOCK_SIZE - 17)
|
||||
{
|
||||
if(i < 120) ctx->wbuf[15] = 0;
|
||||
sha512_compile(ctx);
|
||||
i = 0;
|
||||
}
|
||||
else
|
||||
i = (i >> 3) + 1;
|
||||
|
||||
while(i < 14)
|
||||
ctx->wbuf[i++] = 0;
|
||||
|
||||
/* the following 64-bit length fields are assembled in the */
|
||||
/* wrong byte order on little endian machines but this is */
|
||||
/* corrected later since they are only ever used as 64-bit */
|
||||
/* word values. */
|
||||
ctx->wbuf[14] = ctx->count[1];
|
||||
ctx->wbuf[15] = ctx->count[0];
|
||||
sha512_compile(ctx);
|
||||
|
||||
/* extract the hash value as bytes in case the hash buffer is */
|
||||
/* misaligned for 32-bit words */
|
||||
for(i = 0; i < hlen; ++i)
|
||||
hval[i] = (unsigned char)(ctx->hash[i >> 3] >> (8 * (~i & 7)));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(SHA_384)
|
||||
|
||||
/* SHA384 initialisation data */
|
||||
|
||||
const uint_64t i384[80] =
|
||||
{
|
||||
li_64(cbbb9d5dc1059ed8), li_64(629a292a367cd507),
|
||||
li_64(9159015a3070dd17), li_64(152fecd8f70e5939),
|
||||
li_64(67332667ffc00b31), li_64(8eb44a8768581511),
|
||||
li_64(db0c2e0d64f98fa7), li_64(47b5481dbefa4fa4)
|
||||
};
|
||||
|
||||
VOID_RETURN sha384_begin(sha384_ctx ctx[1])
|
||||
{
|
||||
ctx->count[0] = ctx->count[1] = 0;
|
||||
memcpy(ctx->hash, i384, 8 * sizeof(uint_64t));
|
||||
}
|
||||
|
||||
VOID_RETURN sha384_end(unsigned char hval[], sha384_ctx ctx[1])
|
||||
{
|
||||
sha_end2(hval, ctx, SHA384_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
VOID_RETURN sha384(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||
{ sha384_ctx cx[1];
|
||||
|
||||
sha384_begin(cx);
|
||||
sha384_hash(data, len, cx);
|
||||
sha_end2(hval, cx, SHA384_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(SHA_512)
|
||||
|
||||
/* SHA512 initialisation data */
|
||||
|
||||
const uint_64t i512[80] =
|
||||
{
|
||||
li_64(6a09e667f3bcc908), li_64(bb67ae8584caa73b),
|
||||
li_64(3c6ef372fe94f82b), li_64(a54ff53a5f1d36f1),
|
||||
li_64(510e527fade682d1), li_64(9b05688c2b3e6c1f),
|
||||
li_64(1f83d9abfb41bd6b), li_64(5be0cd19137e2179)
|
||||
};
|
||||
|
||||
VOID_RETURN sha512_begin(sha512_ctx ctx[1])
|
||||
{
|
||||
ctx->count[0] = ctx->count[1] = 0;
|
||||
memcpy(ctx->hash, i512, 8 * sizeof(uint_64t));
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_end(unsigned char hval[], sha512_ctx ctx[1])
|
||||
{
|
||||
sha_end2(hval, ctx, SHA512_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
VOID_RETURN sha512(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||
{ sha512_ctx cx[1];
|
||||
|
||||
sha512_begin(cx);
|
||||
sha512_hash(data, len, cx);
|
||||
sha_end2(hval, cx, SHA512_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(SHA_2)
|
||||
|
||||
#define CTX_224(x) ((x)->uu->ctx256)
|
||||
#define CTX_256(x) ((x)->uu->ctx256)
|
||||
#define CTX_384(x) ((x)->uu->ctx512)
|
||||
#define CTX_512(x) ((x)->uu->ctx512)
|
||||
|
||||
/* SHA2 initialisation */
|
||||
|
||||
INT_RETURN sha2_begin(unsigned long len, sha2_ctx ctx[1])
|
||||
{
|
||||
switch(len)
|
||||
{
|
||||
#if defined(SHA_224)
|
||||
case 224:
|
||||
case 28: CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0;
|
||||
memcpy(CTX_256(ctx)->hash, i224, 32);
|
||||
ctx->sha2_len = 28; return EXIT_SUCCESS;
|
||||
#endif
|
||||
#if defined(SHA_256)
|
||||
case 256:
|
||||
case 32: CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0;
|
||||
memcpy(CTX_256(ctx)->hash, i256, 32);
|
||||
ctx->sha2_len = 32; return EXIT_SUCCESS;
|
||||
#endif
|
||||
#if defined(SHA_384)
|
||||
case 384:
|
||||
case 48: CTX_384(ctx)->count[0] = CTX_384(ctx)->count[1] = 0;
|
||||
memcpy(CTX_384(ctx)->hash, i384, 64);
|
||||
ctx->sha2_len = 48; return EXIT_SUCCESS;
|
||||
#endif
|
||||
#if defined(SHA_512)
|
||||
case 512:
|
||||
case 64: CTX_512(ctx)->count[0] = CTX_512(ctx)->count[1] = 0;
|
||||
memcpy(CTX_512(ctx)->hash, i512, 64);
|
||||
ctx->sha2_len = 64; return EXIT_SUCCESS;
|
||||
#endif
|
||||
default: return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
VOID_RETURN sha2_hash(const unsigned char data[], unsigned long len, sha2_ctx ctx[1])
|
||||
{
|
||||
switch(ctx->sha2_len)
|
||||
{
|
||||
#if defined(SHA_224)
|
||||
case 28: sha224_hash(data, len, CTX_224(ctx)); return;
|
||||
#endif
|
||||
#if defined(SHA_256)
|
||||
case 32: sha256_hash(data, len, CTX_256(ctx)); return;
|
||||
#endif
|
||||
#if defined(SHA_384)
|
||||
case 48: sha384_hash(data, len, CTX_384(ctx)); return;
|
||||
#endif
|
||||
#if defined(SHA_512)
|
||||
case 64: sha512_hash(data, len, CTX_512(ctx)); return;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
VOID_RETURN sha2_end(unsigned char hval[], sha2_ctx ctx[1])
|
||||
{
|
||||
switch(ctx->sha2_len)
|
||||
{
|
||||
#if defined(SHA_224)
|
||||
case 28: sha_end1(hval, CTX_224(ctx), SHA224_DIGEST_SIZE); return;
|
||||
#endif
|
||||
#if defined(SHA_256)
|
||||
case 32: sha_end1(hval, CTX_256(ctx), SHA256_DIGEST_SIZE); return;
|
||||
#endif
|
||||
#if defined(SHA_384)
|
||||
case 48: sha_end2(hval, CTX_384(ctx), SHA384_DIGEST_SIZE); return;
|
||||
#endif
|
||||
#if defined(SHA_512)
|
||||
case 64: sha_end2(hval, CTX_512(ctx), SHA512_DIGEST_SIZE); return;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
INT_RETURN sha2(unsigned char hval[], unsigned long size,
|
||||
const unsigned char data[], unsigned long len)
|
||||
{ sha2_ctx cx[1];
|
||||
|
||||
if(sha2_begin(size, cx) == EXIT_SUCCESS)
|
||||
{
|
||||
sha2_hash(data, len, cx); sha2_end(hval, cx); return EXIT_SUCCESS;
|
||||
}
|
||||
else
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
Reference in New Issue
Block a user