mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 07:28:10 +00:00
replace blowfish with rijndael
This commit is contained in:
parent
69a88a28a8
commit
9308fddb7f
3
Makefile
3
Makefile
@ -1,6 +1,7 @@
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -Os
|
||||
OBJS = bignum.o ecdsa.o secp256k1.o sha2.o rand.o hmac.o bip32.o ripemd160.o blowfish.o
|
||||
OBJS = bignum.o ecdsa.o secp256k1.o sha2.o rand.o hmac.o bip32.o ripemd160.o
|
||||
OBJS += aescrypt.o aeskey.o aestab.o
|
||||
|
||||
all: tests test-openssl
|
||||
|
||||
|
2
README
2
README
@ -4,9 +4,9 @@ trezor-crypto
|
||||
Heavily optimized cryptography algorithms for embedded devices.
|
||||
|
||||
These include:
|
||||
- AES/Rijndael encryption/decryption
|
||||
- Big Number (256 bit) Arithmetics
|
||||
- BIP32 Hierarchical Deterministic Wallets
|
||||
- Blowfish encryption/decryption (ECB)
|
||||
- ECDSA signing/verifying (only hardcoded secp256k1 curve,
|
||||
uses RFC6979 for deterministic signatures)
|
||||
- ECDSA public key derivation + Base58 address representation
|
||||
|
103
aes.h
Normal file
103
aes.h
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
-------------------------------------------------------------------------
|
||||
Copyright (c) 2001, 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.
|
||||
|
||||
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 fitness for purpose.
|
||||
-------------------------------------------------------------------------
|
||||
Issue Date: 29/07/2002
|
||||
|
||||
This file contains the definitions required to use AES (Rijndael) in C.
|
||||
*/
|
||||
|
||||
#ifndef _AES_H
|
||||
#define _AES_H
|
||||
|
||||
/* This include is used only to find 8 and 32 bit unsigned integer types */
|
||||
|
||||
#include "limits.h"
|
||||
|
||||
#if UCHAR_MAX == 0xff /* an unsigned 8 bit type for internal AES use */
|
||||
typedef unsigned char aes_08t;
|
||||
#else
|
||||
#error Please define an unsigned 8 bit type in aes.h
|
||||
#endif
|
||||
|
||||
#if UINT_MAX == 0xffffffff /* an unsigned 32 bit type for internal AES use */
|
||||
typedef unsigned int aes_32t;
|
||||
#elif ULONG_MAX == 0xffffffff
|
||||
typedef unsigned long aes_32t;
|
||||
#else
|
||||
#error Please define an unsigned 32 bit type in aes.h
|
||||
#endif
|
||||
|
||||
/* BLOCK_SIZE is in BYTES: 16, 24, 32 or undefined for aes.c and 16, 20,
|
||||
24, 28, 32 or undefined for aespp.c. When left undefined a slower
|
||||
version that provides variable block length is compiled.
|
||||
*/
|
||||
|
||||
// #define BLOCK_SIZE 16
|
||||
|
||||
/* key schedule length (in 32-bit words) */
|
||||
|
||||
#if !defined(BLOCK_SIZE)
|
||||
#define KS_LENGTH 128
|
||||
#else
|
||||
#define KS_LENGTH 4 * BLOCK_SIZE
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef unsigned int aes_fret; /* type for function return value */
|
||||
#define aes_bad 0 /* bad function return value */
|
||||
#define aes_good 1 /* good function return value */
|
||||
#ifndef AES_DLL /* implement normal or DLL functions */
|
||||
#define aes_rval aes_fret
|
||||
#else
|
||||
#define aes_rval aes_fret __declspec(dllexport) _stdcall
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct /* the AES context for encryption */
|
||||
{ aes_32t k_sch[KS_LENGTH]; /* the encryption key schedule */
|
||||
aes_32t n_rnd; /* the number of cipher rounds */
|
||||
aes_32t n_blk; /* the number of bytes in the state */
|
||||
} aes_ctx;
|
||||
|
||||
#if !defined(BLOCK_SIZE)
|
||||
aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]);
|
||||
aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
|
||||
|
||||
aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]);
|
||||
aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
421
aescrypt.c
Normal file
421
aescrypt.c
Normal file
@ -0,0 +1,421 @@
|
||||
/*
|
||||
-------------------------------------------------------------------------
|
||||
Copyright (c) 2001, 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.
|
||||
|
||||
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 fitness for purpose.
|
||||
-------------------------------------------------------------------------
|
||||
Issue Date: 29/07/2002
|
||||
|
||||
This file contains the code for implementing encryption and decryption
|
||||
for AES (Rijndael) for block and key sizes of 16, 24 and 32 bytes. It
|
||||
can optionally be replaced by code written in assembler using NASM.
|
||||
*/
|
||||
|
||||
#include "aesopt.h"
|
||||
|
||||
#if defined(BLOCK_SIZE) && (BLOCK_SIZE & 7)
|
||||
#error An illegal block size has been specified.
|
||||
#endif
|
||||
|
||||
#define unused 77 /* Sunset Strip */
|
||||
|
||||
#define si(y,x,k,c) s(y,c) = word_in(x + 4 * c) ^ k[c]
|
||||
#define so(y,x,c) word_out(y + 4 * c, s(x,c))
|
||||
|
||||
#if BLOCK_SIZE == 16
|
||||
|
||||
#if defined(ARRAYS)
|
||||
#define locals(y,x) x[4],y[4]
|
||||
#else
|
||||
#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
|
||||
/*
|
||||
the following defines prevent the compiler requiring the declaration
|
||||
of generated but unused variables in the fwd_var and inv_var macros
|
||||
*/
|
||||
#define b04 unused
|
||||
#define b05 unused
|
||||
#define b06 unused
|
||||
#define b07 unused
|
||||
#define b14 unused
|
||||
#define b15 unused
|
||||
#define b16 unused
|
||||
#define b17 unused
|
||||
#endif
|
||||
#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
|
||||
s(y,2) = s(x,2); s(y,3) = s(x,3);
|
||||
#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
|
||||
#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
|
||||
#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
|
||||
|
||||
#elif BLOCK_SIZE == 24
|
||||
|
||||
#if defined(ARRAYS)
|
||||
#define locals(y,x) x[6],y[6]
|
||||
#else
|
||||
#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \
|
||||
y##0,y##1,y##2,y##3,y##4,y##5
|
||||
#define b06 unused
|
||||
#define b07 unused
|
||||
#define b16 unused
|
||||
#define b17 unused
|
||||
#endif
|
||||
#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
|
||||
s(y,2) = s(x,2); s(y,3) = s(x,3); \
|
||||
s(y,4) = s(x,4); s(y,5) = s(x,5);
|
||||
#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
|
||||
si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
|
||||
#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
|
||||
so(y,x,3); so(y,x,4); so(y,x,5)
|
||||
#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
|
||||
rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
|
||||
#else
|
||||
|
||||
#if defined(ARRAYS)
|
||||
#define locals(y,x) x[8],y[8]
|
||||
#else
|
||||
#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
|
||||
y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
|
||||
#endif
|
||||
#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
|
||||
s(y,2) = s(x,2); s(y,3) = s(x,3); \
|
||||
s(y,4) = s(x,4); s(y,5) = s(x,5); \
|
||||
s(y,6) = s(x,6); s(y,7) = s(x,7);
|
||||
|
||||
#if BLOCK_SIZE == 32
|
||||
|
||||
#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \
|
||||
si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
|
||||
#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
|
||||
so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
|
||||
#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \
|
||||
rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
|
||||
#else
|
||||
|
||||
#define state_in(y,x,k) \
|
||||
switch(nc) \
|
||||
{ case 8: si(y,x,k,7); si(y,x,k,6); \
|
||||
case 6: si(y,x,k,5); si(y,x,k,4); \
|
||||
case 4: si(y,x,k,3); si(y,x,k,2); \
|
||||
si(y,x,k,1); si(y,x,k,0); \
|
||||
}
|
||||
|
||||
#define state_out(y,x) \
|
||||
switch(nc) \
|
||||
{ case 8: so(y,x,7); so(y,x,6); \
|
||||
case 6: so(y,x,5); so(y,x,4); \
|
||||
case 4: so(y,x,3); so(y,x,2); \
|
||||
so(y,x,1); so(y,x,0); \
|
||||
}
|
||||
|
||||
#if defined(FAST_VARIABLE)
|
||||
|
||||
#define round(rm,y,x,k) \
|
||||
switch(nc) \
|
||||
{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
|
||||
rm(y,x,k,5); rm(y,x,k,4); \
|
||||
rm(y,x,k,3); rm(y,x,k,2); \
|
||||
rm(y,x,k,1); rm(y,x,k,0); \
|
||||
break; \
|
||||
case 6: rm(y,x,k,5); rm(y,x,k,4); \
|
||||
rm(y,x,k,3); rm(y,x,k,2); \
|
||||
rm(y,x,k,1); rm(y,x,k,0); \
|
||||
break; \
|
||||
case 4: rm(y,x,k,3); rm(y,x,k,2); \
|
||||
rm(y,x,k,1); rm(y,x,k,0); \
|
||||
break; \
|
||||
}
|
||||
#else
|
||||
|
||||
#define round(rm,y,x,k) \
|
||||
switch(nc) \
|
||||
{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
|
||||
case 6: rm(y,x,k,5); rm(y,x,k,4); \
|
||||
case 4: rm(y,x,k,3); rm(y,x,k,2); \
|
||||
rm(y,x,k,1); rm(y,x,k,0); \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(ENCRYPTION)
|
||||
|
||||
/* I am grateful to Frank Yellin for the following construction
|
||||
(and that for decryption) which, given the column (c) of the
|
||||
output state variable, gives the input state variables which
|
||||
are needed in its computation for each row (r) of the state.
|
||||
|
||||
For the fixed block size options, compilers should be able to
|
||||
reduce this complex expression (and the equivalent one for
|
||||
decryption) to a static variable reference at compile time.
|
||||
But for variable block size code, there will be some limbs on
|
||||
which conditional clauses will be returned.
|
||||
*/
|
||||
|
||||
/* y = output word, x = input word, r = row, c = column for r = 0,
|
||||
1, 2 and 3 = column accessed for row r.
|
||||
*/
|
||||
|
||||
#define fwd_var(x,r,c)\
|
||||
( r == 0 ? \
|
||||
( c == 0 ? s(x,0) \
|
||||
: c == 1 ? s(x,1) \
|
||||
: c == 2 ? s(x,2) \
|
||||
: c == 3 ? s(x,3) \
|
||||
: c == 4 ? s(x,4) \
|
||||
: c == 5 ? s(x,5) \
|
||||
: c == 6 ? s(x,6) \
|
||||
: s(x,7))\
|
||||
: r == 1 ? \
|
||||
( c == 0 ? s(x,1) \
|
||||
: c == 1 ? s(x,2) \
|
||||
: c == 2 ? s(x,3) \
|
||||
: c == 3 ? nc == 4 ? s(x,0) : s(x,4) \
|
||||
: c == 4 ? s(x,5) \
|
||||
: c == 5 ? nc == 8 ? s(x,6) : s(x,0) \
|
||||
: c == 6 ? s(x,7) \
|
||||
: s(x,0))\
|
||||
: r == 2 ? \
|
||||
( c == 0 ? nc == 8 ? s(x,3) : s(x,2) \
|
||||
: c == 1 ? nc == 8 ? s(x,4) : s(x,3) \
|
||||
: c == 2 ? nc == 4 ? s(x,0) : nc == 8 ? s(x,5) : s(x,4) \
|
||||
: c == 3 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,6) : s(x,5) \
|
||||
: c == 4 ? nc == 8 ? s(x,7) : s(x,0) \
|
||||
: c == 5 ? nc == 8 ? s(x,0) : s(x,1) \
|
||||
: c == 6 ? s(x,1) \
|
||||
: s(x,2))\
|
||||
: \
|
||||
( c == 0 ? nc == 8 ? s(x,4) : s(x,3) \
|
||||
: c == 1 ? nc == 4 ? s(x,0) : nc == 8 ? s(x,5) : s(x,4) \
|
||||
: c == 2 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,6) : s(x,5) \
|
||||
: c == 3 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,7) : s(x,0) \
|
||||
: c == 4 ? nc == 8 ? s(x,0) : s(x,1) \
|
||||
: c == 5 ? nc == 8 ? s(x,1) : s(x,2) \
|
||||
: c == 6 ? s(x,2) \
|
||||
: s(x,3)))
|
||||
|
||||
#if defined(FT4_SET)
|
||||
#undef dec_fmvars
|
||||
#define dec_fmvars
|
||||
#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
|
||||
#elif defined(FT1_SET)
|
||||
#undef dec_fmvars
|
||||
#define dec_fmvars
|
||||
#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
|
||||
#else
|
||||
#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
|
||||
#endif
|
||||
|
||||
#if defined(FL4_SET)
|
||||
#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
|
||||
#elif defined(FL1_SET)
|
||||
#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
|
||||
#else
|
||||
#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
|
||||
#endif
|
||||
|
||||
aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])
|
||||
{ aes_32t locals(b0, b1);
|
||||
const aes_32t *kp = cx->k_sch;
|
||||
dec_fmvars /* declare variables for fwd_mcol() if needed */
|
||||
|
||||
if(!(cx->n_blk & 1)) return aes_bad;
|
||||
|
||||
state_in(b0, in_blk, kp);
|
||||
|
||||
#if (ENC_UNROLL == FULL)
|
||||
|
||||
kp += (cx->n_rnd - 9) * nc;
|
||||
|
||||
switch(cx->n_rnd)
|
||||
{
|
||||
case 14: round(fwd_rnd, b1, b0, kp - 4 * nc);
|
||||
round(fwd_rnd, b0, b1, kp - 3 * nc);
|
||||
case 12: round(fwd_rnd, b1, b0, kp - 2 * nc);
|
||||
round(fwd_rnd, b0, b1, kp - nc);
|
||||
case 10: round(fwd_rnd, b1, b0, kp );
|
||||
round(fwd_rnd, b0, b1, kp + nc);
|
||||
round(fwd_rnd, b1, b0, kp + 2 * nc);
|
||||
round(fwd_rnd, b0, b1, kp + 3 * nc);
|
||||
round(fwd_rnd, b1, b0, kp + 4 * nc);
|
||||
round(fwd_rnd, b0, b1, kp + 5 * nc);
|
||||
round(fwd_rnd, b1, b0, kp + 6 * nc);
|
||||
round(fwd_rnd, b0, b1, kp + 7 * nc);
|
||||
round(fwd_rnd, b1, b0, kp + 8 * nc);
|
||||
round(fwd_lrnd, b0, b1, kp + 9 * nc);
|
||||
}
|
||||
#else
|
||||
|
||||
#if (ENC_UNROLL == PARTIAL)
|
||||
{ aes_32t rnd;
|
||||
for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd)
|
||||
{
|
||||
kp += nc;
|
||||
round(fwd_rnd, b1, b0, kp);
|
||||
kp += nc;
|
||||
round(fwd_rnd, b0, b1, kp);
|
||||
}
|
||||
kp += nc;
|
||||
round(fwd_rnd, b1, b0, kp);
|
||||
#else
|
||||
{ aes_32t rnd, *p0 = b0, *p1 = b1, *pt;
|
||||
for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
|
||||
{
|
||||
kp += nc;
|
||||
round(fwd_rnd, p1, p0, kp);
|
||||
pt = p0, p0 = p1, p1 = pt;
|
||||
}
|
||||
#endif
|
||||
kp += nc;
|
||||
round(fwd_lrnd, b0, b1, kp);
|
||||
}
|
||||
#endif
|
||||
|
||||
state_out(out_blk, b0);
|
||||
return aes_good;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(DECRYPTION)
|
||||
|
||||
#define inv_var(x,r,c) \
|
||||
( r == 0 ? \
|
||||
( c == 0 ? s(x,0) \
|
||||
: c == 1 ? s(x,1) \
|
||||
: c == 2 ? s(x,2) \
|
||||
: c == 3 ? s(x,3) \
|
||||
: c == 4 ? s(x,4) \
|
||||
: c == 5 ? s(x,5) \
|
||||
: c == 6 ? s(x,6) \
|
||||
: s(x,7))\
|
||||
: r == 1 ? \
|
||||
( c == 0 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,7) : s(x,5) \
|
||||
: c == 1 ? s(x,0) \
|
||||
: c == 2 ? s(x,1) \
|
||||
: c == 3 ? s(x,2) \
|
||||
: c == 4 ? s(x,3) \
|
||||
: c == 5 ? s(x,4) \
|
||||
: c == 6 ? s(x,5) \
|
||||
: s(x,6))\
|
||||
: r == 2 ? \
|
||||
( c == 0 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,5) : s(x,4) \
|
||||
: c == 1 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,6) : s(x,5) \
|
||||
: c == 2 ? nc == 8 ? s(x,7) : s(x,0) \
|
||||
: c == 3 ? nc == 8 ? s(x,0) : s(x,1) \
|
||||
: c == 4 ? nc == 8 ? s(x,1) : s(x,2) \
|
||||
: c == 5 ? nc == 8 ? s(x,2) : s(x,3) \
|
||||
: c == 6 ? s(x,3) \
|
||||
: s(x,4))\
|
||||
: \
|
||||
( c == 0 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,4) : s(x,3) \
|
||||
: c == 1 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,5) : s(x,4) \
|
||||
: c == 2 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,6) : s(x,5) \
|
||||
: c == 3 ? nc == 8 ? s(x,7) : s(x,0) \
|
||||
: c == 4 ? nc == 8 ? s(x,0) : s(x,1) \
|
||||
: c == 5 ? nc == 8 ? s(x,1) : s(x,2) \
|
||||
: c == 6 ? s(x,2) \
|
||||
: s(x,3)))
|
||||
|
||||
#if defined(IT4_SET)
|
||||
#undef dec_imvars
|
||||
#define dec_imvars
|
||||
#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
|
||||
#elif defined(IT1_SET)
|
||||
#undef dec_imvars
|
||||
#define dec_imvars
|
||||
#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
|
||||
#else
|
||||
#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
|
||||
#endif
|
||||
|
||||
#if defined(IL4_SET)
|
||||
#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
|
||||
#elif defined(IL1_SET)
|
||||
#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
|
||||
#else
|
||||
#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
|
||||
#endif
|
||||
|
||||
aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])
|
||||
{ aes_32t locals(b0, b1);
|
||||
const aes_32t *kp = cx->k_sch + nc * cx->n_rnd;
|
||||
dec_imvars /* declare variables for inv_mcol() if needed */
|
||||
|
||||
if(!(cx->n_blk & 2)) return aes_bad;
|
||||
|
||||
state_in(b0, in_blk, kp);
|
||||
|
||||
#if (DEC_UNROLL == FULL)
|
||||
|
||||
kp = cx->k_sch + 9 * nc;
|
||||
switch(cx->n_rnd)
|
||||
{
|
||||
case 14: round(inv_rnd, b1, b0, kp + 4 * nc);
|
||||
round(inv_rnd, b0, b1, kp + 3 * nc);
|
||||
case 12: round(inv_rnd, b1, b0, kp + 2 * nc);
|
||||
round(inv_rnd, b0, b1, kp + nc );
|
||||
case 10: round(inv_rnd, b1, b0, kp );
|
||||
round(inv_rnd, b0, b1, kp - nc);
|
||||
round(inv_rnd, b1, b0, kp - 2 * nc);
|
||||
round(inv_rnd, b0, b1, kp - 3 * nc);
|
||||
round(inv_rnd, b1, b0, kp - 4 * nc);
|
||||
round(inv_rnd, b0, b1, kp - 5 * nc);
|
||||
round(inv_rnd, b1, b0, kp - 6 * nc);
|
||||
round(inv_rnd, b0, b1, kp - 7 * nc);
|
||||
round(inv_rnd, b1, b0, kp - 8 * nc);
|
||||
round(inv_lrnd, b0, b1, kp - 9 * nc);
|
||||
}
|
||||
#else
|
||||
|
||||
#if (DEC_UNROLL == PARTIAL)
|
||||
{ aes_32t rnd;
|
||||
for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd)
|
||||
{
|
||||
kp -= nc;
|
||||
round(inv_rnd, b1, b0, kp);
|
||||
kp -= nc;
|
||||
round(inv_rnd, b0, b1, kp);
|
||||
}
|
||||
kp -= nc;
|
||||
round(inv_rnd, b1, b0, kp);
|
||||
#else
|
||||
{ aes_32t rnd, *p0 = b0, *p1 = b1, *pt;
|
||||
for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
|
||||
{
|
||||
kp -= nc;
|
||||
round(inv_rnd, p1, p0, kp);
|
||||
pt = p0, p0 = p1, p1 = pt;
|
||||
}
|
||||
#endif
|
||||
kp -= nc;
|
||||
round(inv_lrnd, b0, b1, kp);
|
||||
}
|
||||
#endif
|
||||
|
||||
state_out(out_blk, b0);
|
||||
return aes_good;
|
||||
}
|
||||
|
||||
#endif
|
369
aeskey.c
Normal file
369
aeskey.c
Normal file
@ -0,0 +1,369 @@
|
||||
/*
|
||||
-------------------------------------------------------------------------
|
||||
Copyright (c) 2001, 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.
|
||||
|
||||
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 fitness for purpose.
|
||||
-------------------------------------------------------------------------
|
||||
Issue Date: 29/07/2002
|
||||
|
||||
This file contains the code for implementing the key schedule for AES
|
||||
(Rijndael) for block and key sizes of 16, 24, and 32 bytes.
|
||||
*/
|
||||
|
||||
#include "aesopt.h"
|
||||
|
||||
#if defined(BLOCK_SIZE) && (BLOCK_SIZE & 7)
|
||||
#error An illegal block size has been specified.
|
||||
#endif
|
||||
|
||||
/* Subroutine to set the block size (if variable) in bytes, legal
|
||||
values being 16, 24 and 32.
|
||||
*/
|
||||
|
||||
#if !defined(BLOCK_SIZE)
|
||||
|
||||
aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1])
|
||||
{
|
||||
#if !defined(FIXED_TABLES)
|
||||
if(!tab_init) gen_tabs();
|
||||
#endif
|
||||
|
||||
if((blen & 7) || blen < 16 || blen > 32)
|
||||
{
|
||||
cx->n_blk = 0; return aes_bad;
|
||||
}
|
||||
|
||||
cx->n_blk = blen;
|
||||
return aes_good;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Initialise the key schedule from the user supplied key. The key
|
||||
length is now specified in bytes - 16, 24 or 32 as appropriate.
|
||||
This corresponds to bit lengths of 128, 192 and 256 bits, and
|
||||
to Nk values of 4, 6 and 8 respectively.
|
||||
|
||||
The following macros implement a single cycle in the key
|
||||
schedule generation process. The number of cycles needed
|
||||
for each cx->n_col and nk value is:
|
||||
|
||||
nk = 4 5 6 7 8
|
||||
------------------------------
|
||||
cx->n_col = 4 10 9 8 7 7
|
||||
cx->n_col = 5 14 11 10 9 9
|
||||
cx->n_col = 6 19 15 12 11 11
|
||||
cx->n_col = 7 21 19 16 13 14
|
||||
cx->n_col = 8 29 23 19 17 14
|
||||
*/
|
||||
|
||||
#define ke4(k,i) \
|
||||
{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
|
||||
k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
#define kel4(k,i) \
|
||||
{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
|
||||
k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
|
||||
#define ke6(k,i) \
|
||||
{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
|
||||
k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
|
||||
k[6*(i)+10] = ss[4] ^= ss[3]; k[6*(i)+11] = ss[5] ^= ss[4]; \
|
||||
}
|
||||
#define kel6(k,i) \
|
||||
{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
|
||||
k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
|
||||
#define ke8(k,i) \
|
||||
{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
|
||||
k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
|
||||
k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); k[8*(i)+13] = ss[5] ^= ss[4]; \
|
||||
k[8*(i)+14] = ss[6] ^= ss[5]; k[8*(i)+15] = ss[7] ^= ss[6]; \
|
||||
}
|
||||
#define kel8(k,i) \
|
||||
{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
|
||||
k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
|
||||
#if defined(ENCRYPTION_KEY_SCHEDULE)
|
||||
|
||||
aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1])
|
||||
{ aes_32t ss[8];
|
||||
|
||||
#if !defined(FIXED_TABLES)
|
||||
if(!tab_init) gen_tabs();
|
||||
#endif
|
||||
|
||||
#if !defined(BLOCK_SIZE)
|
||||
if(!cx->n_blk) cx->n_blk = 16;
|
||||
#else
|
||||
cx->n_blk = BLOCK_SIZE;
|
||||
#endif
|
||||
|
||||
cx->n_blk = (cx->n_blk & ~3) | 1;
|
||||
|
||||
cx->k_sch[0] = ss[0] = word_in(in_key );
|
||||
cx->k_sch[1] = ss[1] = word_in(in_key + 4);
|
||||
cx->k_sch[2] = ss[2] = word_in(in_key + 8);
|
||||
cx->k_sch[3] = ss[3] = word_in(in_key + 12);
|
||||
|
||||
#if (BLOCK_SIZE == 16) && (ENC_UNROLL != NONE)
|
||||
|
||||
switch(klen)
|
||||
{
|
||||
case 16: ke4(cx->k_sch, 0); ke4(cx->k_sch, 1);
|
||||
ke4(cx->k_sch, 2); ke4(cx->k_sch, 3);
|
||||
ke4(cx->k_sch, 4); ke4(cx->k_sch, 5);
|
||||
ke4(cx->k_sch, 6); ke4(cx->k_sch, 7);
|
||||
ke4(cx->k_sch, 8); kel4(cx->k_sch, 9);
|
||||
cx->n_rnd = 10; break;
|
||||
case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
|
||||
cx->k_sch[5] = ss[5] = word_in(in_key + 20);
|
||||
ke6(cx->k_sch, 0); ke6(cx->k_sch, 1);
|
||||
ke6(cx->k_sch, 2); ke6(cx->k_sch, 3);
|
||||
ke6(cx->k_sch, 4); ke6(cx->k_sch, 5);
|
||||
ke6(cx->k_sch, 6); kel6(cx->k_sch, 7);
|
||||
cx->n_rnd = 12; break;
|
||||
case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
|
||||
cx->k_sch[5] = ss[5] = word_in(in_key + 20);
|
||||
cx->k_sch[6] = ss[6] = word_in(in_key + 24);
|
||||
cx->k_sch[7] = ss[7] = word_in(in_key + 28);
|
||||
ke8(cx->k_sch, 0); ke8(cx->k_sch, 1);
|
||||
ke8(cx->k_sch, 2); ke8(cx->k_sch, 3);
|
||||
ke8(cx->k_sch, 4); ke8(cx->k_sch, 5);
|
||||
kel8(cx->k_sch, 6);
|
||||
cx->n_rnd = 14; break;
|
||||
default: cx->n_rnd = 0; return aes_bad;
|
||||
}
|
||||
#else
|
||||
{ aes_32t i, l;
|
||||
cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
|
||||
l = (nc * cx->n_rnd + nc - 1) / (klen >> 2);
|
||||
|
||||
switch(klen)
|
||||
{
|
||||
case 16: for(i = 0; i < l; ++i)
|
||||
ke4(cx->k_sch, i);
|
||||
break;
|
||||
case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
|
||||
cx->k_sch[5] = ss[5] = word_in(in_key + 20);
|
||||
for(i = 0; i < l; ++i)
|
||||
ke6(cx->k_sch, i);
|
||||
break;
|
||||
case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
|
||||
cx->k_sch[5] = ss[5] = word_in(in_key + 20);
|
||||
cx->k_sch[6] = ss[6] = word_in(in_key + 24);
|
||||
cx->k_sch[7] = ss[7] = word_in(in_key + 28);
|
||||
for(i = 0; i < l; ++i)
|
||||
ke8(cx->k_sch, i);
|
||||
break;
|
||||
default: cx->n_rnd = 0; return aes_bad;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return aes_good;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(DECRYPTION_KEY_SCHEDULE)
|
||||
|
||||
#if (DEC_ROUND != NO_TABLES)
|
||||
#define d_vars dec_imvars
|
||||
#define ff(x) inv_mcol(x)
|
||||
#else
|
||||
#define ff(x) (x)
|
||||
#define d_vars
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#define kdf4(k,i) \
|
||||
{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; ss[1] = ss[1] ^ ss[3]; ss[2] = ss[2] ^ ss[3]; ss[3] = ss[3]; \
|
||||
ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \
|
||||
ss[4] ^= k[4*(i)]; k[4*(i)+4] = ff(ss[4]); ss[4] ^= k[4*(i)+1]; k[4*(i)+5] = ff(ss[4]); \
|
||||
ss[4] ^= k[4*(i)+2]; k[4*(i)+6] = ff(ss[4]); ss[4] ^= k[4*(i)+3]; k[4*(i)+7] = ff(ss[4]); \
|
||||
}
|
||||
#define kd4(k,i) \
|
||||
{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
|
||||
k[4*(i)+4] = ss[4] ^= k[4*(i)]; k[4*(i)+5] = ss[4] ^= k[4*(i)+1]; \
|
||||
k[4*(i)+6] = ss[4] ^= k[4*(i)+2]; k[4*(i)+7] = ss[4] ^= k[4*(i)+3]; \
|
||||
}
|
||||
#define kdl4(k,i) \
|
||||
{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \
|
||||
k[4*(i)+4] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; k[4*(i)+5] = ss[1] ^ ss[3]; \
|
||||
k[4*(i)+6] = ss[0]; k[4*(i)+7] = ss[1]; \
|
||||
}
|
||||
#else
|
||||
#define kdf4(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+ 4] = ff(ss[0]); ss[1] ^= ss[0]; k[4*(i)+ 5] = ff(ss[1]); \
|
||||
ss[2] ^= ss[1]; k[4*(i)+ 6] = ff(ss[2]); ss[3] ^= ss[2]; k[4*(i)+ 7] = ff(ss[3]); \
|
||||
}
|
||||
#define kd4(k,i) \
|
||||
{ ss[4] = ls_box(ss[3],3) ^ rcon_tab[i]; \
|
||||
ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[4*(i)+ 4] = ss[4] ^= k[4*(i)]; \
|
||||
ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[4] ^= k[4*(i)+ 1]; \
|
||||
ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[4] ^= k[4*(i)+ 2]; \
|
||||
ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[4] ^= k[4*(i)+ 3]; \
|
||||
}
|
||||
#define kdl4(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+ 4] = ss[0]; ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[1]; \
|
||||
ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[2]; ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[3]; \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define kdf6(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 6] = ff(ss[0]); ss[1] ^= ss[0]; k[6*(i)+ 7] = ff(ss[1]); \
|
||||
ss[2] ^= ss[1]; k[6*(i)+ 8] = ff(ss[2]); ss[3] ^= ss[2]; k[6*(i)+ 9] = ff(ss[3]); \
|
||||
ss[4] ^= ss[3]; k[6*(i)+10] = ff(ss[4]); ss[5] ^= ss[4]; k[6*(i)+11] = ff(ss[5]); \
|
||||
}
|
||||
#define kd6(k,i) \
|
||||
{ ss[6] = ls_box(ss[5],3) ^ rcon_tab[i]; \
|
||||
ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[6*(i)+ 6] = ss[6] ^= k[6*(i)]; \
|
||||
ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[6] ^= k[6*(i)+ 1]; \
|
||||
ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[6] ^= k[6*(i)+ 2]; \
|
||||
ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[6] ^= k[6*(i)+ 3]; \
|
||||
ss[4] ^= ss[3]; k[6*(i)+10] = ss[6] ^= k[6*(i)+ 4]; \
|
||||
ss[5] ^= ss[4]; k[6*(i)+11] = ss[6] ^= k[6*(i)+ 5]; \
|
||||
}
|
||||
#define kdl6(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 6] = ss[0]; ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[1]; \
|
||||
ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[2]; ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[3]; \
|
||||
}
|
||||
|
||||
#define kdf8(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 8] = ff(ss[0]); ss[1] ^= ss[0]; k[8*(i)+ 9] = ff(ss[1]); \
|
||||
ss[2] ^= ss[1]; k[8*(i)+10] = ff(ss[2]); ss[3] ^= ss[2]; k[8*(i)+11] = ff(ss[3]); \
|
||||
ss[4] ^= ls_box(ss[3],0); k[8*(i)+12] = ff(ss[4]); ss[5] ^= ss[4]; k[8*(i)+13] = ff(ss[5]); \
|
||||
ss[6] ^= ss[5]; k[8*(i)+14] = ff(ss[6]); ss[7] ^= ss[6]; k[8*(i)+15] = ff(ss[7]); \
|
||||
}
|
||||
#define kd8(k,i) \
|
||||
{ aes_32t g = ls_box(ss[7],3) ^ rcon_tab[i]; \
|
||||
ss[0] ^= g; g = ff(g); k[8*(i)+ 8] = g ^= k[8*(i)]; \
|
||||
ss[1] ^= ss[0]; k[8*(i)+ 9] = g ^= k[8*(i)+ 1]; \
|
||||
ss[2] ^= ss[1]; k[8*(i)+10] = g ^= k[8*(i)+ 2]; \
|
||||
ss[3] ^= ss[2]; k[8*(i)+11] = g ^= k[8*(i)+ 3]; \
|
||||
g = ls_box(ss[3],0); \
|
||||
ss[4] ^= g; g = ff(g); k[8*(i)+12] = g ^= k[8*(i)+ 4]; \
|
||||
ss[5] ^= ss[4]; k[8*(i)+13] = g ^= k[8*(i)+ 5]; \
|
||||
ss[6] ^= ss[5]; k[8*(i)+14] = g ^= k[8*(i)+ 6]; \
|
||||
ss[7] ^= ss[6]; k[8*(i)+15] = g ^= k[8*(i)+ 7]; \
|
||||
}
|
||||
#define kdl8(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 8] = ss[0]; ss[1] ^= ss[0]; k[8*(i)+ 9] = ss[1]; \
|
||||
ss[2] ^= ss[1]; k[8*(i)+10] = ss[2]; ss[3] ^= ss[2]; k[8*(i)+11] = ss[3]; \
|
||||
}
|
||||
|
||||
aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1])
|
||||
{ aes_32t ss[8];
|
||||
d_vars
|
||||
|
||||
#if !defined(FIXED_TABLES)
|
||||
if(!tab_init) gen_tabs();
|
||||
#endif
|
||||
|
||||
#if !defined(BLOCK_SIZE)
|
||||
if(!cx->n_blk) cx->n_blk = 16;
|
||||
#else
|
||||
cx->n_blk = BLOCK_SIZE;
|
||||
#endif
|
||||
|
||||
cx->n_blk = (cx->n_blk & ~3) | 2;
|
||||
|
||||
cx->k_sch[0] = ss[0] = word_in(in_key );
|
||||
cx->k_sch[1] = ss[1] = word_in(in_key + 4);
|
||||
cx->k_sch[2] = ss[2] = word_in(in_key + 8);
|
||||
cx->k_sch[3] = ss[3] = word_in(in_key + 12);
|
||||
|
||||
#if (BLOCK_SIZE == 16) && (DEC_UNROLL != NONE)
|
||||
|
||||
switch(klen)
|
||||
{
|
||||
case 16: kdf4(cx->k_sch, 0); kd4(cx->k_sch, 1);
|
||||
kd4(cx->k_sch, 2); kd4(cx->k_sch, 3);
|
||||
kd4(cx->k_sch, 4); kd4(cx->k_sch, 5);
|
||||
kd4(cx->k_sch, 6); kd4(cx->k_sch, 7);
|
||||
kd4(cx->k_sch, 8); kdl4(cx->k_sch, 9);
|
||||
cx->n_rnd = 10; break;
|
||||
case 24: ss[4] = word_in(in_key + 16);
|
||||
cx->k_sch[4] = ff(ss[4]);
|
||||
ss[5] = word_in(in_key + 20);
|
||||
cx->k_sch[5] = ff(ss[5]);
|
||||
kdf6(cx->k_sch, 0); kd6(cx->k_sch, 1);
|
||||
kd6(cx->k_sch, 2); kd6(cx->k_sch, 3);
|
||||
kd6(cx->k_sch, 4); kd6(cx->k_sch, 5);
|
||||
kd6(cx->k_sch, 6); kdl6(cx->k_sch, 7);
|
||||
cx->n_rnd = 12; break;
|
||||
case 32: ss[4] = word_in(in_key + 16);
|
||||
cx->k_sch[4] = ff(ss[4]);
|
||||
ss[5] = word_in(in_key + 20);
|
||||
cx->k_sch[5] = ff(ss[5]);
|
||||
ss[6] = word_in(in_key + 24);
|
||||
cx->k_sch[6] = ff(ss[6]);
|
||||
ss[7] = word_in(in_key + 28);
|
||||
cx->k_sch[7] = ff(ss[7]);
|
||||
kdf8(cx->k_sch, 0); kd8(cx->k_sch, 1);
|
||||
kd8(cx->k_sch, 2); kd8(cx->k_sch, 3);
|
||||
kd8(cx->k_sch, 4); kd8(cx->k_sch, 5);
|
||||
kdl8(cx->k_sch, 6);
|
||||
cx->n_rnd = 14; break;
|
||||
default: cx->n_rnd = 0; return aes_bad;
|
||||
}
|
||||
#else
|
||||
{ aes_32t i, l;
|
||||
cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
|
||||
l = (nc * cx->n_rnd + nc - 1) / (klen >> 2);
|
||||
|
||||
switch(klen)
|
||||
{
|
||||
case 16:
|
||||
for(i = 0; i < l; ++i)
|
||||
ke4(cx->k_sch, i);
|
||||
break;
|
||||
case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
|
||||
cx->k_sch[5] = ss[5] = word_in(in_key + 20);
|
||||
for(i = 0; i < l; ++i)
|
||||
ke6(cx->k_sch, i);
|
||||
break;
|
||||
case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
|
||||
cx->k_sch[5] = ss[5] = word_in(in_key + 20);
|
||||
cx->k_sch[6] = ss[6] = word_in(in_key + 24);
|
||||
cx->k_sch[7] = ss[7] = word_in(in_key + 28);
|
||||
for(i = 0; i < l; ++i)
|
||||
ke8(cx->k_sch, i);
|
||||
break;
|
||||
default: cx->n_rnd = 0; return aes_bad;
|
||||
}
|
||||
#if (DEC_ROUND != NO_TABLES)
|
||||
for(i = nc; i < nc * cx->n_rnd; ++i)
|
||||
cx->k_sch[i] = inv_mcol(cx->k_sch[i]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
return aes_good;
|
||||
}
|
||||
|
||||
#endif
|
836
aesopt.h
Normal file
836
aesopt.h
Normal file
@ -0,0 +1,836 @@
|
||||
/*
|
||||
-------------------------------------------------------------------------
|
||||
Copyright (c) 2001, 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.
|
||||
|
||||
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 fitness for purpose.
|
||||
-------------------------------------------------------------------------
|
||||
Issue Date: 29/07/2002
|
||||
|
||||
This file contains the compilation options for AES (Rijndael) and code
|
||||
that is common across encryption, key scheduling and table generation.
|
||||
|
||||
OPERATION
|
||||
|
||||
These source code files implement the AES algorithm Rijndael designed by
|
||||
Joan Daemen and Vincent Rijmen. The version in aes.c is designed for
|
||||
block and key sizes of 128, 192 and 256 bits (16, 24 and 32 bytes) while
|
||||
that in aespp.c provides for block and keys sizes of 128, 160, 192, 224
|
||||
and 256 bits (16, 20, 24, 28 and 32 bytes). This file is a common header
|
||||
file for these two implementations and for aesref.c, which is a reference
|
||||
implementation.
|
||||
|
||||
This version is designed for flexibility and speed using operations on
|
||||
32-bit words rather than operations on bytes. It provides aes_both fixed
|
||||
and dynamic block and key lengths and can also run with either big or
|
||||
little endian internal byte order (see aes.h). It inputs block and key
|
||||
lengths in bytes with the legal values being 16, 24 and 32 for aes.c and
|
||||
16, 20, 24, 28 and 32 for aespp.c
|
||||
|
||||
THE CIPHER INTERFACE
|
||||
|
||||
aes_08t (an unsigned 8-bit type)
|
||||
aes_32t (an unsigned 32-bit type)
|
||||
aes_fret (a signed 16 bit type for function return values)
|
||||
aes_good (value != 0, a good return)
|
||||
aes_bad (value == 0, an error return)
|
||||
struct aes_ctx (structure for the cipher encryption context)
|
||||
struct aes_ctx (structure for the cipher decryption context)
|
||||
aes_rval the function return type (aes_fret if not DLL)
|
||||
|
||||
C subroutine calls:
|
||||
|
||||
aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1]);
|
||||
aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]);
|
||||
aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
|
||||
|
||||
aes_rval aes_dec_len(unsigned int blen, aes_ctx cx[1]);
|
||||
aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]);
|
||||
aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
|
||||
|
||||
IMPORTANT NOTE: If you are using this C interface and your compiler does
|
||||
not set the memory used for objects to zero before use, you will need to
|
||||
ensure that cx.s_flg is set to zero before using these subroutine calls.
|
||||
|
||||
C++ aes class subroutines:
|
||||
|
||||
class AESclass for encryption
|
||||
class AESclass for decryption
|
||||
|
||||
aes_rval len(unsigned int blen = 16);
|
||||
aes_rval key(const unsigned char in_key[], unsigned int klen);
|
||||
aes_rval blk(const unsigned char in_blk[], unsigned char out_blk[]);
|
||||
|
||||
aes_rval len(unsigned int blen = 16);
|
||||
aes_rval key(const unsigned char in_key[], unsigned int klen);
|
||||
aes_rval blk(const unsigned char in_blk[], unsigned char out_blk[]);
|
||||
|
||||
The block length inputs to set_block and set_key are in numbers of
|
||||
BYTES, not bits. The calls to subroutines must be made in the above
|
||||
order but multiple calls can be made without repeating earlier calls
|
||||
if their parameters have not changed. If the cipher block length is
|
||||
variable but set_blk has not been called before cipher operations a
|
||||
value of 16 is assumed (that is, the AES block size). In contrast to
|
||||
earlier versions the block and key length parameters are now checked
|
||||
for correctness and the encryption and decryption routines check to
|
||||
ensure that an appropriate key has been set before they are called.
|
||||
|
||||
COMPILATION
|
||||
|
||||
The files used to provide AES (Rijndael) are
|
||||
|
||||
a. aes.h for the definitions needed for use in C.
|
||||
b. aescpp.h for the definitions needed for use in C++.
|
||||
c. aesopt.h for setting compilation options (also includes common
|
||||
code).
|
||||
d. aescrypt.c for encryption and decrytpion, or
|
||||
e. aescrypt.asm for encryption and decryption using assembler code.
|
||||
f. aeskey.c for key scheduling.
|
||||
g. aestab.c for table loading or generation.
|
||||
|
||||
The assembler code uses the NASM assembler. The above files provice
|
||||
block and key lengths of 16, 24 and 32 bytes (128, 192 and 256 bits).
|
||||
If aescrypp.c and aeskeypp.c are used instead of aescrypt.c and
|
||||
aeskey.c respectively, the block and key lengths can then be 16, 20,
|
||||
24, 28 or 32 bytes. However this code has not been optimised to the
|
||||
same extent and is hence slower (esepcially for the AES block size
|
||||
of 16 bytes).
|
||||
|
||||
To compile AES (Rijndael) for use in C code use aes.h and exclude
|
||||
the AES_DLL define in aes.h
|
||||
|
||||
To compile AES (Rijndael) for use in in C++ code use aescpp.h and
|
||||
exclude the AES_DLL define in aes.h
|
||||
|
||||
To compile AES (Rijndael) in C as a Dynamic Link Library DLL) use
|
||||
aes.h, include the AES_DLL define and compile the DLL. If using
|
||||
the test files to test the DLL, exclude aes.c from the test build
|
||||
project and compile it with the same defines as used for the DLL
|
||||
(ensure that the DLL path is correct)
|
||||
|
||||
CONFIGURATION OPTIONS (here and in aes.h)
|
||||
|
||||
a. define BLOCK_SIZE in aes.h to set the cipher block size (16, 24
|
||||
or 32 for the standard code, or 16, 20, 24, 28 or 32 for the
|
||||
extended code) or leave this undefined for dynamically variable
|
||||
block size (this will result in much slower code).
|
||||
b. set AES_DLL in aes.h if AES (Rijndael) is to be compiled as a DLL
|
||||
c. You may need to set PLATFORM_BYTE_ORDER to define the byte order.
|
||||
d. If you want the code to run in a specific internal byte order, then
|
||||
INTERNAL_BYTE_ORDER must be set accordingly.
|
||||
e. set other configuration options decribed below.
|
||||
*/
|
||||
|
||||
#ifndef _AESOPT_H
|
||||
#define _AESOPT_H
|
||||
|
||||
/* START OF CONFIGURATION OPTIONS
|
||||
|
||||
USE OF DEFINES
|
||||
|
||||
Later in this section there are a number of defines that control the
|
||||
operation of the code. In each section, the purpose of each define is
|
||||
explained so that the relevant form can be included or excluded by
|
||||
setting either 1's or 0's respectively on the branches of the related
|
||||
#if clauses.
|
||||
*/
|
||||
|
||||
/* 1. PLATFORM SPECIFIC INCLUDES */
|
||||
|
||||
#include "aes.h"
|
||||
#define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
|
||||
|
||||
/*
|
||||
#if defined( __CRYPTLIB__ ) && !defined( INC_ALL ) && !defined( INC_CHILD )
|
||||
#include "crypt/aes.h"
|
||||
#else
|
||||
#include "aes.h"
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) || defined(__GNU_LIBRARY__)
|
||||
//# include <endian.h>
|
||||
//# include <byteswap.h>
|
||||
#elif defined(__CRYPTLIB__)
|
||||
# if defined( INC_ALL )
|
||||
# include "crypt.h"
|
||||
# elif defined( INC_CHILD )
|
||||
# include "../crypt.h"
|
||||
# else
|
||||
# include "crypt.h"
|
||||
# endif
|
||||
# if defined(DATA_LITTLEENDIAN)
|
||||
# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
|
||||
# else
|
||||
# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
|
||||
# endif
|
||||
#elif defined(_MSC_VER)
|
||||
# include <stdlib.h>
|
||||
#elif !defined(WIN32)
|
||||
# include <stdlib.h>
|
||||
# if !defined (_ENDIAN_H)
|
||||
# include <sys/param.h>
|
||||
# else
|
||||
# include _ENDIAN_H
|
||||
# endif
|
||||
#endif
|
||||
*/
|
||||
|
||||
/* 2. BYTE ORDER IN 32-BIT WORDS
|
||||
|
||||
To obtain the highest speed on processors with 32-bit words, this code
|
||||
needs to determine the order in which bytes are packed into such words.
|
||||
The following block of code is an attempt to capture the most obvious
|
||||
ways in which various environemnts define byte order. It may well fail,
|
||||
in which case the definitions will need to be set by editing at the
|
||||
points marked **** EDIT HERE IF NECESSARY **** below.
|
||||
*/
|
||||
#define AES_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
|
||||
#define AES_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
|
||||
|
||||
#if !defined(PLATFORM_BYTE_ORDER)
|
||||
#if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN)
|
||||
# if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
|
||||
# if defined(BYTE_ORDER)
|
||||
# if (BYTE_ORDER == LITTLE_ENDIAN)
|
||||
# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
|
||||
# elif (BYTE_ORDER == BIG_ENDIAN)
|
||||
# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
|
||||
# endif
|
||||
# endif
|
||||
# elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
|
||||
# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
|
||||
# elif !defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
|
||||
# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
|
||||
# endif
|
||||
#elif defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN)
|
||||
# if defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
|
||||
# if defined(_BYTE_ORDER)
|
||||
# if (_BYTE_ORDER == _LITTLE_ENDIAN)
|
||||
# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
|
||||
# elif (_BYTE_ORDER == _BIG_ENDIAN)
|
||||
# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
|
||||
# endif
|
||||
# endif
|
||||
# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
|
||||
# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
|
||||
# elif !defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
|
||||
# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
|
||||
# endif
|
||||
#elif 0 /* **** EDIT HERE IF NECESSARY **** */
|
||||
#define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
|
||||
#elif 0 /* **** EDIT HERE IF NECESSARY **** */
|
||||
#define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
|
||||
/*
|
||||
#elif (('1234' >> 24) == '1')
|
||||
# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
|
||||
#elif (('4321' >> 24) == '1')
|
||||
# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
|
||||
*/
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(PLATFORM_BYTE_ORDER)
|
||||
# error Please set undetermined byte order (lines 233 or 235 of aesopt.h).
|
||||
#endif
|
||||
|
||||
/* 3. ASSEMBLER SUPPORT
|
||||
|
||||
If the assembler code is used for encryption and decryption this file only
|
||||
provides key scheduling so the following defines are used
|
||||
*/
|
||||
#ifdef AES_ASM
|
||||
#define ENCRYPTION_KEY_SCHEDULE
|
||||
#define DECRYPTION_KEY_SCHEDULE
|
||||
#else
|
||||
|
||||
/* 4. FUNCTIONS REQUIRED
|
||||
|
||||
This implementation provides five main subroutines which provide for
|
||||
setting block length, setting encryption and decryption keys and for
|
||||
encryption and decryption. When the assembler code is not being used
|
||||
the following definition blocks allow the selection of the routines
|
||||
that are to be included in the compilation.
|
||||
*/
|
||||
#if 1
|
||||
#define ENCRYPTION_KEY_SCHEDULE
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#define DECRYPTION_KEY_SCHEDULE
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#define ENCRYPTION
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#define DECRYPTION
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* 5. BYTE ORDER WITHIN 32 BIT WORDS
|
||||
|
||||
The fundamental data processing units in Rijndael are 8-bit bytes. The
|
||||
input, output and key input are all enumerated arrays of bytes in which
|
||||
bytes are numbered starting at zero and increasing to one less than the
|
||||
number of bytes in the array in question. This enumeration is only used
|
||||
for naming bytes and does not imply any adjacency or order relationship
|
||||
from one byte to another. When these inputs and outputs are considered
|
||||
as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to
|
||||
byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte.
|
||||
In this implementation bits are numbered from 0 to 7 starting at the
|
||||
numerically least significant end of each byte (bit n represents 2^n).
|
||||
|
||||
However, Rijndael can be implemented more efficiently using 32-bit
|
||||
words by packing bytes into words so that bytes 4*n to 4*n+3 are placed
|
||||
into word[n]. While in principle these bytes can be assembled into words
|
||||
in any positions, this implementation only supports the two formats in
|
||||
which bytes in adjacent positions within words also have adjacent byte
|
||||
numbers. This order is called big-endian if the lowest numbered bytes
|
||||
in words have the highest numeric significance and little-endian if the
|
||||
opposite applies.
|
||||
|
||||
This code can work in either order irrespective of the order used by the
|
||||
machine on which it runs. Normally the internal byte order will be set
|
||||
to the order of the processor on which the code is to be run but this
|
||||
define can be used to reverse this in special situations
|
||||
*/
|
||||
#if 1
|
||||
#define INTERNAL_BYTE_ORDER PLATFORM_BYTE_ORDER
|
||||
#elif defined(AES_LITTLE_ENDIAN)
|
||||
#define INTERNAL_BYTE_ORDER AES_LITTLE_ENDIAN
|
||||
#elif defined(AES_BIG_ENDIAN)
|
||||
#define INTERNAL_BYTE_ORDER AES_BIG_ENDIAN
|
||||
#endif
|
||||
|
||||
/* 6. FAST INPUT/OUTPUT OPERATIONS.
|
||||
|
||||
On some machines it is possible to improve speed by transferring the
|
||||
bytes in the input and output arrays to and from the internal 32-bit
|
||||
variables by addressing these arrays as if they are arrays of 32-bit
|
||||
words. On some machines this will always be possible but there may
|
||||
be a large performance penalty if the byte arrays are not aligned on
|
||||
the normal word boundaries. On other machines this technique will
|
||||
lead to memory access errors when such 32-bit word accesses are not
|
||||
properly aligned. The option SAFE_IO avoids such problems but will
|
||||
often be slower on those machines that support misaligned access
|
||||
(especially so if care is taken to align the input and output byte
|
||||
arrays on 32-bit word boundaries). If SAFE_IO is not defined it is
|
||||
assumed that access to byte arrays as if they are arrays of 32-bit
|
||||
words will not cause problems when such accesses are misaligned.
|
||||
*/
|
||||
#if 1
|
||||
#define SAFE_IO
|
||||
#endif
|
||||
|
||||
/* 7. LOOP UNROLLING
|
||||
|
||||
The code for encryption and decrytpion 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.
|
||||
There are also potential speed advantages in expanding two iterations in
|
||||
a loop with half the number of iterations, which is called partial loop
|
||||
unrolling. The following options allow partial or full loop unrolling
|
||||
to be set independently for encryption and decryption
|
||||
*/
|
||||
#if 1
|
||||
#define ENC_UNROLL FULL
|
||||
#elif 0
|
||||
#define ENC_UNROLL PARTIAL
|
||||
#else
|
||||
#define ENC_UNROLL NONE
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#define DEC_UNROLL FULL
|
||||
#elif 0
|
||||
#define DEC_UNROLL PARTIAL
|
||||
#else
|
||||
#define DEC_UNROLL NONE
|
||||
#endif
|
||||
|
||||
/* 8. FIXED OR DYNAMIC TABLES
|
||||
|
||||
When this section is included the tables used by the code are comipled
|
||||
statically into the binary file. Otherwise they are computed once when
|
||||
the code is first used.
|
||||
*/
|
||||
#if 1
|
||||
#define FIXED_TABLES
|
||||
#endif
|
||||
|
||||
/* 9. 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).
|
||||
*/
|
||||
#if 1
|
||||
#define FF_TABLES
|
||||
#endif
|
||||
|
||||
/* 10. 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
|
||||
names variables. Include this section if you want to store these local
|
||||
varaibles in arrays. Otherwise individual local variables will be used.
|
||||
*/
|
||||
#if 1
|
||||
#define ARRAYS
|
||||
#endif
|
||||
|
||||
/* In this implementation the columns of the state array are each held in
|
||||
32-bit words. The state array can be held in various ways: in an array
|
||||
of words, in a number of individual word variables or in a number of
|
||||
processor registers. The following define maps a variable name x and
|
||||
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
|
||||
register names.
|
||||
*/
|
||||
|
||||
#if defined(ARRAYS)
|
||||
#define s(x,c) x[c]
|
||||
#else
|
||||
#define s(x,c) x##c
|
||||
#endif
|
||||
|
||||
/* 11. VARIABLE BLOCK SIZE SPEED
|
||||
|
||||
This section is only relevant if you wish to use the variable block
|
||||
length feature of the code. Include this section if you place more
|
||||
emphasis on speed rather than code size.
|
||||
*/
|
||||
#if 1
|
||||
#define FAST_VARIABLE
|
||||
#endif
|
||||
|
||||
/* 12. INTERNAL TABLE CONFIGURATION
|
||||
|
||||
This cipher proceeds by repeating in a number of cycles known as 'rounds'
|
||||
which are implemented by a round function which can optionally be speeded
|
||||
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
|
||||
different again making four different round functions in all.
|
||||
|
||||
This means that:
|
||||
1. Normal encryption and decryption rounds can each use either 0, 1
|
||||
or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
|
||||
2. The last encryption and decryption rounds can also use either 0, 1
|
||||
or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
|
||||
|
||||
Include or exclude the appropriate definitions below to set the number
|
||||
of tables used by this implementation.
|
||||
*/
|
||||
|
||||
#if 1 /* set tables for the normal encryption round */
|
||||
#define ENC_ROUND FOUR_TABLES
|
||||
#elif 0
|
||||
#define ENC_ROUND ONE_TABLE
|
||||
#else
|
||||
#define ENC_ROUND NO_TABLES
|
||||
#endif
|
||||
|
||||
#if 1 /* set tables for the last encryption round */
|
||||
#define LAST_ENC_ROUND FOUR_TABLES
|
||||
#elif 0
|
||||
#define LAST_ENC_ROUND ONE_TABLE
|
||||
#else
|
||||
#define LAST_ENC_ROUND NO_TABLES
|
||||
#endif
|
||||
|
||||
#if 1 /* set tables for the normal decryption round */
|
||||
#define DEC_ROUND FOUR_TABLES
|
||||
#elif 0
|
||||
#define DEC_ROUND ONE_TABLE
|
||||
#else
|
||||
#define DEC_ROUND NO_TABLES
|
||||
#endif
|
||||
|
||||
#if 1 /* set tables for the last decryption round */
|
||||
#define LAST_DEC_ROUND FOUR_TABLES
|
||||
#elif 0
|
||||
#define LAST_DEC_ROUND ONE_TABLE
|
||||
#else
|
||||
#define LAST_DEC_ROUND NO_TABLES
|
||||
#endif
|
||||
|
||||
/* The decryption key schedule can be speeded up with tables in the same
|
||||
way that the round functions can. Include or exclude the following
|
||||
defines to set this requirement.
|
||||
*/
|
||||
#if 1
|
||||
#define KEY_SCHED FOUR_TABLES
|
||||
#elif 0
|
||||
#define KEY_SCHED ONE_TABLE
|
||||
#else
|
||||
#define KEY_SCHED NO_TABLES
|
||||
#endif
|
||||
|
||||
/* END OF CONFIGURATION OPTIONS */
|
||||
|
||||
#define NO_TABLES 0 /* DO NOT CHANGE */
|
||||
#define ONE_TABLE 1 /* DO NOT CHANGE */
|
||||
#define FOUR_TABLES 4 /* DO NOT CHANGE */
|
||||
#define NONE 0 /* DO NOT CHANGE */
|
||||
#define PARTIAL 1 /* DO NOT CHANGE */
|
||||
#define FULL 2 /* DO NOT CHANGE */
|
||||
|
||||
#if defined(BLOCK_SIZE) && ((BLOCK_SIZE & 3) || BLOCK_SIZE < 16 || BLOCK_SIZE > 32)
|
||||
#error An illegal block size has been specified.
|
||||
#endif
|
||||
|
||||
#if !defined(BLOCK_SIZE)
|
||||
#define RC_LENGTH 29
|
||||
#else
|
||||
#define RC_LENGTH 5 * BLOCK_SIZE / 4 - (BLOCK_SIZE == 16 ? 10 : 11)
|
||||
#endif
|
||||
|
||||
/* Disable at least some poor combinations of options */
|
||||
|
||||
#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES
|
||||
#undef LAST_ENC_ROUND
|
||||
#define LAST_ENC_ROUND NO_TABLES
|
||||
#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES
|
||||
#undef LAST_ENC_ROUND
|
||||
#define LAST_ENC_ROUND ONE_TABLE
|
||||
#endif
|
||||
|
||||
#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE
|
||||
#undef ENC_UNROLL
|
||||
#define ENC_UNROLL NONE
|
||||
#endif
|
||||
|
||||
#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES
|
||||
#undef LAST_DEC_ROUND
|
||||
#define LAST_DEC_ROUND NO_TABLES
|
||||
#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES
|
||||
#undef LAST_DEC_ROUND
|
||||
#define LAST_DEC_ROUND ONE_TABLE
|
||||
#endif
|
||||
|
||||
#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE
|
||||
#undef DEC_UNROLL
|
||||
#define DEC_UNROLL NONE
|
||||
#endif
|
||||
|
||||
/* upr(x,n): rotates bytes within words by n positions, moving bytes to
|
||||
higher index positions with wrap around into low positions
|
||||
ups(x,n): moves bytes by n positions to higher index positions in
|
||||
words but without wrap around
|
||||
bval(x,n): extracts a byte from a word
|
||||
|
||||
NOTE: The definitions given here are intended only for use with
|
||||
unsigned variables and with shift counts that are compile
|
||||
time constants
|
||||
*/
|
||||
|
||||
#if (INTERNAL_BYTE_ORDER == AES_LITTLE_ENDIAN)
|
||||
#if defined(_MSC_VER)
|
||||
#define upr(x,n) _lrotl((aes_32t)(x), 8 * (n))
|
||||
#else
|
||||
#define upr(x,n) ((aes_32t)(x) << 8 * (n) | (aes_32t)(x) >> 32 - 8 * (n))
|
||||
#endif
|
||||
#define ups(x,n) ((aes_32t)(x) << 8 * (n))
|
||||
#define bval(x,n) ((aes_08t)((x) >> 8 * (n)))
|
||||
#define bytes2word(b0, b1, b2, b3) \
|
||||
(((aes_32t)(b3) << 24) | ((aes_32t)(b2) << 16) | ((aes_32t)(b1) << 8) | (b0))
|
||||
#endif
|
||||
|
||||
#if (INTERNAL_BYTE_ORDER == AES_BIG_ENDIAN)
|
||||
#define upr(x,n) ((aes_32t)(x) >> 8 * (n) | (aes_32t)(x) << 32 - 8 * (n))
|
||||
#define ups(x,n) ((aes_32t)(x) >> 8 * (n)))
|
||||
#define bval(x,n) ((aes_08t)((x) >> 24 - 8 * (n)))
|
||||
#define bytes2word(b0, b1, b2, b3) \
|
||||
(((aes_32t)(b0) << 24) | ((aes_32t)(b1) << 16) | ((aes_32t)(b2) << 8) | (b3))
|
||||
#endif
|
||||
|
||||
#if defined(SAFE_IO)
|
||||
|
||||
#define word_in(x) bytes2word((x)[0], (x)[1], (x)[2], (x)[3])
|
||||
#define word_out(x,v) { (x)[0] = bval(v,0); (x)[1] = bval(v,1); \
|
||||
(x)[2] = bval(v,2); (x)[3] = bval(v,3); }
|
||||
|
||||
#elif (INTERNAL_BYTE_ORDER == PLATFORM_BYTE_ORDER)
|
||||
|
||||
#define word_in(x) *(aes_32t*)(x)
|
||||
#define word_out(x,v) *(aes_32t*)(x) = (v)
|
||||
|
||||
#else
|
||||
|
||||
#if !defined(bswap_32)
|
||||
#if !defined(_MSC_VER)
|
||||
#define _lrotl(x,n) ((aes_32t)(x) << n | (aes_32t)(x) >> 32 - n)
|
||||
#endif
|
||||
#define bswap_32(x) ((_lrotl((x),8) & 0x00ff00ff) | (_lrotl((x),24) & 0xff00ff00))
|
||||
#endif
|
||||
|
||||
#define word_in(x) bswap_32(*(aes_32t*)(x))
|
||||
#define word_out(x,v) *(aes_32t*)(x) = bswap_32(v)
|
||||
|
||||
#endif
|
||||
|
||||
/* the finite field modular polynomial and elements */
|
||||
|
||||
#define WPOLY 0x011b
|
||||
#define BPOLY 0x1b
|
||||
|
||||
/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
|
||||
|
||||
#define m1 0x80808080
|
||||
#define m2 0x7f7f7f7f
|
||||
#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * BPOLY))
|
||||
|
||||
/* The following defines provide alternative definitions of FFmulX 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 FFmulX is used.
|
||||
|
||||
#define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
|
||||
#define m4 (0x01010101 * BPOLY)
|
||||
#define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
|
||||
*/
|
||||
|
||||
/* Work out which tables are needed for the different options */
|
||||
|
||||
#ifdef AES_ASM
|
||||
#ifdef ENC_ROUND
|
||||
#undef ENC_ROUND
|
||||
#endif
|
||||
#define ENC_ROUND FOUR_TABLES
|
||||
#ifdef LAST_ENC_ROUND
|
||||
#undef LAST_ENC_ROUND
|
||||
#endif
|
||||
#define LAST_ENC_ROUND FOUR_TABLES
|
||||
#ifdef DEC_ROUND
|
||||
#undef DEC_ROUND
|
||||
#endif
|
||||
#define DEC_ROUND FOUR_TABLES
|
||||
#ifdef LAST_DEC_ROUND
|
||||
#undef LAST_DEC_ROUND
|
||||
#endif
|
||||
#define LAST_DEC_ROUND FOUR_TABLES
|
||||
#ifdef KEY_SCHED
|
||||
#undef KEY_SCHED
|
||||
#define KEY_SCHED FOUR_TABLES
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(ENCRYPTION) || defined(AES_ASM)
|
||||
#if ENC_ROUND == ONE_TABLE
|
||||
#define FT1_SET
|
||||
#elif ENC_ROUND == FOUR_TABLES
|
||||
#define FT4_SET
|
||||
#else
|
||||
#define SBX_SET
|
||||
#endif
|
||||
#if LAST_ENC_ROUND == ONE_TABLE
|
||||
#define FL1_SET
|
||||
#elif LAST_ENC_ROUND == FOUR_TABLES
|
||||
#define FL4_SET
|
||||
#elif !defined(SBX_SET)
|
||||
#define SBX_SET
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(DECRYPTION) || defined(AES_ASM)
|
||||
#if DEC_ROUND == ONE_TABLE
|
||||
#define IT1_SET
|
||||
#elif DEC_ROUND == FOUR_TABLES
|
||||
#define IT4_SET
|
||||
#else
|
||||
#define ISB_SET
|
||||
#endif
|
||||
#if LAST_DEC_ROUND == ONE_TABLE
|
||||
#define IL1_SET
|
||||
#elif LAST_DEC_ROUND == FOUR_TABLES
|
||||
#define IL4_SET
|
||||
#elif !defined(ISB_SET)
|
||||
#define ISB_SET
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(ENCRYPTION_KEY_SCHEDULE) || defined(DECRYPTION_KEY_SCHEDULE)
|
||||
#if KEY_SCHED == ONE_TABLE
|
||||
#define LS1_SET
|
||||
#define IM1_SET
|
||||
#elif KEY_SCHED == FOUR_TABLES
|
||||
#define LS4_SET
|
||||
#define IM4_SET
|
||||
#elif !defined(SBX_SET)
|
||||
#define SBX_SET
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef FIXED_TABLES
|
||||
#define prefx extern const
|
||||
#else
|
||||
#define prefx extern
|
||||
extern aes_08t tab_init;
|
||||
void gen_tabs(void);
|
||||
#endif
|
||||
|
||||
prefx aes_32t rcon_tab[29];
|
||||
|
||||
#ifdef SBX_SET
|
||||
prefx aes_08t s_box[256];
|
||||
#endif
|
||||
|
||||
#ifdef ISB_SET
|
||||
prefx aes_08t inv_s_box[256];
|
||||
#endif
|
||||
|
||||
#ifdef FT1_SET
|
||||
prefx aes_32t ft_tab[256];
|
||||
#endif
|
||||
|
||||
#ifdef FT4_SET
|
||||
prefx aes_32t ft_tab[4][256];
|
||||
#endif
|
||||
|
||||
#ifdef FL1_SET
|
||||
prefx aes_32t fl_tab[256];
|
||||
#endif
|
||||
|
||||
#ifdef FL4_SET
|
||||
prefx aes_32t fl_tab[4][256];
|
||||
#endif
|
||||
|
||||
#ifdef IT1_SET
|
||||
prefx aes_32t it_tab[256];
|
||||
#endif
|
||||
|
||||
#ifdef IT4_SET
|
||||
prefx aes_32t it_tab[4][256];
|
||||
#endif
|
||||
|
||||
#ifdef IL1_SET
|
||||
prefx aes_32t il_tab[256];
|
||||
#endif
|
||||
|
||||
#ifdef IL4_SET
|
||||
prefx aes_32t il_tab[4][256];
|
||||
#endif
|
||||
|
||||
#ifdef LS1_SET
|
||||
#ifdef FL1_SET
|
||||
#undef LS1_SET
|
||||
#else
|
||||
prefx aes_32t ls_tab[256];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef LS4_SET
|
||||
#ifdef FL4_SET
|
||||
#undef LS4_SET
|
||||
#else
|
||||
prefx aes_32t ls_tab[4][256];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef IM1_SET
|
||||
prefx aes_32t im_tab[256];
|
||||
#endif
|
||||
|
||||
#ifdef IM4_SET
|
||||
prefx aes_32t im_tab[4][256];
|
||||
#endif
|
||||
|
||||
/* Set the number of columns in nc. Note that it is important
|
||||
that nc is a constant which is known at compile time if the
|
||||
highest speed version of the code is needed.
|
||||
*/
|
||||
|
||||
#if defined(BLOCK_SIZE)
|
||||
#define nc (BLOCK_SIZE >> 2)
|
||||
#else
|
||||
#define nc (cx->n_blk >> 2)
|
||||
#endif
|
||||
|
||||
/* generic definitions of Rijndael macros that use tables */
|
||||
|
||||
#define no_table(x,box,vf,rf,c) bytes2word( \
|
||||
box[bval(vf(x,0,c),rf(0,c))], \
|
||||
box[bval(vf(x,1,c),rf(1,c))], \
|
||||
box[bval(vf(x,2,c),rf(2,c))], \
|
||||
box[bval(vf(x,3,c),rf(3,c))])
|
||||
|
||||
#define one_table(x,op,tab,vf,rf,c) \
|
||||
( tab[bval(vf(x,0,c),rf(0,c))] \
|
||||
^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
|
||||
^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
|
||||
^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
|
||||
|
||||
#define four_tables(x,tab,vf,rf,c) \
|
||||
( tab[0][bval(vf(x,0,c),rf(0,c))] \
|
||||
^ tab[1][bval(vf(x,1,c),rf(1,c))] \
|
||||
^ tab[2][bval(vf(x,2,c),rf(2,c))] \
|
||||
^ tab[3][bval(vf(x,3,c),rf(3,c))])
|
||||
|
||||
#define vf1(x,r,c) (x)
|
||||
#define rf1(r,c) (r)
|
||||
#define rf2(r,c) ((r-c)&3)
|
||||
|
||||
/* perform forward and inverse column mix operation on four bytes in long word x in */
|
||||
/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros. */
|
||||
|
||||
#define dec_fmvars
|
||||
#if defined(FM4_SET) /* not currently used */
|
||||
#define fwd_mcol(x) four_tables(x,fm_tab,vf1,rf1,0)
|
||||
#elif defined(FM1_SET) /* not currently used */
|
||||
#define fwd_mcol(x) one_table(x,upr,fm_tab,vf1,rf1,0)
|
||||
#else
|
||||
#undef dec_fmvars
|
||||
#define dec_fmvars aes_32t f1, f2;
|
||||
#define fwd_mcol(x) (f1 = (x), f2 = FFmulX(f1), f2 ^ upr(f1 ^ f2, 3) ^ upr(f1, 2) ^ upr(f1, 1))
|
||||
#endif
|
||||
|
||||
#define dec_imvars
|
||||
#if defined(IM4_SET)
|
||||
#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
|
||||
#elif defined(IM1_SET)
|
||||
#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0)
|
||||
#else
|
||||
#undef dec_imvars
|
||||
#define dec_imvars aes_32t f2, f4, f8, f9;
|
||||
#define inv_mcol(x) \
|
||||
(f9 = (x), f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
|
||||
f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
|
||||
#endif
|
||||
|
||||
#if defined(FL4_SET)
|
||||
#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
|
||||
#elif defined(LS4_SET)
|
||||
#define ls_box(x,c) four_tables(x,ls_tab,vf1,rf2,c)
|
||||
#elif defined(FL1_SET)
|
||||
#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c)
|
||||
#elif defined(LS1_SET)
|
||||
#define ls_box(x,c) one_table(x,upr,ls_tab,vf1,rf2,c)
|
||||
#else
|
||||
#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c)
|
||||
#endif
|
||||
|
||||
#endif
|
494
aestab.c
Normal file
494
aestab.c
Normal file
@ -0,0 +1,494 @@
|
||||
/*
|
||||
-------------------------------------------------------------------------
|
||||
Copyright (c) 2001, 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.
|
||||
|
||||
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 fitness for purpose.
|
||||
-------------------------------------------------------------------------
|
||||
Issue Date: 29/07/2002
|
||||
*/
|
||||
|
||||
#include "aesopt.h"
|
||||
|
||||
#if defined(FIXED_TABLES) || !defined(FF_TABLES)
|
||||
|
||||
/* finite field arithmetic operations */
|
||||
|
||||
#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY))
|
||||
#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
|
||||
#define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \
|
||||
^ (((x>>5) & 4) * WPOLY))
|
||||
#define f3(x) (f2(x) ^ x)
|
||||
#define f9(x) (f8(x) ^ x)
|
||||
#define fb(x) (f8(x) ^ f2(x) ^ x)
|
||||
#define fd(x) (f8(x) ^ f4(x) ^ x)
|
||||
#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(FIXED_TABLES)
|
||||
|
||||
#define sb_data(w) \
|
||||
w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
|
||||
w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
|
||||
w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
|
||||
w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
|
||||
w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
|
||||
w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
|
||||
w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
|
||||
w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
|
||||
w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
|
||||
w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
|
||||
w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
|
||||
w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
|
||||
w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
|
||||
w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
|
||||
w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
|
||||
w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
|
||||
w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
|
||||
w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
|
||||
w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
|
||||
w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
|
||||
w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
|
||||
w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
|
||||
w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
|
||||
w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
|
||||
w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
|
||||
w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
|
||||
w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
|
||||
w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
|
||||
w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
|
||||
w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
|
||||
w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
|
||||
w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16)
|
||||
|
||||
#define isb_data(w) \
|
||||
w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
|
||||
w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
|
||||
w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
|
||||
w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\
|
||||
w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\
|
||||
w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\
|
||||
w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\
|
||||
w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\
|
||||
w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\
|
||||
w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\
|
||||
w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\
|
||||
w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\
|
||||
w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\
|
||||
w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\
|
||||
w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\
|
||||
w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\
|
||||
w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\
|
||||
w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\
|
||||
w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\
|
||||
w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\
|
||||
w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\
|
||||
w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\
|
||||
w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\
|
||||
w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\
|
||||
w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\
|
||||
w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\
|
||||
w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\
|
||||
w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\
|
||||
w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
|
||||
w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
|
||||
w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
|
||||
w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d),
|
||||
|
||||
#define mm_data(w) \
|
||||
w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
|
||||
w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
|
||||
w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
|
||||
w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\
|
||||
w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\
|
||||
w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\
|
||||
w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\
|
||||
w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\
|
||||
w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\
|
||||
w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\
|
||||
w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\
|
||||
w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\
|
||||
w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\
|
||||
w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\
|
||||
w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\
|
||||
w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\
|
||||
w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\
|
||||
w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\
|
||||
w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\
|
||||
w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\
|
||||
w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\
|
||||
w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\
|
||||
w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\
|
||||
w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\
|
||||
w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\
|
||||
w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\
|
||||
w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\
|
||||
w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\
|
||||
w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
|
||||
w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
|
||||
w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
|
||||
w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff)
|
||||
|
||||
#define h0(x) (x)
|
||||
|
||||
/* These defines are used to ensure tables are generated in the
|
||||
right format depending on the internal byte order required
|
||||
*/
|
||||
|
||||
#define w0(p) bytes2word(p, 0, 0, 0)
|
||||
#define w1(p) bytes2word(0, p, 0, 0)
|
||||
#define w2(p) bytes2word(0, 0, p, 0)
|
||||
#define w3(p) bytes2word(0, 0, 0, p)
|
||||
|
||||
/* Number of elements required in this table for different
|
||||
block and key lengths is:
|
||||
|
||||
Rcon Table key length (bytes)
|
||||
Length 16 20 24 28 32
|
||||
---------------------
|
||||
block 16 | 10 9 8 7 7
|
||||
length 20 | 14 11 10 9 9
|
||||
(bytes) 24 | 19 15 12 11 11
|
||||
28 | 24 19 16 13 13
|
||||
32 | 29 23 19 17 14
|
||||
|
||||
this table can be a table of bytes if the key schedule
|
||||
code is adjusted accordingly
|
||||
*/
|
||||
|
||||
#define u0(p) bytes2word(f2(p), p, p, f3(p))
|
||||
#define u1(p) bytes2word(f3(p), f2(p), p, p)
|
||||
#define u2(p) bytes2word(p, f3(p), f2(p), p)
|
||||
#define u3(p) bytes2word(p, p, f3(p), f2(p))
|
||||
|
||||
#define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p))
|
||||
#define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p))
|
||||
#define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p))
|
||||
#define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p))
|
||||
|
||||
const aes_32t rcon_tab[29] =
|
||||
{
|
||||
w0(0x01), w0(0x02), w0(0x04), w0(0x08),
|
||||
w0(0x10), w0(0x20), w0(0x40), w0(0x80),
|
||||
w0(0x1b), w0(0x36), w0(0x6c), w0(0xd8),
|
||||
w0(0xab), w0(0x4d), w0(0x9a), w0(0x2f),
|
||||
w0(0x5e), w0(0xbc), w0(0x63), w0(0xc6),
|
||||
w0(0x97), w0(0x35), w0(0x6a), w0(0xd4),
|
||||
w0(0xb3), w0(0x7d), w0(0xfa), w0(0xef),
|
||||
w0(0xc5)
|
||||
};
|
||||
|
||||
#ifdef SBX_SET
|
||||
const aes_08t s_box[256] = { sb_data(h0) };
|
||||
#endif
|
||||
#ifdef ISB_SET
|
||||
const aes_08t inv_s_box[256] = { isb_data(h0) };
|
||||
#endif
|
||||
|
||||
#ifdef FT1_SET
|
||||
const aes_32t ft_tab[256] = { sb_data(u0) };
|
||||
#endif
|
||||
#ifdef FT4_SET
|
||||
const aes_32t ft_tab[4][256] =
|
||||
{ { sb_data(u0) }, { sb_data(u1) }, { sb_data(u2) }, { sb_data(u3) } };
|
||||
#endif
|
||||
|
||||
#ifdef FL1_SET
|
||||
const aes_32t fl_tab[256] = { sb_data(w0) };
|
||||
#endif
|
||||
#ifdef FL4_SET
|
||||
const aes_32t fl_tab[4][256] =
|
||||
{ { sb_data(w0) }, { sb_data(w1) }, { sb_data(w2) }, { sb_data(w3) } };
|
||||
#endif
|
||||
|
||||
#ifdef IT1_SET
|
||||
const aes_32t it_tab[256] = { isb_data(v0) };
|
||||
#endif
|
||||
#ifdef IT4_SET
|
||||
const aes_32t it_tab[4][256] =
|
||||
{ { isb_data(v0) }, { isb_data(v1) }, { isb_data(v2) }, { isb_data(v3) } };
|
||||
#endif
|
||||
|
||||
#ifdef IL1_SET
|
||||
const aes_32t il_tab[256] = { isb_data(w0) };
|
||||
#endif
|
||||
#ifdef IL4_SET
|
||||
const aes_32t il_tab[4][256] =
|
||||
{ { isb_data(w0) }, { isb_data(w1) }, { isb_data(w2) }, { isb_data(w3) } };
|
||||
#endif
|
||||
|
||||
#ifdef LS1_SET
|
||||
const aes_32t ls_tab[256] = { sb_data(w0) };
|
||||
#endif
|
||||
#ifdef LS4_SET
|
||||
const aes_32t ls_tab[4][256] =
|
||||
{ { sb_data(w0) }, { sb_data(w1) }, { sb_data(w2) }, { sb_data(w3) } };
|
||||
#endif
|
||||
|
||||
#ifdef IM1_SET
|
||||
const aes_32t im_tab[256] = { mm_data(v0) };
|
||||
#endif
|
||||
#ifdef IM4_SET
|
||||
const aes_32t im_tab[4][256] =
|
||||
{ { mm_data(v0) }, { mm_data(v1) }, { mm_data(v2) }, { mm_data(v3) } };
|
||||
#endif
|
||||
|
||||
#else /* dynamic table generation */
|
||||
|
||||
aes_08t tab_init = 0;
|
||||
|
||||
#define const
|
||||
|
||||
aes_32t rcon_tab[RC_LENGTH];
|
||||
|
||||
#ifdef SBX_SET
|
||||
aes_08t s_box[256];
|
||||
#endif
|
||||
#ifdef ISB_SET
|
||||
aes_08t inv_s_box[256];
|
||||
#endif
|
||||
|
||||
#ifdef FT1_SET
|
||||
aes_32t ft_tab[256];
|
||||
#endif
|
||||
#ifdef FT4_SET
|
||||
aes_32t ft_tab[4][256];
|
||||
#endif
|
||||
|
||||
#ifdef FL1_SET
|
||||
aes_32t fl_tab[256];
|
||||
#endif
|
||||
#ifdef FL4_SET
|
||||
aes_32t fl_tab[4][256];
|
||||
#endif
|
||||
|
||||
#ifdef IT1_SET
|
||||
aes_32t it_tab[256];
|
||||
#endif
|
||||
#ifdef IT4_SET
|
||||
aes_32t it_tab[4][256];
|
||||
#endif
|
||||
|
||||
#ifdef IL1_SET
|
||||
aes_32t il_tab[256];
|
||||
#endif
|
||||
#ifdef IL4_SET
|
||||
aes_32t il_tab[4][256];
|
||||
#endif
|
||||
|
||||
#ifdef LS1_SET
|
||||
aes_32t ls_tab[256];
|
||||
#endif
|
||||
#ifdef LS4_SET
|
||||
aes_32t ls_tab[4][256];
|
||||
#endif
|
||||
|
||||
#ifdef IM1_SET
|
||||
aes_32t im_tab[256];
|
||||
#endif
|
||||
#ifdef IM4_SET
|
||||
aes_32t im_tab[4][256];
|
||||
#endif
|
||||
|
||||
#if !defined(FF_TABLES)
|
||||
|
||||
/* Generate the tables for the dynamic table option
|
||||
|
||||
It will generally be sensible to use tables to compute finite
|
||||
field multiplies and inverses but where memory is scarse this
|
||||
code might sometimes be better. But it only has effect during
|
||||
initialisation so its pretty unimportant in overall terms.
|
||||
*/
|
||||
|
||||
/* return 2 ^ (n - 1) where n is the bit number of the highest bit
|
||||
set in x with x in the range 1 < x < 0x00000200. This form is
|
||||
used so that locals within fi can be bytes rather than words
|
||||
*/
|
||||
|
||||
static aes_08t hibit(const aes_32t x)
|
||||
{ aes_08t r = (aes_08t)((x >> 1) | (x >> 2));
|
||||
|
||||
r |= (r >> 2);
|
||||
r |= (r >> 4);
|
||||
return (r + 1) >> 1;
|
||||
}
|
||||
|
||||
/* return the inverse of the finite field element x */
|
||||
|
||||
static aes_08t fi(const aes_08t x)
|
||||
{ aes_08t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
|
||||
|
||||
if(x < 2) return x;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if(!n1) return v1;
|
||||
|
||||
while(n2 >= n1)
|
||||
{
|
||||
n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
|
||||
}
|
||||
|
||||
if(!n2) return v2;
|
||||
|
||||
while(n1 >= n2)
|
||||
{
|
||||
n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* define the finite field multiplies required for Rijndael */
|
||||
|
||||
#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
|
||||
#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
|
||||
#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
|
||||
#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
|
||||
#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
|
||||
#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
|
||||
#define fi(x) ((x) ? pow[255 - log[x]]: 0)
|
||||
|
||||
#endif
|
||||
|
||||
/* The forward and inverse affine transformations used in the S-box */
|
||||
|
||||
#define fwd_affine(x) \
|
||||
(w = (aes_32t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(aes_08t)(w^(w>>8)))
|
||||
|
||||
#define inv_affine(x) \
|
||||
(w = (aes_32t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(aes_08t)(w^(w>>8)))
|
||||
|
||||
void gen_tabs(void)
|
||||
{ aes_32t i, w;
|
||||
|
||||
#if defined(FF_TABLES)
|
||||
|
||||
aes_08t pow[512], log[256];
|
||||
|
||||
/* log and power tables for GF(2^8) finite field with
|
||||
WPOLY as modular polynomial - the simplest primitive
|
||||
root is 0x03, used here to generate the tables
|
||||
*/
|
||||
|
||||
i = 0; w = 1;
|
||||
do
|
||||
{
|
||||
pow[i] = (aes_08t)w;
|
||||
pow[i + 255] = (aes_08t)w;
|
||||
log[w] = (aes_08t)i++;
|
||||
w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0);
|
||||
}
|
||||
while (w != 1);
|
||||
|
||||
#endif
|
||||
|
||||
for(i = 0, w = 1; i < RC_LENGTH; ++i)
|
||||
{
|
||||
rcon_tab[i] = bytes2word(w, 0, 0, 0);
|
||||
w = f2(w);
|
||||
}
|
||||
|
||||
for(i = 0; i < 256; ++i)
|
||||
{ aes_08t b;
|
||||
|
||||
b = fwd_affine(fi((aes_08t)i));
|
||||
w = bytes2word(f2(b), b, b, f3(b));
|
||||
|
||||
#ifdef SBX_SET
|
||||
s_box[i] = b;
|
||||
#endif
|
||||
|
||||
#ifdef FT1_SET /* tables for a normal encryption round */
|
||||
ft_tab[i] = w;
|
||||
#endif
|
||||
#ifdef FT4_SET
|
||||
ft_tab[0][i] = w;
|
||||
ft_tab[1][i] = upr(w,1);
|
||||
ft_tab[2][i] = upr(w,2);
|
||||
ft_tab[3][i] = upr(w,3);
|
||||
#endif
|
||||
w = bytes2word(b, 0, 0, 0);
|
||||
|
||||
#ifdef FL1_SET /* tables for last encryption round (may also */
|
||||
fl_tab[i] = w; /* be used in the key schedule) */
|
||||
#endif
|
||||
#ifdef FL4_SET
|
||||
fl_tab[0][i] = w;
|
||||
fl_tab[1][i] = upr(w,1);
|
||||
fl_tab[2][i] = upr(w,2);
|
||||
fl_tab[3][i] = upr(w,3);
|
||||
#endif
|
||||
|
||||
#ifdef LS1_SET /* table for key schedule if fl_tab above is */
|
||||
ls_tab[i] = w; /* not of the required form */
|
||||
#endif
|
||||
#ifdef LS4_SET
|
||||
ls_tab[0][i] = w;
|
||||
ls_tab[1][i] = upr(w,1);
|
||||
ls_tab[2][i] = upr(w,2);
|
||||
ls_tab[3][i] = upr(w,3);
|
||||
#endif
|
||||
|
||||
b = fi(inv_affine((aes_08t)i));
|
||||
w = bytes2word(fe(b), f9(b), fd(b), fb(b));
|
||||
|
||||
#ifdef IM1_SET /* tables for the inverse mix column operation */
|
||||
im_tab[b] = w;
|
||||
#endif
|
||||
#ifdef IM4_SET
|
||||
im_tab[0][b] = w;
|
||||
im_tab[1][b] = upr(w,1);
|
||||
im_tab[2][b] = upr(w,2);
|
||||
im_tab[3][b] = upr(w,3);
|
||||
#endif
|
||||
|
||||
#ifdef ISB_SET
|
||||
inv_s_box[i] = b;
|
||||
#endif
|
||||
#ifdef IT1_SET /* tables for a normal decryption round */
|
||||
it_tab[i] = w;
|
||||
#endif
|
||||
#ifdef IT4_SET
|
||||
it_tab[0][i] = w;
|
||||
it_tab[1][i] = upr(w,1);
|
||||
it_tab[2][i] = upr(w,2);
|
||||
it_tab[3][i] = upr(w,3);
|
||||
#endif
|
||||
w = bytes2word(b, 0, 0, 0);
|
||||
#ifdef IL1_SET /* tables for last decryption round */
|
||||
il_tab[i] = w;
|
||||
#endif
|
||||
#ifdef IL4_SET
|
||||
il_tab[0][i] = w;
|
||||
il_tab[1][i] = upr(w,1);
|
||||
il_tab[2][i] = upr(w,2);
|
||||
il_tab[3][i] = upr(w,3);
|
||||
#endif
|
||||
}
|
||||
|
||||
tab_init = 1;
|
||||
}
|
||||
|
||||
#endif
|
409
blowfish.c
409
blowfish.c
@ -1,409 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Pavol Rusnak
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "blowfish.h"
|
||||
|
||||
static const uint32_t P_orig[16 + 2] = {
|
||||
0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,
|
||||
0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
|
||||
0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
|
||||
0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917,
|
||||
0x9216D5D9, 0x8979FB1B,
|
||||
};
|
||||
|
||||
static const uint32_t S_orig[4][256] = {{
|
||||
0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7,
|
||||
0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99,
|
||||
0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
|
||||
0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E,
|
||||
0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE,
|
||||
0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
|
||||
0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF,
|
||||
0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E,
|
||||
0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
|
||||
0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440,
|
||||
0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE,
|
||||
0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
|
||||
0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E,
|
||||
0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677,
|
||||
0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
|
||||
0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032,
|
||||
0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88,
|
||||
0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
|
||||
0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E,
|
||||
0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0,
|
||||
0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
|
||||
0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98,
|
||||
0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88,
|
||||
0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
|
||||
0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6,
|
||||
0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D,
|
||||
0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
|
||||
0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7,
|
||||
0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA,
|
||||
0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
|
||||
0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F,
|
||||
0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09,
|
||||
0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
|
||||
0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB,
|
||||
0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279,
|
||||
0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
|
||||
0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB,
|
||||
0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82,
|
||||
0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
|
||||
0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573,
|
||||
0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0,
|
||||
0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
|
||||
0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790,
|
||||
0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8,
|
||||
0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
|
||||
0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0,
|
||||
0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7,
|
||||
0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
|
||||
0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD,
|
||||
0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1,
|
||||
0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
|
||||
0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9,
|
||||
0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477,
|
||||
0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
|
||||
0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49,
|
||||
0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF,
|
||||
0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
|
||||
0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5,
|
||||
0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41,
|
||||
0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
|
||||
0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400,
|
||||
0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915,
|
||||
0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
|
||||
0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A,
|
||||
},{
|
||||
0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623,
|
||||
0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266,
|
||||
0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
|
||||
0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E,
|
||||
0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6,
|
||||
0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
|
||||
0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E,
|
||||
0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1,
|
||||
0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
|
||||
0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8,
|
||||
0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF,
|
||||
0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
|
||||
0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701,
|
||||
0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7,
|
||||
0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
|
||||
0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331,
|
||||
0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF,
|
||||
0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
|
||||
0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E,
|
||||
0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87,
|
||||
0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
|
||||
0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2,
|
||||
0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16,
|
||||
0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
|
||||
0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B,
|
||||
0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509,
|
||||
0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
|
||||
0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3,
|
||||
0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F,
|
||||
0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
|
||||
0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4,
|
||||
0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960,
|
||||
0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
|
||||
0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28,
|
||||
0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802,
|
||||
0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
|
||||
0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510,
|
||||
0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF,
|
||||
0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
|
||||
0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E,
|
||||
0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50,
|
||||
0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
|
||||
0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8,
|
||||
0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281,
|
||||
0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
|
||||
0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696,
|
||||
0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128,
|
||||
0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
|
||||
0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0,
|
||||
0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0,
|
||||
0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
|
||||
0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250,
|
||||
0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3,
|
||||
0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
|
||||
0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00,
|
||||
0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061,
|
||||
0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
|
||||
0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E,
|
||||
0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735,
|
||||
0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
|
||||
0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9,
|
||||
0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340,
|
||||
0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
|
||||
0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7,
|
||||
},{
|
||||
0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934,
|
||||
0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068,
|
||||
0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
|
||||
0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840,
|
||||
0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45,
|
||||
0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
|
||||
0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A,
|
||||
0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB,
|
||||
0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
|
||||
0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6,
|
||||
0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42,
|
||||
0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
|
||||
0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2,
|
||||
0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB,
|
||||
0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
|
||||
0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B,
|
||||
0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33,
|
||||
0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
|
||||
0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3,
|
||||
0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC,
|
||||
0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
|
||||
0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564,
|
||||
0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B,
|
||||
0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
|
||||
0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922,
|
||||
0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728,
|
||||
0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
|
||||
0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E,
|
||||
0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37,
|
||||
0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
|
||||
0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804,
|
||||
0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B,
|
||||
0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
|
||||
0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB,
|
||||
0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D,
|
||||
0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
|
||||
0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350,
|
||||
0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9,
|
||||
0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
|
||||
0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE,
|
||||
0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D,
|
||||
0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
|
||||
0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F,
|
||||
0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61,
|
||||
0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
|
||||
0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9,
|
||||
0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2,
|
||||
0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
|
||||
0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E,
|
||||
0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633,
|
||||
0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
|
||||
0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169,
|
||||
0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52,
|
||||
0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
|
||||
0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5,
|
||||
0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62,
|
||||
0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
|
||||
0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76,
|
||||
0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24,
|
||||
0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
|
||||
0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4,
|
||||
0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C,
|
||||
0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
|
||||
0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0,
|
||||
},{
|
||||
0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B,
|
||||
0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE,
|
||||
0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
|
||||
0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4,
|
||||
0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8,
|
||||
0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
|
||||
0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304,
|
||||
0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22,
|
||||
0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
|
||||
0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6,
|
||||
0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9,
|
||||
0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
|
||||
0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593,
|
||||
0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51,
|
||||
0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
|
||||
0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C,
|
||||
0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B,
|
||||
0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
|
||||
0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C,
|
||||
0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD,
|
||||
0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
|
||||
0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319,
|
||||
0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB,
|
||||
0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
|
||||
0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991,
|
||||
0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32,
|
||||
0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
|
||||
0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166,
|
||||
0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE,
|
||||
0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
|
||||
0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5,
|
||||
0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47,
|
||||
0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
|
||||
0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D,
|
||||
0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84,
|
||||
0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
|
||||
0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8,
|
||||
0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD,
|
||||
0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
|
||||
0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7,
|
||||
0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38,
|
||||
0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
|
||||
0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C,
|
||||
0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525,
|
||||
0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
|
||||
0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442,
|
||||
0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964,
|
||||
0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
|
||||
0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8,
|
||||
0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D,
|
||||
0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
|
||||
0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299,
|
||||
0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02,
|
||||
0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
|
||||
0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614,
|
||||
0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A,
|
||||
0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
|
||||
0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B,
|
||||
0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0,
|
||||
0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
|
||||
0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E,
|
||||
0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9,
|
||||
0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
|
||||
0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6,
|
||||
}};
|
||||
|
||||
static uint32_t P[16 + 2];
|
||||
static uint32_t S[4][256];
|
||||
|
||||
static inline void swap(uint32_t *L, uint32_t *R)
|
||||
{
|
||||
uint32_t t;
|
||||
t = *L;
|
||||
*L = *R;
|
||||
*R = t;
|
||||
}
|
||||
|
||||
static inline void swapendian(uint32_t *n)
|
||||
{
|
||||
uint8_t a, b, c, d;
|
||||
a = (*n >> 24) & 0xff;
|
||||
b = (*n >> 16) & 0xff;
|
||||
c = (*n >> 8) & 0xff;
|
||||
d = *n & 0xff;
|
||||
*n = (d << 24) | (c << 16) | (b << 8) | a;
|
||||
}
|
||||
|
||||
static uint32_t f(uint32_t x)
|
||||
{
|
||||
uint32_t h = S[0][x >> 24] + S[1][x >> 16 & 0xff];
|
||||
return (h ^ S[2][x >> 8 & 0xff]) + S[3][x & 0xff];
|
||||
}
|
||||
|
||||
static void encrypt(uint32_t *L, uint32_t *R)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 16; i += 2) {
|
||||
*L ^= P[i];
|
||||
*R ^= f(*L);
|
||||
*R ^= P[i + 1];
|
||||
*L ^= f(*R);
|
||||
}
|
||||
*L ^= P[16];
|
||||
*R ^= P[17];
|
||||
swap(L, R);
|
||||
}
|
||||
|
||||
static void decrypt(uint32_t *L, uint32_t *R)
|
||||
{
|
||||
int i;
|
||||
for (i = 16; i > 0; i -= 2) {
|
||||
*L ^= P[i + 1];
|
||||
*R ^= f(*L);
|
||||
*R ^= P[i];
|
||||
*L ^= f(*R);
|
||||
}
|
||||
*L ^= P[1];
|
||||
*R ^= P[0];
|
||||
swap(L, R);
|
||||
}
|
||||
|
||||
static void key_schedule(uint32_t *key, int keylen)
|
||||
{
|
||||
int i, j;
|
||||
uint32_t L = 0, R = 0;
|
||||
memcpy(P, P_orig, sizeof(P));
|
||||
memcpy(S, S_orig, sizeof(S));
|
||||
for (i = 0; i < 18; i++) {
|
||||
P[i] ^= key[i % keylen];
|
||||
}
|
||||
for (i = 0; i < 18; i+=2) {
|
||||
encrypt(&L, &R);
|
||||
P[i] = L;
|
||||
P[i + 1] = R;
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 256; j += 2) {
|
||||
encrypt(&L, &R);
|
||||
S[i][j] = L;
|
||||
S[i][j + 1] = R;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void blowfish_setkey(uint8_t *key, int keylen)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < keylen / 4; i++) {
|
||||
swapendian((uint32_t *)(key + i * 4));
|
||||
}
|
||||
key_schedule((uint32_t *)key, keylen / 4);
|
||||
}
|
||||
|
||||
void blowfish_encrypt(uint8_t *data, int datalen)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < datalen / 4; i++) {
|
||||
swapendian((uint32_t *)(data + i * 4));
|
||||
}
|
||||
for (i = 0; i < datalen / 8; i++) {
|
||||
encrypt((uint32_t *)(data + i * 8), (uint32_t *)(data + i * 8 + 4));
|
||||
}
|
||||
for (i = 0; i < datalen / 4; i++) {
|
||||
swapendian((uint32_t *)(data + i * 4));
|
||||
}
|
||||
}
|
||||
|
||||
void blowfish_decrypt(uint8_t *data, int datalen)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < datalen / 4; i++) {
|
||||
swapendian((uint32_t *)(data + i * 4));
|
||||
}
|
||||
for (i = 0; i < datalen / 8; i++) {
|
||||
decrypt((uint32_t *)(data + i * 8), (uint32_t *)(data + i * 8 + 4));
|
||||
}
|
||||
for (i = 0; i < datalen / 4; i++) {
|
||||
swapendian((uint32_t *)(data + i * 4));
|
||||
}
|
||||
}
|
32
blowfish.h
32
blowfish.h
@ -1,32 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Pavol Rusnak
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __BLOWFISH_H__
|
||||
#define __BLOWFISH_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void blowfish_setkey(uint8_t *key, int keylen);
|
||||
void blowfish_encrypt(uint8_t *data, int datalen);
|
||||
void blowfish_decrypt(uint8_t *data, int datalen);
|
||||
|
||||
#endif
|
92
tests.c
92
tests.c
@ -26,7 +26,7 @@
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "blowfish.h"
|
||||
#include "aes.h"
|
||||
#include "bignum.h"
|
||||
#include "bip32.h"
|
||||
#include "ecdsa.h"
|
||||
@ -262,74 +262,31 @@ START_TEST(test_verify_speed)
|
||||
}
|
||||
END_TEST
|
||||
|
||||
#define test_bfsh(KEY, CLEAR, CIPHER) do { \
|
||||
memcpy(key, fromhex(KEY), strlen(KEY)/2); \
|
||||
memcpy(data, fromhex(CLEAR), strlen(CLEAR)/2); \
|
||||
blowfish_setkey(key, strlen(KEY)/2); \
|
||||
blowfish_encrypt(data, strlen(CLEAR)/2); \
|
||||
ck_assert_mem_eq(data, fromhex(CIPHER), strlen(CIPHER)/2); \
|
||||
#define test_aes(KEY, BLKLEN, IN, OUT) do { \
|
||||
SHA256_Raw((uint8_t *)KEY, strlen(KEY), key); \
|
||||
aes_blk_len(BLKLEN, &ctx); \
|
||||
aes_enc_key(key, 32, &ctx); \
|
||||
memcpy(in, fromhex(IN), BLKLEN); \
|
||||
aes_enc_blk(in, out, &ctx); \
|
||||
ck_assert_mem_eq(out, fromhex(OUT), BLKLEN); \
|
||||
} while (0)
|
||||
|
||||
// test vectors from https://www.schneier.com/code/vectors.txt
|
||||
START_TEST(test_blowfish_1)
|
||||
START_TEST(test_rijndael)
|
||||
{
|
||||
uint8_t key[8];
|
||||
uint8_t data[8];
|
||||
test_bfsh("0000000000000000", "0000000000000000", "4ef997456198dd78");
|
||||
test_bfsh("ffffffffffffffff", "ffffffffffffffff", "51866fd5b85ecb8a");
|
||||
test_bfsh("3000000000000000", "1000000000000001", "7d856f9a613063f2");
|
||||
test_bfsh("1111111111111111", "1111111111111111", "2466dd878b963c9d");
|
||||
test_bfsh("0123456789abcdef", "1111111111111111", "61f9c3802281b096");
|
||||
test_bfsh("1111111111111111", "0123456789abcdef", "7d0cc630afda1ec7");
|
||||
test_bfsh("0000000000000000", "0000000000000000", "4ef997456198dd78");
|
||||
test_bfsh("fedcba9876543210", "0123456789abcdef", "0aceab0fc6a0a28d");
|
||||
test_bfsh("7ca110454a1a6e57", "01a1d6d039776742", "59c68245eb05282b");
|
||||
test_bfsh("0131d9619dc1376e", "5cd54ca83def57da", "b1b8cc0b250f09a0");
|
||||
test_bfsh("07a1133e4a0b2686", "0248d43806f67172", "1730e5778bea1da4");
|
||||
test_bfsh("3849674c2602319e", "51454b582ddf440a", "a25e7856cf2651eb");
|
||||
test_bfsh("04b915ba43feb5b6", "42fd443059577fa2", "353882b109ce8f1a");
|
||||
test_bfsh("0113b970fd34f2ce", "059b5e0851cf143a", "48f4d0884c379918");
|
||||
test_bfsh("0170f175468fb5e6", "0756d8e0774761d2", "432193b78951fc98");
|
||||
test_bfsh("43297fad38e373fe", "762514b829bf486a", "13f04154d69d1ae5");
|
||||
test_bfsh("07a7137045da2a16", "3bdd119049372802", "2eedda93ffd39c79");
|
||||
test_bfsh("04689104c2fd3b2f", "26955f6835af609a", "d887e0393c2da6e3");
|
||||
test_bfsh("37d06bb516cb7546", "164d5e404f275232", "5f99d04f5b163969");
|
||||
test_bfsh("1f08260d1ac2465e", "6b056e18759f5cca", "4a057a3b24d3977b");
|
||||
test_bfsh("584023641aba6176", "004bd6ef09176062", "452031c1e4fada8e");
|
||||
test_bfsh("025816164629b007", "480d39006ee762f2", "7555ae39f59b87bd");
|
||||
test_bfsh("49793ebc79b3258f", "437540c8698f3cfa", "53c55f9cb49fc019");
|
||||
test_bfsh("4fb05e1515ab73a7", "072d43a077075292", "7a8e7bfa937e89a3");
|
||||
test_bfsh("49e95d6d4ca229bf", "02fe55778117f12a", "cf9c5d7a4986adb5");
|
||||
test_bfsh("018310dc409b26d6", "1d9d5c5018f728c2", "d1abb290658bc778");
|
||||
test_bfsh("1c587f1c13924fef", "305532286d6f295a", "55cb3774d13ef201");
|
||||
test_bfsh("0101010101010101", "0123456789abcdef", "fa34ec4847b268b2");
|
||||
test_bfsh("1f1f1f1f0e0e0e0e", "0123456789abcdef", "a790795108ea3cae");
|
||||
test_bfsh("e0fee0fef1fef1fe", "0123456789abcdef", "c39e072d9fac631d");
|
||||
test_bfsh("0000000000000000", "ffffffffffffffff", "014933e0cdaff6e4");
|
||||
test_bfsh("ffffffffffffffff", "0000000000000000", "f21e9a77b71c49bc");
|
||||
test_bfsh("0123456789abcdef", "0000000000000000", "245946885754369a");
|
||||
test_bfsh("fedcba9876543210", "ffffffffffffffff", "6b5c5a9c5d9e0a5a");
|
||||
}
|
||||
END_TEST
|
||||
aes_ctx ctx;
|
||||
uint8_t key[32], in[32], out[32];
|
||||
|
||||
// mnemonic test vectors
|
||||
START_TEST(test_blowfish_2)
|
||||
{
|
||||
uint8_t key[24];
|
||||
uint8_t data[24];
|
||||
// 6d6e656d6f6e6963 = "mnemonic"
|
||||
test_bfsh("6d6e656d6f6e6963", "0000000000000000", "e6b5de53efaec3a5");
|
||||
test_bfsh("6d6e656d6f6e6963", "00000000000000000000000000000000", "e6b5de53efaec3a5e6b5de53efaec3a5");
|
||||
test_bfsh("6d6e656d6f6e6963", "000000000000000000000000000000000000000000000000", "e6b5de53efaec3a5e6b5de53efaec3a5e6b5de53efaec3a5");
|
||||
test_bfsh("6d6e656d6f6e6963", "7f7f7f7f7f7f7f7f", "cb21e7cd6313594b");
|
||||
test_bfsh("6d6e656d6f6e6963", "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", "cb21e7cd6313594bcb21e7cd6313594b");
|
||||
test_bfsh("6d6e656d6f6e6963", "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", "cb21e7cd6313594bcb21e7cd6313594bcb21e7cd6313594b");
|
||||
test_bfsh("6d6e656d6f6e6963", "8080808080808080", "8800e1df66298ae6");
|
||||
test_bfsh("6d6e656d6f6e6963", "80808080808080808080808080808080", "8800e1df66298ae68800e1df66298ae6");
|
||||
test_bfsh("6d6e656d6f6e6963", "808080808080808080808080808080808080808080808080", "8800e1df66298ae68800e1df66298ae68800e1df66298ae6");
|
||||
test_bfsh("6d6e656d6f6e6963", "ffffffffffffffff", "4c8be56fcf3de4cf");
|
||||
test_bfsh("6d6e656d6f6e6963", "ffffffffffffffffffffffffffffffff", "4c8be56fcf3de4cf4c8be56fcf3de4cf");
|
||||
test_bfsh("6d6e656d6f6e6963", "ffffffffffffffffffffffffffffffffffffffffffffffff", "4c8be56fcf3de4cf4c8be56fcf3de4cf4c8be56fcf3de4cf");
|
||||
test_aes("mnemonic", 16, "00000000000000000000000000000000", "a3af8b7d326a2d47bd7576012e07d103");
|
||||
test_aes("mnemonic", 24, "000000000000000000000000000000000000000000000000", "7b8704678f263c316ddd1746d8377a4046a99dd9e5687d59");
|
||||
test_aes("mnemonic", 32, "0000000000000000000000000000000000000000000000000000000000000000", "7c0575db9badc9960441c6b8dcbd5ebdfec522ede5309904b7088d0e77c2bcef");
|
||||
|
||||
test_aes("mnemonic", 16, "686f6a6461686f6a6461686f6a6461686f6a6461", "9c3bb85af2122cc2df449033338beb56");
|
||||
test_aes("mnemonic", 24, "686f6a6461686f6a6461686f6a6461686f6a6461686f6a64", "0d7009c589869eaa1d7398bffc7660cce32207a520d6cafe");
|
||||
test_aes("mnemonic", 32, "686f6a6461686f6a6461686f6a6461686f6a6461686f6a6461686f6a6461686f", "b1a4d05e3827611c5986ea4c207679a6934f20767434218029c4b3b7a53806a3");
|
||||
|
||||
test_aes("mnemonic", 16, "ffffffffffffffffffffffffffffffff", "e720f4474b7dabe382eec0529e2b1128");
|
||||
test_aes("mnemonic", 24, "ffffffffffffffffffffffffffffffffffffffffffffffff", "14dfe4c7a93e14616dce6c793110baee0b8bb404f3bec6c5");
|
||||
test_aes("mnemonic", 32, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ccf498fd9a57f872a4d274549fab474cbacdbd9d935ca31b06e3025526a704fb");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
@ -353,9 +310,8 @@ Suite *test_suite(void)
|
||||
tcase_add_test(tc, test_verify_speed);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("blowfish");
|
||||
tcase_add_test(tc, test_blowfish_1);
|
||||
tcase_add_test(tc, test_blowfish_2);
|
||||
tc = tcase_create("rijndael");
|
||||
tcase_add_test(tc, test_rijndael);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
|
Loading…
Reference in New Issue
Block a user