MDS v2 structures and decode/crypto utilities from Marisa-Chan's repository in preparation for MDS v2/MDX support implementation.

This commit is contained in:
OBattler
2026-01-18 03:56:57 +01:00
parent 605a1443de
commit 51effd0453
67 changed files with 21470 additions and 8 deletions

View File

@@ -175,6 +175,20 @@ typedef struct
uint32_t trk_blocks_offs;
} mds_sess_block_t; /* 24 bytes */
/* MDF v2.01 session block. */
typedef struct
{
int64_t sess_start;
uint16_t sess_id;
uint8_t all_blocks_num;
uint8_t non_track_blocks_num;
uint16_t first_trk;
uint16_t last_trk;
uint32_t pad;
uint32_t trk_blocks_offs;
int64_t sess_end;
} mds_v2_sess_block_t; /* 24 bytes */
typedef struct
{
uint8_t trk_mode;
@@ -220,6 +234,17 @@ typedef struct
uint32_t pad0;
} mds_footer_t; /* 16 bytes */
/* MDF v2.01 track footer block. */
typedef struct
{
uint32_t fn_offs;
uint32_t pad; /* Always wide */
uint32_t pad0;
uint32_t pad1;
uint64_t trk_sectors;
uint64_t pad2;
} mds_v2_footer_t; /* 16 bytes */
typedef struct
{
uint32_t type;
@@ -1949,6 +1974,7 @@ image_load_mds(cd_image_t *img, const char *mdsfile)
track_index_t *ci = NULL;
track_file_t *tf = NULL;
int is_viso = 0;
int version = 1;
int last_t = -1;
int error;
char pathname[MAX_FILENAME_LENGTH];
@@ -1956,9 +1982,11 @@ image_load_mds(cd_image_t *img, const char *mdsfile)
mds_hdr_t mds_hdr = { 0 };
mds_sess_block_t mds_sess_block = { 0 };
mds_v2_sess_block_t mds_v2_sess_block = { 0 };
mds_trk_block_t mds_trk_block = { 0 };
mds_trk_ex_block_t mds_trk_ex_block = { 0 };
mds_footer_t mds_footer = { 0 };
mds_v2_footer_t mds_v2_footer = { 0 };
mds_dpm_block_t mds_dpm_block = { 0 };
uint32_t mds_dpm_blocks_num = 0x00000000;
uint32_t mds_dpm_block_offs = 0x00000000;
@@ -2006,6 +2034,7 @@ image_load_mds(cd_image_t *img, const char *mdsfile)
#else
warning("\"%s\" is a Daemon Tools encrypted MDS which is not supported\n", mdsfile);
#endif
version = 2;
fclose(fp);
return 0;
}
@@ -2083,9 +2112,18 @@ image_load_mds(cd_image_t *img, const char *mdsfile)
}
for (int s = 0; s < mds_hdr.sess_num; s++) {
fseek(fp, mds_hdr.sess_blocks_offs + (s * sizeof(mds_sess_block_t)), SEEK_SET);
if (fread(&mds_sess_block, 1, sizeof(mds_sess_block_t), fp) != sizeof(mds_sess_block_t))
return 0;
if (version == 2) {
fseek(fp, mds_hdr.sess_blocks_offs + (s * sizeof(mds_v2_sess_block_t)), SEEK_SET);
if (fread(&mds_v2_sess_block, 1, sizeof(mds_v2_sess_block_t), fp) != sizeof(mds_v2_sess_block_t))
return 0;
memcpy(&mds_sess_block, &mds_v2_sess_block, sizeof(mds_sess_block_t));
mds_sess_block.sess_start = (int32_t) mds_v2_sess_block.sess_start;
mds_sess_block.sess_end = (int32_t) mds_v2_sess_block.sess_end;
} else {
fseek(fp, mds_hdr.sess_blocks_offs + (s * sizeof(mds_sess_block_t)), SEEK_SET);
if (fread(&mds_sess_block, 1, sizeof(mds_sess_block_t), fp) != sizeof(mds_sess_block_t))
return 0;
}
for (int t = 0; t < mds_sess_block.all_blocks_num; t++) {
fseek(fp, mds_sess_block.trk_blocks_offs + (t * sizeof(mds_trk_block_t)), SEEK_SET);
@@ -2127,9 +2165,17 @@ image_load_mds(cd_image_t *img, const char *mdsfile)
uint32_t astart2 = mds_trk_block.start_sect + mds_trk_ex_block.trk_sectors;
if (mds_trk_block.footer_offs != 0ULL) for (uint32_t ff = 0; ff < mds_trk_block.files_num; ff++) {
fseek(fp, mds_trk_block.footer_offs + (ff * sizeof(mds_footer_t)), SEEK_SET);
if (fread(&mds_footer, 1, sizeof(mds_footer_t), fp) != sizeof(mds_footer_t))
return 0;
if (version == 2) {
fseek(fp, mds_trk_block.footer_offs + (ff * sizeof(mds_v2_footer_t)), SEEK_SET);
if (fread(&mds_v2_footer, 1, sizeof(mds_v2_footer_t), fp) != sizeof(mds_v2_footer_t))
return 0;
memcpy(&mds_footer, &mds_v2_footer, sizeof(mds_footer));
mds_footer.fn_is_wide = 1;
} else {
fseek(fp, mds_trk_block.footer_offs + (ff * sizeof(mds_footer_t)), SEEK_SET);
if (fread(&mds_footer, 1, sizeof(mds_footer_t), fp) != sizeof(mds_footer_t))
return 0;
}
uint16_t wfn[2048] = { 0 };
char fn[2048] = { 0 };
@@ -2149,7 +2195,10 @@ image_load_mds(cd_image_t *img, const char *mdsfile)
break;
}
if (!stricmp(fn, "*.mdf")) {
if (strlen(fn) == 0)
/* This is in MDX files - the file name string is empty. */
strcpy(fn, mdsfile);
else if (!stricmp(fn, "*.mdf")) {
strcpy(fn, mdsfile);
fn[strlen(mdsfile) - 3] = 'm';
fn[strlen(mdsfile) - 2] = 'd';
@@ -2681,7 +2730,8 @@ image_open(cdrom_t *dev, const char *path)
if (img != NULL) {
int ret;
const int is_cue = ((ext == 4) && !stricmp(path + strlen(path) - ext + 1, "CUE"));
const int is_mds = ((ext == 4) && !stricmp(path + strlen(path) - ext + 1, "MDS"));
const int is_mds = ((ext == 4) && (!stricmp(path + strlen(path) - ext + 1, "MDS") ||
!stricmp(path + strlen(path) - ext + 1, "MDX")));
char n[1024] = { 0 };
sprintf(n, "CD-ROM %i Image", dev->id + 1);

View File

@@ -16,12 +16,48 @@
#
add_library(utils OBJECT
# Core
cJSON.c
crc.c
crc32.c
decode.c
edc.c
fifo.c
fifo8.c
ini.c
log.c
random.c
utils.c
# Common
common/crc.c
common/crypto.c
common/endian.c
common/gfmul.c
common/pkcs5.c
common/xts.c
# Crypto
crypto/aescrypt.c
crypto/aeskey.c
crypto/aessmall.c
crypto/aestab.c
crypto/bf_ecb.c
crypto/bf_enc.c
crypto/bf_skey.c
crypto/c_ecb.c
crypto/c_enc.c
crypto/c_skey.c
crypto/des.c
crypto/des_enc.c
crypto/ecb3_enc.c
crypto/rmd160.c
crypto/serpent.c
crypto/set_key.c
crypto/sha1.c
crypto/sha2.c
crypto/twofish.c
crypto/whirlpool.c
)

133
src/utils/common/crc.c Normal file
View File

@@ -0,0 +1,133 @@
/*
Legal Notice: Some portions of the source code contained in this file were
derived from the source code of Encryption for the Masses 2.02a, which is
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
Agreement for Encryption for the Masses'. Modifications and additions to
the original source code (contained in this file) and all other portions of
this file are Copyright (c) 2003-2008 TrueCrypt Foundation and are governed
by the TrueCrypt License 2.4 the full text of which is contained in the
file License.txt included in TrueCrypt binary and source code distribution
packages. */
#include "tcdefs.h"
#include "crc.h"
#include "../common/endian.h"
#ifndef TC_MINIMIZE_CODE_SIZE
/* CRC polynomial 0x04c11db7 */
uint32_t crc_32_tab[]=
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
uint32_t GetCrc32 (unsigned char *data, int length)
{
uint32_t CRC = 0xffffffff;
while (length--)
{
CRC = (CRC >> 8) ^ crc_32_tab[ (CRC ^ *data++) & 0xFF ];
}
return CRC ^ 0xffffffff;
}
uint32_t crc32int (uint32_t *data)
{
unsigned char *d = (unsigned char *) data;
uint32_t CRC = 0xffffffff;
CRC = (CRC >> 8) ^ crc_32_tab[ (CRC ^ *d++) & 0xFF ];
CRC = (CRC >> 8) ^ crc_32_tab[ (CRC ^ *d++) & 0xFF ];
CRC = (CRC >> 8) ^ crc_32_tab[ (CRC ^ *d++) & 0xFF ];
return (CRC >> 8) ^ crc_32_tab[ (CRC ^ *d) & 0xFF ] ^ 0xffffffff;
}
#if BYTE_ORDER == LITTLE_ENDIAN
# define CRC_SELFTEST 0x6fcf9e13
#else
# define CRC_SELFTEST 0xca87914d
#endif
int crc32_selftests (void)
{
int i;
uint32_t crc = 0xffffffff;
int bSuccess = 0;
for (i = 0; i < (int)sizeof(crc_32_tab); i++)
crc = UPDC32 (((unsigned char *) crc_32_tab)[i], crc);
bSuccess = CRC_SELFTEST == (crc ^ 0xffffffff);
bSuccess &= GetCrc32 ((unsigned char *)crc_32_tab, sizeof crc_32_tab) == CRC_SELFTEST;
return bSuccess;
}
#else // TC_MINIMIZE_CODE_SIZE
uint32_t GetCrc32 (unsigned char *data, int length)
{
uint32_t r = 0xFFFFFFFFUL;
int i, b;
for (i = 0; i < length; ++i)
{
r ^= data[i];
for (b = 0; b < 8; ++b)
{
if ((unsigned __int8) r & 1)
r = (r >> 1) ^ 0xEDB88320UL;
else
r >>= 1;
}
}
return r ^ 0xFFFFFFFFUL;
}
int crc32_selftests ()
{
unsigned __int8 testData[32];
unsigned __int8 i;
for (i = 0; i < sizeof (testData); ++i)
testData[i] = i;
return GetCrc32 (testData, sizeof (testData)) == 0x91267E8AUL;
}
#endif // TC_MINIMIZE_CODE_SIZE

37
src/utils/common/crc.h Normal file
View File

@@ -0,0 +1,37 @@
/*
Legal Notice: Some portions of the source code contained in this file were
derived from the source code of Encryption for the Masses 2.02a, which is
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
Agreement for Encryption for the Masses'. Modifications and additions to
the original source code (contained in this file) and all other portions of
this file are Copyright (c) 2003-2008 TrueCrypt Foundation and are governed
by the TrueCrypt License 2.4 the full text of which is contained in the
file License.txt included in TrueCrypt binary and source code distribution
packages. */
#ifndef TC_HEADER_CRC
#define TC_HEADER_CRC
#include <inttypes.h>
#include "tcdefs.h"
#if defined(__cplusplus)
extern "C"
{
#endif
#define UPDC32(octet, crc)\
(uint32_t)((crc_32_tab[(((uint32_t)(crc)) ^ ((unsigned char)(octet))) & 0xff] ^ (((uint32_t)(crc)) >> 8)))
uint32_t GetCrc32 (unsigned char *data, int length);
uint32_t crc32int (uint32_t *data);
int crc32_selftests (void);
extern uint32_t crc_32_tab[];
#if defined(__cplusplus)
}
#endif
#endif // TC_HEADER_CRC

1653
src/utils/common/crypto.c Normal file

File diff suppressed because it is too large Load Diff

304
src/utils/common/crypto.h Normal file
View File

@@ -0,0 +1,304 @@
/*
Legal Notice: Some portions of the source code contained in this file were
derived from the source code of Encryption for the Masses 2.02a, which is
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
Agreement for Encryption for the Masses'. Modifications and additions to
the original source code (contained in this file) and all other portions of
this file are Copyright (c) 2003-2008 TrueCrypt Foundation and are governed
by the TrueCrypt License 2.4 the full text of which is contained in the
file License.txt included in TrueCrypt binary and source code distribution
packages. */
/* Update the following when adding a new cipher or EA:
Crypto.h:
ID #define
MAX_EXPANDED_KEY #define
Crypto.c:
Ciphers[]
EncryptionAlgorithms[]
CipherInit()
EncipherBlock()
DecipherBlock()
*/
#ifndef CRYPTO_H
#define CRYPTO_H
#include <inttypes.h>
#include "tcdefs.h"
#ifdef __cplusplus
extern "C" {
#endif
// Encryption data unit size, which may differ from the sector size and must always be 512
#define ENCRYPTION_DATA_UNIT_SIZE 512
// Size of the salt (in bytes)
#define PKCS5_SALT_SIZE 64
// Size of the volume header area containing concatenated master key(s) and secondary key(s) (XTS mode)
#define MASTER_KEYDATA_SIZE 256
// Size of the deprecated volume header item containing either an IV seed (CBC mode) or tweak key (LRW mode)
#define LEGACY_VOL_IV_SIZE 32
// Volume header byte offsets
#define HEADER_SALT_OFFSET 0
#define HEADER_ENCRYPTED_DATA_OFFSET PKCS5_SALT_SIZE
#define HEADER_MASTER_KEYDATA_OFFSET 256
// Volume header sizes
#define HEADER_SIZE 512
#define HEADER_ENCRYPTED_DATA_SIZE (HEADER_SIZE - HEADER_ENCRYPTED_DATA_OFFSET)
/* The offset, in bytes, of the hidden volume header position from the end of the file (a positive value).
The extra offset (SECTOR_SIZE * 2) was added because FAT file system fills the last sector with zeroes
(marked as free; observed when quick format was performed using the OS format tool). One extra sector was
added to the offset for future expandability (should the header size increase, or should header backup be
introduced). */
#define HIDDEN_VOL_HEADER_OFFSET (HEADER_SIZE + SECTOR_SIZE * 2)
// The first PRF to try when mounting
#define FIRST_PRF_ID 1
// Hash algorithms (pseudorandom functions).
enum
{
RIPEMD160 = FIRST_PRF_ID,
SHA1,
WHIRLPOOL,
SHA512,
HASH_ENUM_END_ID
};
// The last PRF to try when mounting and also the number of implemented PRFs
#define LAST_PRF_ID (HASH_ENUM_END_ID - 1)
#define RIPEMD160_BLOCKSIZE 64
#define RIPEMD160_DIGESTSIZE 20
#define SHA1_BLOCKSIZE 64
#define SHA1_DIGESTSIZE 20
#define SHA512_BLOCKSIZE 128
#define SHA512_DIGESTSIZE 64
#define WHIRLPOOL_BLOCKSIZE 64
#define WHIRLPOOL_DIGESTSIZE 64
#define MAX_DIGESTSIZE WHIRLPOOL_DIGESTSIZE
#define DEFAULT_HASH_ALGORITHM FIRST_PRF_ID
#define DEFAULT_HASH_ALGORITHM_BOOT RIPEMD160
// The mode of operation used for newly created volumes and first to try when mounting
#define FIRST_MODE_OF_OPERATION_ID 1
// Modes of operation
enum
{
/* If you add/remove a mode, update the following: GetMaxPkcs5OutSize(), EAInitMode() */
XTS = FIRST_MODE_OF_OPERATION_ID,
LRW, // Deprecated/legacy
CBC, // Deprecated/legacy
OUTER_CBC, // Deprecated/legacy
INNER_CBC, // Deprecated/legacy
MODE_ENUM_END_ID
};
// The last mode of operation to try when mounting and also the number of implemented modes
#define LAST_MODE_OF_OPERATION (MODE_ENUM_END_ID - 1)
// Ciphertext/plaintext block size for XTS mode (in bytes)
#define BYTES_PER_XTS_BLOCK 16
// Number of ciphertext/plaintext blocks per XTS data unit
#define BLOCKS_PER_XTS_DATA_UNIT (ENCRYPTION_DATA_UNIT_SIZE / BYTES_PER_XTS_BLOCK)
// Cipher IDs
enum
{
NONE = 0,
AES256,
AES192,
AES128,
BLOWFISH, // Deprecated/legacy
CAST, // Deprecated/legacy
SERPENT,
TRIPLEDES, // Deprecated/legacy
TWOFISH,
DES56 // Deprecated/legacy (used only by Triple DES)
};
typedef struct
{
int Id; // Cipher ID
char *Name; // Name
int BlockSize; // Block size (bytes)
int KeySize; // Key size (bytes)
int KeyScheduleSize; // Scheduled key size (bytes)
} Cipher;
typedef struct
{
int Ciphers[4]; // Null terminated array of ciphers used by encryption algorithm
int Modes[LAST_MODE_OF_OPERATION + 1]; // Null terminated array of modes of operation
int FormatEnabled;
} EncryptionAlgorithm;
typedef struct
{
int Id; // Hash ID
char *Name; // Name
int Deprecated;
int SystemEncryption; // Available for system encryption
} Hash;
// Maxium length of scheduled key
#define AES_KS (sizeof(aes_encrypt_ctx) + sizeof(aes_decrypt_ctx))
#define SERPENT_KS (140 * 4)
#define MAX_EXPANDED_KEY (AES_KS + SERPENT_KS + TWOFISH_KS)
#define PRAND_DISK_WIPE_PASSES 200
#if !defined (TC_WINDOWS_BOOT) || defined (TC_WINDOWS_BOOT_AES)
# include "../crypto/aes.h"
#else
# include "../crypto/aesSmall.h"
#endif
#include "../crypto/blowfish.h"
#include "../crypto/cast.h"
#include "../crypto/des.h"
#include "../crypto/serpent.h"
#include "../crypto/twofish.h"
#include "../crypto/rmd160.h"
# include "../crypto/sha1.h"
# include "../crypto/sha2.h"
# include "../crypto/whirlpool.h"
#include "gfmul.h"
#include "password.h"
typedef struct keyInfo_t
{
int noIterations; /* Number of times to iterate (PKCS-5) */
int keyLength; /* Length of the key */
int8_t userKey[MAX_PASSWORD]; /* Password (to which keyfiles may have been applied). WITHOUT +1 for the null terminator. */
int8_t salt[PKCS5_SALT_SIZE]; /* PKCS-5 salt */
int8_t master_keydata[MASTER_KEYDATA_SIZE]; /* Concatenated master primary and secondary key(s) (XTS mode). For LRW (deprecated/legacy), it contains the tweak key before the master key(s). For CBC (deprecated/legacy), it contains the IV seed before the master key(s). */
} KEY_INFO, *PKEY_INFO;
typedef struct CRYPTO_INFO_t
{
int ea; /* Encryption algorithm ID */
int mode; /* Mode of operation (e.g., XTS) */
uint8_t ks[MAX_EXPANDED_KEY]; /* Primary key schedule (if it is a cascade, it conatins multiple concatenated keys) */
uint8_t ks2[MAX_EXPANDED_KEY]; /* Secondary key schedule (if cascade, multiple concatenated) for XTS mode. */
GfCtx gf_ctx;
uint8_t master_keydata[MASTER_KEYDATA_SIZE]; /* This holds the volume header area containing concatenated master key(s) and secondary key(s) (XTS mode). For LRW (deprecated/legacy), it contains the tweak key before the master key(s). For CBC (deprecated/legacy), it contains the IV seed before the master key(s). */
uint8_t k2[MASTER_KEYDATA_SIZE]; /* For XTS, this contains the secondary key (if cascade, multiple concatenated). For LRW (deprecated/legacy), it contains the tweak key. For CBC (deprecated/legacy), it contains the IV seed. */
uint8_t salt[PKCS5_SALT_SIZE];
int noIterations;
int pkcs5;
// uint64_t volume_creation_time;
// uint64_t header_creation_time;
// // Hidden volume status & parameters
// int hiddenVolume; // Indicates whether the volume is mounted/mountable as hidden volume
// int bProtectHiddenVolume; // Indicates whether the volume contains a hidden volume to be protected against overwriting
// int bHiddenVolProtectionAction; // TRUE if a write operation has been denied by the driver in order to prevent the hidden volume from being overwritten (set to FALSE upon volume mount).
// uint64_t hiddenVolumeSize; // Size of the hidden volume excluding the header (in bytes). Set to 0 for standard volumes.
// uint64_t hiddenVolumeOffset; // Absolute position, in bytes, of the first hidden volume data sector within the host volume (provided that there is a hidden volume within). This must be set for all hidden volumes; in case of a normal volume, this variable is only used when protecting a hidden volume within it.
// uint64_t volDataAreaOffset; // Absolute position, in bytes, of the first data sector of the volume.
// int bPartitionInInactiveSysEncScope; // If TRUE, the volume is a partition located on an encrypted system drive and mounted without pre-boot authentication.
// UINT64_STRUCT FirstDataUnitNo; // First data unit number of the volume. This is 0 for file-hosted and non-system partition-hosted volumes. For partitions within key scope of system encryption this reflects real physical offset within the device (this is used e.g. when such a partition is mounted as a regular volume without pre-boot authentication).
// UINT64_STRUCT VolumeSize;
// UINT64_STRUCT EncryptedAreaStart;
// UINT64_STRUCT EncryptedAreaLength;
} CRYPTO_INFO, *PCRYPTO_INFO;
PCRYPTO_INFO crypto_open (void);
void crypto_loadkey (PKEY_INFO keyInfo, char *lpszUserKey, int nUserKeyLen);
void crypto_close (PCRYPTO_INFO cryptoInfo);
int CipherGetBlockSize (int cipher);
int CipherGetKeySize (int cipher);
int CipherGetKeyScheduleSize (int cipher);
char * CipherGetName (int cipher);
int CipherInit (int cipher, unsigned char *key, unsigned char *ks);
int EAInit (int ea, unsigned char *key, unsigned char *ks);
int EAInitMode (PCRYPTO_INFO ci);
void EncipherBlock(int cipher, void *data, void *ks);
void DecipherBlock(int cipher, void *data, void *ks);
int EAGetFirst (void);
int EAGetCount (void);
int EAGetNext (int previousEA);
char * EAGetName (char *buf, int ea);
int EAGetByName (char *name);
int EAGetKeySize (int ea);
int EAGetFirstMode (int ea);
int EAGetNextMode (int ea, int previousModeId);
char * EAGetModeName (int ea, int mode, int capitalLetters);
int EAGetKeyScheduleSize (int ea);
int EAGetLargestKey (void);
int EAGetLargestKeyForMode (int mode);
int EAGetCipherCount (int ea);
int EAGetFirstCipher (int ea);
int EAGetLastCipher (int ea);
int EAGetNextCipher (int ea, int previousCipherId);
int EAGetPreviousCipher (int ea, int previousCipherId);
int EAIsFormatEnabled (int ea);
int EAIsModeSupported (int ea, int testedMode);
char *HashGetName (int hash_algo_id);
int HashIsDeprecated (int hashId);
int GetMaxPkcs5OutSize (void);
//void EncryptDataUnits (uint8_t *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci);
//void DecryptDataUnits (uint8_t *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci);
void EncryptBuffer (uint8_t *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo);
void DecryptBuffer (uint8_t *buf, TC_LARGEST_COMPILER_UINT len, uint32_t secSz, uint64_t secN, uint8_t flags, PCRYPTO_INFO cryptoInfo);
#ifndef TC_NO_COMPILER_INT64
void Xor128 (uint64_t *a, uint64_t *b);
void Xor64 (uint64_t *a, uint64_t *b);
void EncryptBufferLRW128 (uint8_t *buffer, uint64_t length, uint64_t blockIndex, PCRYPTO_INFO cryptoInfo);
void DecryptBufferLRW128 (uint8_t *buffer, uint64_t length, uint64_t blockIndex, PCRYPTO_INFO cryptoInfo);
void EncryptBufferLRW64 (uint8_t *buffer, uint64_t length, uint64_t blockIndex, PCRYPTO_INFO cryptoInfo);
void DecryptBufferLRW64 (uint8_t *buffer, uint64_t length, uint64_t blockIndex, PCRYPTO_INFO cryptoInfo);
void InitSectorIVAndWhitening (uint64_t unitNo, int blockSize, uint32_t *iv, uint64_t *ivSeed, uint32_t *whitening);
//uint64_t DataUnit2LRWIndex (uint64_t dataUnit, int blockSize, PCRYPTO_INFO ci);
#endif // #ifndef TC_NO_COMPILER_INT64
#ifdef __cplusplus
}
#endif
#endif /* CRYPTO_H */

57
src/utils/common/endian.c Normal file
View File

@@ -0,0 +1,57 @@
/*
Legal Notice: Some portions of the source code contained in this file were
derived from the source code of Encryption for the Masses 2.02a, which is
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
Agreement for Encryption for the Masses'. Modifications and additions to
the original source code (contained in this file) and all other portions of
this file are Copyright (c) 2003-2008 TrueCrypt Foundation and are governed
by the TrueCrypt License 2.4 the full text of which is contained in the
file License.txt included in TrueCrypt binary and source code distribution
packages. */
#include "tcdefs.h"
#include "../common/endian.h"
uint16_t MirrorBytes16 (uint16_t x)
{
return (x << 8) | (x >> 8);
}
uint32_t MirrorBytes32 (uint32_t x)
{
uint32_t n = (uint8_t) x;
n <<= 8; n |= (uint8_t) (x >> 8);
n <<= 8; n |= (uint8_t) (x >> 16);
return (n << 8) | (uint8_t) (x >> 24);
}
#ifndef TC_NO_COMPILER_INT64
uint64_t MirrorBytes64 (uint64_t x)
{
uint64_t n = (uint8_t) x;
n <<= 8; n |= (uint8_t) (x >> 8);
n <<= 8; n |= (uint8_t) (x >> 16);
n <<= 8; n |= (uint8_t) (x >> 24);
n <<= 8; n |= (uint8_t) (x >> 32);
n <<= 8; n |= (uint8_t) (x >> 40);
n <<= 8; n |= (uint8_t) (x >> 48);
return (n << 8) | (uint8_t) (x >> 56);
}
#endif
void
LongReverse (uint32_t *buffer, unsigned byteCount)
{
uint32_t value;
byteCount /= sizeof (uint32_t);
while (byteCount--)
{
value = *buffer;
value = ((value & 0xFF00FF00L) >> 8) | \
((value & 0x00FF00FFL) << 8);
*buffer++ = (value << 16) | (value >> 16);
}
}

138
src/utils/common/endian.h Normal file
View File

@@ -0,0 +1,138 @@
/*
Legal Notice: Some portions of the source code contained in this file were
derived from the source code of Encryption for the Masses 2.02a, which is
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
Agreement for Encryption for the Masses'. Modifications and additions to
the original source code (contained in this file) and all other portions of
this file are Copyright (c) 2003-2008 TrueCrypt Foundation and are governed
by the TrueCrypt License 2.4 the full text of which is contained in the
file License.txt included in TrueCrypt binary and source code distribution
packages. */
#ifndef TC_ENDIAN_H
#define TC_ENDIAN_H
#include <inttypes.h>
#if defined(__cplusplus)
extern "C"
{
#endif
#ifdef _WIN32
# ifndef LITTLE_ENDIAN
# define LITTLE_ENDIAN 1234
# endif
# ifndef BYTE_ORDER
# define BYTE_ORDER LITTLE_ENDIAN
# endif
#elif !defined(BYTE_ORDER)
# ifdef TC_MACOSX
# include <machine/endian.h>
# elif defined (TC_BSD)
# include <sys/endian.h>
# else
# include <endian.h>
# endif
# ifndef BYTE_ORDER
# ifndef __BYTE_ORDER
# error Byte order cannot be determined (BYTE_ORDER undefined)
# endif
# define BYTE_ORDER __BYTE_ORDER
# endif
# ifndef LITTLE_ENDIAN
# define LITTLE_ENDIAN __LITTLE_ENDIAN
# endif
# ifndef BIG_ENDIAN
# define BIG_ENDIAN __BIG_ENDIAN
# endif
#endif // !BYTE_ORDER
/* Macros to read and write 16, 32, and 64-bit quantities in a portable manner.
These functions are implemented as macros rather than true functions as
the need to adjust the memory pointers makes them somewhat painful to call
in user code */
#define mputInt64(memPtr,data) \
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 56 ) & 0xFF ), \
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 48 ) & 0xFF ), \
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 40 ) & 0xFF ), \
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 32 ) & 0xFF ), \
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 24 ) & 0xFF ), \
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 16 ) & 0xFF ), \
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 8 ) & 0xFF ), \
*memPtr++ = ( unsigned char ) ( ( data ) & 0xFF )
#define mputLong(memPtr,data) \
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 24 ) & 0xFF ), \
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 16 ) & 0xFF ), \
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 8 ) & 0xFF ), \
*memPtr++ = ( unsigned char ) ( ( data ) & 0xFF )
#define mputWord(memPtr,data) \
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 8 ) & 0xFF ), \
*memPtr++ = ( unsigned char ) ( ( data ) & 0xFF )
#define mputByte(memPtr,data) \
*memPtr++ = ( unsigned char ) data
#define mputBytes(memPtr,data,len) \
memcpy (memPtr,data,len); \
memPtr += len;
#define mgetInt64(memPtr) \
( memPtr += 8, ( ( unsigned __int64 ) memPtr[ -8 ] << 56 ) | ( ( unsigned __int64 ) memPtr[ -7 ] << 48 ) | \
( ( unsigned __int64 ) memPtr[ -6 ] << 40 ) | ( ( unsigned __int64 ) memPtr[ -5 ] << 32 ) | \
( ( unsigned __int64 ) memPtr[ -4 ] << 24 ) | ( ( unsigned __int64 ) memPtr[ -3 ] << 16 ) | \
( ( unsigned __int64 ) memPtr[ -2 ] << 8 ) | ( unsigned __int64 ) memPtr[ -1 ] )
#define mgetLong(memPtr) \
( memPtr += 4, ( ( unsigned __int32 ) memPtr[ -4 ] << 24 ) | ( ( unsigned __int32 ) memPtr[ -3 ] << 16 ) | \
( ( unsigned __int32 ) memPtr[ -2 ] << 8 ) | ( unsigned __int32 ) memPtr[ -1 ] )
#define mgetWord(memPtr) \
( memPtr += 2, ( unsigned short ) memPtr[ -2 ] << 8 ) | ( ( unsigned short ) memPtr[ -1 ] )
#define mgetByte(memPtr) \
( ( unsigned char ) *memPtr++ )
#if BYTE_ORDER == BIG_ENDIAN
# define LE16(x) MirrorBytes16(x)
# define LE32(x) MirrorBytes32(x)
# define LE64(x) MirrorBytes64(x)
#else
# define LE16(x) (x)
# define LE32(x) (x)
# define LE64(x) (x)
#endif
#if BYTE_ORDER == LITTLE_ENDIAN
# define BE16(x) MirrorBytes16(x)
# define BE32(x) MirrorBytes32(x)
# define BE64(x) MirrorBytes64(x)
#else
# define BE16(x) (x)
# define BE32(x) (x)
# define BE64(x) (x)
#endif
uint16_t MirrorBytes16 (uint16_t x);
uint32_t MirrorBytes32 (uint32_t x);
#ifndef TC_NO_COMPILER_INT64
uint64_t MirrorBytes64 (uint64_t x);
#endif
void LongReverse ( uint32_t *buffer , unsigned byteCount );
#if defined(__cplusplus)
}
#endif
#endif /* TC_ENDIAN_H */

893
src/utils/common/gfmul.c Normal file
View File

@@ -0,0 +1,893 @@
/*
---------------------------------------------------------------------------
Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved.
LICENSE TERMS
The free distribution and use of this software is allowed (with or without
changes) provided that:
1. source code distributions include the above copyright notice, this
list of conditions and the following disclaimer;
2. binary distributions include the above copyright notice, this list
of conditions and the following disclaimer in their documentation;
3. the name of the copyright holder is not used to endorse products
built using this software without specific written permission.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue Date: 31/01/2004
My thanks to John Viega and David McGrew for their support in developing
this code and to David for testing it on a big-endain system.
*/
/*
Portions Copyright (c) 2005 TrueCrypt Foundation
TrueCrypt Foundation made the following changes:
- Added multiplication in the finite field GF(2^128) optimized for
cases involving a 64-bit operand.
- Added multiplication in the finite field GF(2^64).
- Added MSB-first mode.
- Added basic test algorithms.
- Removed GCM.
*/
#include <memory.h>
#include <stdlib.h>
#include <inttypes.h>
#include "gfmul.h"
#include "tcdefs.h"
#include "../common/endian.h"
/* BUFFER_ALIGN32 or BUFFER_ALIGN64 must be defined at this point to */
/* enable faster operation by taking advantage of memory aligned values */
/* NOTE: the BUFFER_ALIGN64 option has not been tested extensively */
#define BUFFER_ALIGN32
#define UNROLL_LOOPS /* define to unroll some loops */
#define IN_LINES /* define to use inline functions */
/* in place of macros */
#define mode(x) GM_##x
#if defined(__cplusplus)
extern "C"
{
#endif
typedef uint32_t mode(32t);
typedef uint64_t mode(64t);
#define BRG_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
#define BRG_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
#if BYTE_ORDER == LITTLE_ENDIAN
# define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
#endif
#if BYTE_ORDER == BIG_ENDIAN
# define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
#endif
#ifdef _MSC_VER
#pragma intrinsic(memcpy)
#define in_line __inline
#else
#define in_line
#endif
#if 0 && defined(_MSC_VER)
#define rotl32 _lrotl
#define rotr32 _lrotr
#else
#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n)))
#endif
#if !defined(bswap_32)
#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00))
#endif
#if (PLATFORM_BYTE_ORDER == BRG_LITTLE_ENDIAN)
#define SWAP_BYTES
#else
#undef SWAP_BYTES
#endif
#if defined(SWAP_BYTES)
#if defined ( IN_LINES )
in_line void bsw_32(void * p, unsigned int n)
{ unsigned int i = n;
while(i--)
((mode(32t)*)p)[i] = bswap_32(((mode(32t)*)p)[i]);
}
#else
#define bsw_32(p,n) \
{ int _i = (n); while(_i--) ((mode(32t)*)p)[_i] = bswap_32(((mode(32t)*)p)[_i]); }
#endif
#else
#define bsw_32(p,n)
#endif
/* These values are used to detect long word alignment in order */
/* to speed up some GCM buffer operations. This facility may */
/* not work on some machines */
#define lp08(x) ((unsigned char*)(x))
#define lp32(x) ((mode(32t)*)(x))
#define lp64(x) ((mode(64t)*)(x))
#define A32_MASK 3
#define A64_MASK 7
#define aligned32(x) (!(((mode(32t))(x)) & A32_MASK))
#define aligned64(x) (!(((mode(32t))(x)) & A64_MASK))
#if defined( BUFFER_ALIGN32 )
#define ADR_MASK A32_MASK
#define aligned aligned32
#define lp lp32
#define lp_inc 4
#if defined( IN_LINES )
in_line void move_block_aligned( void *p, const void *q)
{
lp32(p)[0] = lp32(q)[0], lp32(p)[1] = lp32(q)[1],
lp32(p)[2] = lp32(q)[2], lp32(p)[3] = lp32(q)[3];
}
in_line void move_block_aligned64( void *p, const void *q)
{
lp32(p)[0] = lp32(q)[0], lp32(p)[1] = lp32(q)[1];
}
in_line void xor_block_aligned( void *p, const void *q)
{
lp32(p)[0] ^= lp32(q)[0], lp32(p)[1] ^= lp32(q)[1],
lp32(p)[2] ^= lp32(q)[2], lp32(p)[3] ^= lp32(q)[3];
}
in_line void xor_block_aligned64( void *p, const void *q)
{
lp32(p)[0] ^= lp32(q)[0], lp32(p)[1] ^= lp32(q)[1];
}
#else
#define move_block_aligned(p,q) \
lp32(p)[0] = lp32(q)[0], lp32(p)[1] = lp32(q)[1], \
lp32(p)[2] = lp32(q)[2], lp32(p)[3] = lp32(q)[3]
#define xor_block_aligned(p,q) \
lp32(p)[0] ^= lp32(q)[0], lp32(p)[1] ^= lp32(q)[1], \
lp32(p)[2] ^= lp32(q)[2], lp32(p)[3] ^= lp32(q)[3]
#endif
#elif defined( BUFFER_ALIGN64 )
#define ADR_MASK A64_MASK
#define aligned aligned64
#define lp lp64
#define lp_inc 8
#define move_block_aligned(p,q) \
lp64(p)[0] = lp64(q)[0], lp64(p)[1] = lp64(q)[1]
#define xor_block_aligned(p,q) \
lp64(p)[0] ^= lp64(q)[0], lp64(p)[1] ^= lp64(q)[1]
#else
#define aligned(x) 0
#endif
#define move_block(p,q) memcpy((p), (q), BLOCK_LEN)
#define xor_block(p,q) \
lp08(p)[ 0] ^= lp08(q)[ 0], lp08(p)[ 1] ^= lp08(q)[ 1], \
lp08(p)[ 2] ^= lp08(q)[ 2], lp08(p)[ 3] ^= lp08(q)[ 3], \
lp08(p)[ 4] ^= lp08(q)[ 4], lp08(p)[ 5] ^= lp08(q)[ 5], \
lp08(p)[ 6] ^= lp08(q)[ 6], lp08(p)[ 7] ^= lp08(q)[ 7], \
lp08(p)[ 8] ^= lp08(q)[ 8], lp08(p)[ 9] ^= lp08(q)[ 9], \
lp08(p)[10] ^= lp08(q)[10], lp08(p)[11] ^= lp08(q)[11], \
lp08(p)[12] ^= lp08(q)[12], lp08(p)[13] ^= lp08(q)[13], \
lp08(p)[14] ^= lp08(q)[14], lp08(p)[15] ^= lp08(q)[15]
#define gf_dat(q) {\
q(0x00), q(0x01), q(0x02), q(0x03), q(0x04), q(0x05), q(0x06), q(0x07),\
q(0x08), q(0x09), q(0x0a), q(0x0b), q(0x0c), q(0x0d), q(0x0e), q(0x0f),\
q(0x10), q(0x11), q(0x12), q(0x13), q(0x14), q(0x15), q(0x16), q(0x17),\
q(0x18), q(0x19), q(0x1a), q(0x1b), q(0x1c), q(0x1d), q(0x1e), q(0x1f),\
q(0x20), q(0x21), q(0x22), q(0x23), q(0x24), q(0x25), q(0x26), q(0x27),\
q(0x28), q(0x29), q(0x2a), q(0x2b), q(0x2c), q(0x2d), q(0x2e), q(0x2f),\
q(0x30), q(0x31), q(0x32), q(0x33), q(0x34), q(0x35), q(0x36), q(0x37),\
q(0x38), q(0x39), q(0x3a), q(0x3b), q(0x3c), q(0x3d), q(0x3e), q(0x3f),\
q(0x40), q(0x41), q(0x42), q(0x43), q(0x44), q(0x45), q(0x46), q(0x47),\
q(0x48), q(0x49), q(0x4a), q(0x4b), q(0x4c), q(0x4d), q(0x4e), q(0x4f),\
q(0x50), q(0x51), q(0x52), q(0x53), q(0x54), q(0x55), q(0x56), q(0x57),\
q(0x58), q(0x59), q(0x5a), q(0x5b), q(0x5c), q(0x5d), q(0x5e), q(0x5f),\
q(0x60), q(0x61), q(0x62), q(0x63), q(0x64), q(0x65), q(0x66), q(0x67),\
q(0x68), q(0x69), q(0x6a), q(0x6b), q(0x6c), q(0x6d), q(0x6e), q(0x6f),\
q(0x70), q(0x71), q(0x72), q(0x73), q(0x74), q(0x75), q(0x76), q(0x77),\
q(0x78), q(0x79), q(0x7a), q(0x7b), q(0x7c), q(0x7d), q(0x7e), q(0x7f),\
q(0x80), q(0x81), q(0x82), q(0x83), q(0x84), q(0x85), q(0x86), q(0x87),\
q(0x88), q(0x89), q(0x8a), q(0x8b), q(0x8c), q(0x8d), q(0x8e), q(0x8f),\
q(0x90), q(0x91), q(0x92), q(0x93), q(0x94), q(0x95), q(0x96), q(0x97),\
q(0x98), q(0x99), q(0x9a), q(0x9b), q(0x9c), q(0x9d), q(0x9e), q(0x9f),\
q(0xa0), q(0xa1), q(0xa2), q(0xa3), q(0xa4), q(0xa5), q(0xa6), q(0xa7),\
q(0xa8), q(0xa9), q(0xaa), q(0xab), q(0xac), q(0xad), q(0xae), q(0xaf),\
q(0xb0), q(0xb1), q(0xb2), q(0xb3), q(0xb4), q(0xb5), q(0xb6), q(0xb7),\
q(0xb8), q(0xb9), q(0xba), q(0xbb), q(0xbc), q(0xbd), q(0xbe), q(0xbf),\
q(0xc0), q(0xc1), q(0xc2), q(0xc3), q(0xc4), q(0xc5), q(0xc6), q(0xc7),\
q(0xc8), q(0xc9), q(0xca), q(0xcb), q(0xcc), q(0xcd), q(0xce), q(0xcf),\
q(0xd0), q(0xd1), q(0xd2), q(0xd3), q(0xd4), q(0xd5), q(0xd6), q(0xd7),\
q(0xd8), q(0xd9), q(0xda), q(0xdb), q(0xdc), q(0xdd), q(0xde), q(0xdf),\
q(0xe0), q(0xe1), q(0xe2), q(0xe3), q(0xe4), q(0xe5), q(0xe6), q(0xe7),\
q(0xe8), q(0xe9), q(0xea), q(0xeb), q(0xec), q(0xed), q(0xee), q(0xef),\
q(0xf0), q(0xf1), q(0xf2), q(0xf3), q(0xf4), q(0xf5), q(0xf6), q(0xf7),\
q(0xf8), q(0xf9), q(0xfa), q(0xfb), q(0xfc), q(0xfd), q(0xfe), q(0xff) }
/* given the value i in 0..255 as the byte overflow when a a field */
/* element in GHASH is multipled by x^8, this function will return */
/* the values that are generated in the lo 16-bit word of the field */
/* value by applying the modular polynomial. The values lo_byte and */
/* hi_byte are returned via the macro xp_fun(lo_byte, hi_byte) so */
/* that the values can be assembled into memory as required by a */
/* suitable definition of this macro operating on the table above */
#define xp(i) xp_fun( \
(i & 0x80 ? 0xe1 : 0) ^ (i & 0x40 ? 0x70 : 0) ^ \
(i & 0x20 ? 0x38 : 0) ^ (i & 0x10 ? 0x1c : 0) ^ \
(i & 0x08 ? 0x0e : 0) ^ (i & 0x04 ? 0x07 : 0) ^ \
(i & 0x02 ? 0x03 : 0) ^ (i & 0x01 ? 0x01 : 0), \
(i & 0x80 ? 0x00 : 0) ^ (i & 0x40 ? 0x80 : 0) ^ \
(i & 0x20 ? 0x40 : 0) ^ (i & 0x10 ? 0x20 : 0) ^ \
(i & 0x08 ? 0x10 : 0) ^ (i & 0x04 ? 0x08 : 0) ^ \
(i & 0x02 ? 0x84 : 0) ^ (i & 0x01 ? 0xc2 : 0) )
#define xp64(i) xp_fun( \
(i & 0x80 ? 0xd8 : 0) ^ (i & 0x40 ? 0x6c : 0) ^ \
(i & 0x20 ? 0x36 : 0) ^ (i & 0x10 ? 0x1b : 0) ^ \
(i & 0x08 ? 0x0d : 0) ^ (i & 0x04 ? 0x06 : 0) ^ \
(i & 0x02 ? 0x03 : 0) ^ (i & 0x01 ? 0x01 : 0), \
(i & 0x80 ? 0x00 : 0) ^ (i & 0x40 ? 0x00 : 0) ^ \
(i & 0x20 ? 0x00 : 0) ^ (i & 0x10 ? 0x00 : 0) ^ \
(i & 0x08 ? 0x80 : 0) ^ (i & 0x04 ? 0xc0 : 0) ^ \
(i & 0x02 ? 0x60 : 0) ^ (i & 0x01 ? 0xb0 : 0) )
static mode(32t) gf_poly[2] = { 0, 0xe1000000 };
static mode(32t) gf_poly64[2] = { 0, 0xd8000000 };
/* Multiply of a GF128 field element by x. The field element */
/* is held in an array of bytes in which field bits 8n..8n + 7 */
/* are held in byte[n], with lower indexed bits placed in the */
/* more numerically significant bit positions in bytes. */
/* This function multiples a field element x, in the polynomial */
/* field representation. It uses 32-bit word operations to gain */
/* speed but compensates for machine endianess and hence works */
/* correctly on both styles of machine */
in_line void mul_x(mode(32t) x[4])
{ mode(32t) t;
bsw_32(x, 4);
/* at this point the filed element bits 0..127 are set out */
/* as follows in 32-bit words (where the most significant */
/* (ms) numeric bits are to the left) */
/* */
/* x[0] x[1] x[2] x[3] */
/* ms ls ms ls ms ls ms ls */
/* field: 0 ... 31 32 .. 63 64 .. 95 96 .. 127 */
t = gf_poly[x[3] & 1]; /* bit 127 of the element */
x[3] = (x[3] >> 1) | (x[2] << 31); /* shift bits up by one */
x[2] = (x[2] >> 1) | (x[1] << 31); /* position */
x[1] = (x[1] >> 1) | (x[0] << 31); /* if bit 7 is 1 xor in */
x[0] = (x[0] >> 1) ^ t; /* the field polynomial */
bsw_32(x, 4);
}
in_line void mul_x64(mode(32t) x[2])
{ mode(32t) t;
bsw_32(x, 2);
/* at this point the filed element bits 0..127 are set out */
/* as follows in 32-bit words (where the most significant */
/* (ms) numeric bits are to the left) */
/* */
/* x[0] x[1] x[2] x[3] */
/* ms ls ms ls ms ls ms ls */
/* field: 0 ... 31 32 .. 63 64 .. 95 96 .. 127 */
t = gf_poly64[x[1] & 1]; /* bit 127 of the element */
/* shift bits up by one */
/* position */
x[1] = (x[1] >> 1) | (x[0] << 31); /* if bit 7 is 1 xor in */
x[0] = (x[0] >> 1) ^ t; /* the field polynomial */
bsw_32(x, 2);
}
/* Multiply of a GF128 field element by x^8 using 32-bit words */
/* for speed - machine endianess matters here */
#if (PLATFORM_BYTE_ORDER == BRG_LITTLE_ENDIAN)
#define xp_fun(x,y) ((mode(32t))(x)) | (((mode(32t))(y)) << 8)
static const uint16_t gft_le[256] = gf_dat(xp);
static const uint16_t gft_le64[256] = gf_dat(xp64);
in_line void mul_lex8(mode(32t) x[4]) /* mutiply with long words */
{ mode(32t) t = (x[3] >> 24); /* in little endian format */
x[3] = (x[3] << 8) | (x[2] >> 24);
x[2] = (x[2] << 8) | (x[1] >> 24);
x[1] = (x[1] << 8) | (x[0] >> 24);
x[0] = (x[0] << 8) ^ gft_le[t];
}
in_line void mul_lex8_64(mode(32t) x[2]) /* mutiply with long words */
{ mode(32t) t = (x[1] >> 24); /* in little endian format */
x[1] = (x[1] << 8) | (x[0] >> 24);
x[0] = (x[0] << 8) ^ gft_le64[t];
}
#endif
#if 1 || (PLATFORM_BYTE_ORDER == BRG_LITTLE_ENDIAN)
#undef xp_fun
#define xp_fun(x,y) ((mode(32t))(y)) | (((mode(32t))(x)) << 8)
static const uint16_t gft_be[256] = gf_dat(xp);
static const uint16_t gft_be64[256] = gf_dat(xp64);
in_line void mul_bex8(mode(32t) x[4]) /* mutiply with long words */
{ mode(32t) t = (x[3] & 0xff); /* in big endian format */
x[3] = (x[3] >> 8) | (x[2] << 24);
x[2] = (x[2] >> 8) | (x[1] << 24);
x[1] = (x[1] >> 8) | (x[0] << 24);
x[0] = (x[0] >> 8) ^ (((mode(32t))gft_be[t]) << 16);
}
in_line void mul_bex8_64(mode(32t) x[2]) /* mutiply with long words */
{ mode(32t) t = (x[1] & 0xff); /* in big endian format */
x[1] = (x[1] >> 8) | (x[0] << 24);
x[0] = (x[0] >> 8) ^ (((mode(32t))gft_be64[t]) << 16);
}
#endif
/* hence choose the correct version for the machine endianess */
#if PLATFORM_BYTE_ORDER == BRG_BIG_ENDIAN
#define mul_x8 mul_bex8
#define mul_x8_64 mul_bex8_64
#else
#define mul_x8 mul_lex8
#define mul_x8_64 mul_lex8_64
#endif
/* different versions of the general gf_mul function are provided */
/* here. Sadly none are very fast :-( */
void GfMul128 (void *a, const void* b)
{ mode(32t) r[CBLK_LEN >> 2], p[8][CBLK_LEN >> 2];
int i;
move_block_aligned(p[0], b);
bsw_32(p[0], 4);
for(i = 0; i < 7; ++i)
{
p[i + 1][3] = (p[i][3] >> 1) | (p[i][2] << 31);
p[i + 1][2] = (p[i][2] >> 1) | (p[i][1] << 31);
p[i + 1][1] = (p[i][1] >> 1) | (p[i][0] << 31);
p[i + 1][0] = (p[i][0] >> 1) ^ gf_poly[p[i][3] & 1];
}
memset(r, 0, CBLK_LEN);
for(i = 0; i < 16; ++i)
{
if(i) mul_bex8(r); /* order is always big endian here */
if(((unsigned char*)a)[15 - i] & 0x80)
xor_block_aligned(r, p[0]);
if(((unsigned char*)a)[15 - i] & 0x40)
xor_block_aligned(r, p[1]);
if(((unsigned char*)a)[15 - i] & 0x20)
xor_block_aligned(r, p[2]);
if(((unsigned char*)a)[15 - i] & 0x10)
xor_block_aligned(r, p[3]);
if(((unsigned char*)a)[15 - i] & 0x08)
xor_block_aligned(r, p[4]);
if(((unsigned char*)a)[15 - i] & 0x04)
xor_block_aligned(r, p[5]);
if(((unsigned char*)a)[15 - i] & 0x02)
xor_block_aligned(r, p[6]);
if(((unsigned char*)a)[15 - i] & 0x01)
xor_block_aligned(r, p[7]);
}
bsw_32(r, 4);
move_block_aligned(a, r);
}
#if defined( UNROLL_LOOPS )
#define xor_8k(i) \
xor_block_aligned(r, ctx->gf_t8k[i + i][a[i] & 15]); \
xor_block_aligned(r, ctx->gf_t8k[i + i + 1][a[i] >> 4])
void GfMul128Tab (unsigned char a[CBLK_LEN], GfCtx8k *ctx)
{ uint32_t r[CBLK_LEN >> 2];
move_block_aligned(r, ctx->gf_t8k[0][a[0] & 15]);
xor_block_aligned(r, ctx->gf_t8k[1][a[0] >> 4]);
xor_8k( 1); xor_8k( 2); xor_8k( 3);
xor_8k( 4); xor_8k( 5); xor_8k( 6); xor_8k( 7);
xor_8k( 8); xor_8k( 9); xor_8k(10); xor_8k(11);
xor_8k(12); xor_8k(13); xor_8k(14); xor_8k(15);
move_block_aligned(a, r);
}
#else
void GfMul128Tab (unsigned char a[CBLK_LEN], GfCtx8k *ctx)
{ uint32_t r[CBLK_LEN >> 2], *p;
int i;
p = ctx->gf_t8k[0][a[0] & 15];
memcpy(r, p, CBLK_LEN);
p = ctx->gf_t8k[1][a[0] >> 4];
xor_block_aligned(r, p);
for(i = 1; i < CBLK_LEN; ++i)
{
xor_block_aligned(r, ctx->gf_t8k[i + i][a[i] & 15]);
xor_block_aligned(r, ctx->gf_t8k[i + i + 1][a[i] >> 4]);
}
memcpy(a, r, CBLK_LEN);
}
#endif
void compile_8k_table(uint8_t *a, GfCtx8k *ctx)
{ int i, j, k;
memset(ctx->gf_t8k, 0, 32 * 16 * 16);
for(i = 0; i < 2 * CBLK_LEN; ++i)
{
if(i == 0)
{
memcpy(ctx->gf_t8k[1][8], a, CBLK_LEN);
for(j = 4; j > 0; j >>= 1)
{
memcpy(ctx->gf_t8k[1][j], ctx->gf_t8k[1][j + j], CBLK_LEN);
mul_x(ctx->gf_t8k[1][j]);
}
memcpy(ctx->gf_t8k[0][8], ctx->gf_t8k[1][1], CBLK_LEN);
mul_x(ctx->gf_t8k[0][8]);
for(j = 4; j > 0; j >>= 1)
{
memcpy(ctx->gf_t8k[0][j], ctx->gf_t8k[0][j + j], CBLK_LEN);
mul_x(ctx->gf_t8k[0][j]);
}
}
else if(i > 1)
for(j = 8; j > 0; j >>= 1)
{
memcpy(ctx->gf_t8k[i][j], ctx->gf_t8k[i - 2][j], CBLK_LEN);
mul_x8(ctx->gf_t8k[i][j]);
}
for(j = 2; j < 16; j += j)
{
mode(32t) *pj = ctx->gf_t8k[i][j];
mode(32t) *pk = ctx->gf_t8k[i][1];
mode(32t) *pl = ctx->gf_t8k[i][j + 1];
for(k = 1; k < j; ++k)
{
*pl++ = pj[0] ^ *pk++;
*pl++ = pj[1] ^ *pk++;
*pl++ = pj[2] ^ *pk++;
*pl++ = pj[3] ^ *pk++;
}
}
}
}
void compile_4k_table64(uint8_t *a, GfCtx4k64 *ctx)
{ int i, j, k;
memset(ctx->gf_t4k, 0, sizeof(ctx->gf_t4k));
for(i = 0; i < 2 * CBLK_LEN8; ++i)
{
if(i == 0)
{
memcpy(ctx->gf_t4k[1][8], a, CBLK_LEN8);
for(j = 4; j > 0; j >>= 1)
{
memcpy(ctx->gf_t4k[1][j], ctx->gf_t4k[1][j + j], CBLK_LEN8);
mul_x64(ctx->gf_t4k[1][j]);
}
memcpy(ctx->gf_t4k[0][8], ctx->gf_t4k[1][1], CBLK_LEN8);
mul_x64(ctx->gf_t4k[0][8]);
for(j = 4; j > 0; j >>= 1)
{
memcpy(ctx->gf_t4k[0][j], ctx->gf_t4k[0][j + j], CBLK_LEN8);
mul_x64(ctx->gf_t4k[0][j]);
}
}
else if(i > 1)
for(j = 8; j > 0; j >>= 1)
{
memcpy(ctx->gf_t4k[i][j], ctx->gf_t4k[i - 2][j], CBLK_LEN8);
mul_x8_64(ctx->gf_t4k[i][j]);
}
for(j = 2; j < 16; j += j)
{
mode(32t) *pj = ctx->gf_t4k[i][j];
mode(32t) *pk = ctx->gf_t4k[i][1];
mode(32t) *pl = ctx->gf_t4k[i][j + 1];
for(k = 1; k < j; ++k)
{
*pl++ = pj[0] ^ *pk++;
*pl++ = pj[1] ^ *pk++;
*pl++ = pj[2] ^ *pk++;
*pl++ = pj[3] ^ *pk++;
}
}
}
}
static int IsBitSet128 (unsigned int bit, uint8_t *a)
{
return a[(127 - bit) / 8] & (0x80 >> ((127 - bit) % 8));
}
static int IsBitSet64 (unsigned int bit, uint8_t *a)
{
return a[(63 - bit) / 8] & (0x80 >> ((63 - bit) % 8));
}
static void SetBit128 (unsigned int bit, uint8_t *a)
{
a[(127 - bit) / 8] |= 0x80 >> ((127 - bit) % 8);
}
static void SetBit64 (unsigned int bit, uint8_t *a)
{
a[(63 - bit) / 8] |= 0x80 >> ((63 - bit) % 8);
}
void MirrorBits128 (uint8_t *a)
{
uint8_t t[128 / 8];
int i;
memset (t,0,16);
for (i = 0; i < 128; i++)
{
if (IsBitSet128(i, a))
SetBit128 (127 - i, t);
}
memcpy (a, t, sizeof (t));
burn (t,sizeof (t));
}
void MirrorBits64 (uint8_t *a)
{
uint8_t t[64 / 8];
int i;
memset (t,0,8);
for (i = 0; i < 64; i++)
{
if (IsBitSet64(i, a))
SetBit64 (63 - i, t);
}
memcpy (a, t, sizeof (t));
burn (t,sizeof (t));
}
/* Allocate and initialize speed optimization table
for multiplication by 64-bit operand in MSB-first mode */
int Gf128Tab64Init (uint8_t *a, GfCtx *ctx)
{
GfCtx8k *ctx8k;
uint8_t am[16];
int i, j;
ctx8k = (GfCtx8k *) TCalloc (sizeof (GfCtx8k));
if (!ctx8k)
return 0;
memcpy (am, a, 16);
MirrorBits128 (am);
compile_8k_table (am, ctx8k);
/* Convert 8k LSB-first table to 4k MSB-first */
for (i = 16; i < 32; i++)
{
for (j = 0; j < 16; j++)
{
int jm = 0;
jm |= (j & 0x1) << 3;
jm |= (j & 0x2) << 1;
jm |= (j & 0x4) >> 1;
jm |= (j & 0x8) >> 3;
memcpy (&ctx->gf_t128[i-16][jm], (unsigned char *)&ctx8k->gf_t8k[31-i][j], 16);
MirrorBits128 ((unsigned char *)&ctx->gf_t128[i-16][jm]);
}
}
burn (ctx8k ,sizeof (*ctx8k));
burn (am, sizeof (am));
TCfree (ctx8k);
return 1;
}
int Gf64TabInit (uint8_t *a, GfCtx *ctx)
{
/* Deprecated/legacy */
GfCtx4k64 *ctx4k;
uint8_t am[8];
int i, j;
ctx4k = (GfCtx4k64 *) TCalloc (sizeof (GfCtx4k64));
if (!ctx4k)
return 0;
memcpy (am, a, 8);
MirrorBits64 (am);
compile_4k_table64 (am, ctx4k);
/* Convert LSB-first table to MSB-first */
for (i = 0; i < 16; i++)
{
for (j = 0; j < 16; j++)
{
int jm = 0;
jm |= (j & 0x1) << 3;
jm |= (j & 0x2) << 1;
jm |= (j & 0x4) >> 1;
jm |= (j & 0x8) >> 3;
memcpy (&ctx->gf_t64[i][jm], (unsigned char *)&ctx4k->gf_t4k[15-i][j], 8);
MirrorBits64 ((unsigned char *)&ctx->gf_t64[i][jm]);
}
}
burn (ctx4k,sizeof (*ctx4k));
burn (am, sizeof (am));
TCfree (ctx4k);
return 1;
}
#define xor_8kt64(i) \
xor_block_aligned(r, ctx->gf_t128[i + i][a[i] & 15]); \
xor_block_aligned(r, ctx->gf_t128[i + i + 1][a[i] >> 4])
/* Multiply a 128-bit number by a 64-bit number in the finite field GF(2^128) */
void Gf128MulBy64Tab (uint8_t a[8], uint8_t p[16], GfCtx *ctx)
{
uint32_t r[CBLK_LEN >> 2];
move_block_aligned(r, ctx->gf_t128[7*2][a[7] & 15]);
xor_block_aligned(r, ctx->gf_t128[7*2+1][a[7] >> 4]);
if (*(uint16_t *)a)
{
xor_8kt64(0);
xor_8kt64(1);
}
if (a[2])
{
xor_8kt64(2);
}
xor_8kt64(3);
xor_8kt64(4);
xor_8kt64(5);
xor_8kt64(6);
move_block_aligned(p, r);
}
#define xor_8k64(i) \
xor_block_aligned64(r, ctx->gf_t64[i + i][a[i] & 15]); \
xor_block_aligned64(r, ctx->gf_t64[i + i + 1][a[i] >> 4])
/* Multiply two 64-bit numbers in the finite field GF(2^64) */
void Gf64MulTab (unsigned char a[8], unsigned char p[8], GfCtx *ctx)
{
/* Deprecated/legacy */
uint32_t r[CBLK_LEN8 >> 2];
move_block_aligned64(r, ctx->gf_t64[7*2][a[7] & 15]);
xor_block_aligned64(r, ctx->gf_t64[7*2+1][a[7] >> 4]);
if (*(uint16_t *)a)
{
xor_8k64(0);
xor_8k64(1);
}
if (a[2])
{
xor_8k64(2);
}
xor_8k64(3);
xor_8k64(4);
xor_8k64(5);
xor_8k64(6);
move_block_aligned64(p, r);
}
/* Basic algorithms for testing of optimized algorithms */
static void xor128 (uint64_t *a, uint64_t *b)
{
*a++ ^= *b++;
*a ^= *b;
}
static void shl128 (uint8_t *a)
{
int i, x = 0, xx;
for (i = 15; i >= 0; i--)
{
xx = (a[i] & 0x80) >> 7;
a[i] = (a[i] << 1) | x;
x = xx;
}
}
static void GfMul128Basic (uint8_t *a, uint8_t *b, uint8_t *p)
{
int i;
uint8_t la[16];
memcpy (la, a, 16);
memset (p, 0, 16);
for (i = 0; i < 128; i++)
{
if (IsBitSet128 (i, b))
xor128 ((uint64_t *)p, (uint64_t *)la);
if (la[0] & 0x80)
{
shl128 (la);
la[15] ^= 0x87;
}
else
{
shl128 (la);
}
}
}
static void xor64 (uint64_t *a, uint64_t *b)
{
*a ^= *b;
}
static void shl64 (uint8_t *a)
{
int i, x = 0, xx;
for (i = 7; i >= 0; i--)
{
xx = (a[i] & 0x80) >> 7;
a[i] = (a[i] << 1) | x;
x = xx;
}
}
static void GfMul64Basic (uint8_t *a, uint8_t *b, uint8_t* p)
{
/* Deprecated/legacy */
int i;
uint8_t la[8];
memcpy (la, a, 8);
memset (p, 0, 8);
for (i = 0; i < 64; i++)
{
if (IsBitSet64 (i, b))
xor64 ((uint64_t *)p, (uint64_t *)la);
if (la[0] & 0x80)
{
shl64 (la);
la[7] ^= 0x1b;
}
else
{
shl64 (la);
}
}
}
int GfMulSelfTest (void)
{
int result = 1;
uint8_t a[16];
uint8_t b[16];
uint8_t p1[16];
uint8_t p2[16];
GfCtx *gfCtx = (GfCtx *) TCalloc (sizeof (GfCtx));
int i, j;
if (!gfCtx)
return 0;
/* GF(2^64) - deprecated/legacy */
for (i = 0; i < 0x100; i++)
{
for (j = 0; j < 8; j++)
{
a[j] = (uint8_t) i;
b[j] = a[j] ^ 0xff;
}
GfMul64Basic (a, b, p1);
Gf64TabInit (a, gfCtx);
Gf64MulTab (b, p2, gfCtx);
if (memcmp (p1, p2, 8) != 0)
result = 0;
}
/* GF(2^128) */
for (i = 0; i < 0x100; i++)
{
for (j = 0; j < 16; j++)
{
a[j] = (uint8_t) i;
b[j] = j < 8 ? 0 : a[j] ^ 0xff;
}
GfMul128Basic (a, b, p1);
Gf128Tab64Init (a, gfCtx);
Gf128MulBy64Tab (b + 8, p2, gfCtx);
if (memcmp (p1, p2, 16) != 0)
result = 0;
}
TCfree (gfCtx);
return result;
}
#if defined(__cplusplus)
}
#endif

78
src/utils/common/gfmul.h Normal file
View File

@@ -0,0 +1,78 @@
/*
---------------------------------------------------------------------------
Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved.
LICENSE TERMS
The free distribution and use of this software is allowed (with or without
changes) provided that:
1. source code distributions include the above copyright notice, this
list of conditions and the following disclaimer;
2. binary distributions include the above copyright notice, this list
of conditions and the following disclaimer in their documentation;
3. the name of the copyright holder is not used to endorse products
built using this software without specific written permission.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue Date: 31/01/2004
*/
/* Adapted for TrueCrypt by the TrueCrypt Foundation */
#ifndef _GCM_H
#define _GCM_H
#include <inttypes.h>
#include "tcdefs.h"
#if defined(__cplusplus)
extern "C"
{
#endif
#define CBLK_LEN 16 /* encryption block length */
#define CBLK_LEN8 8
typedef struct
{
uint32_t gf_t8k[CBLK_LEN * 2][16][CBLK_LEN / 4];
} GfCtx8k;
typedef struct
{
uint32_t gf_t4k[CBLK_LEN8 * 2][16][CBLK_LEN / 4];
} GfCtx4k64;
typedef struct
{
/* union not used to support faster mounting */
uint32_t gf_t128[CBLK_LEN * 2 / 2][16][CBLK_LEN / 4];
uint32_t gf_t64[CBLK_LEN8 * 2][16][CBLK_LEN8 / 4];
} GfCtx;
typedef int ret_type;
void GfMul128 (void *a, const void* b);
void GfMul128Tab(unsigned char a[16], GfCtx8k *ctx);
int Gf128Tab64Init (uint8_t *a, GfCtx *ctx);
void Gf128MulBy64Tab (uint8_t a[8], uint8_t p[16], GfCtx *ctx);
int Gf64TabInit (uint8_t *a, GfCtx *ctx);
void Gf64MulTab (unsigned char a[8], unsigned char p[8], GfCtx *ctx);
void MirrorBits128 (uint8_t *a);
void MirrorBits64 (uint8_t *a);
int GfMulSelfTest (void);
#if defined(__cplusplus)
}
#endif
#endif

View File

@@ -0,0 +1,39 @@
/*
Legal Notice: Some portions of the source code contained in this file were
derived from the source code of Encryption for the Masses 2.02a, which is
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
Agreement for Encryption for the Masses'. Modifications and additions to
the original source code (contained in this file) and all other portions of
this file are Copyright (c) 2003-2008 TrueCrypt Foundation and are governed
by the TrueCrypt License 2.4 the full text of which is contained in the
file License.txt included in TrueCrypt binary and source code distribution
packages. */
#ifndef PASSWORD_H
#define PASSWORD_H
#include <inttypes.h>
// User text input limits
#define MIN_PASSWORD 1 // Minimum password length
#define MAX_PASSWORD 64 // Maximum password length
#define PASSWORD_LEN_WARNING 20 // Display a warning when a password is shorter than this
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
// Modifying this structure can introduce incompatibility with previous versions
int32_t Length;
unsigned char Text[MAX_PASSWORD + 1];
char Pad[3]; // keep 64-bit alignment
} Password;
#ifdef __cplusplus
}
#endif
#endif // PASSWORD_H

631
src/utils/common/pkcs5.c Normal file
View File

@@ -0,0 +1,631 @@
/*
Legal Notice: Some portions of the source code contained in this file were
derived from the source code of Encryption for the Masses 2.02a, which is
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
Agreement for Encryption for the Masses'. Modifications and additions to
the original source code (contained in this file) and all other portions of
this file are Copyright (c) 2003-2008 TrueCrypt Foundation and are governed
by the TrueCrypt License 2.4 the full text of which is contained in the
file License.txt included in TrueCrypt binary and source code distribution
packages. */
#include "tcdefs.h"
#include <memory.h>
#include "../crypto/rmd160.h"
#include "../crypto/sha1.h"
#include "../crypto/sha2.h"
#include "../crypto/whirlpool.h"
#include "pkcs5.h"
#include "crypto.h"
void hmac_truncate
(
char *d1, /* data to be truncated */
char *d2, /* truncated data */
int len /* length in bytes to keep */
)
{
int i;
for (i = 0; i < len; i++)
d2[i] = d1[i];
}
void hmac_sha512
(
char *k, /* secret key */
int lk, /* length of the key in bytes */
char *d, /* data */
int ld, /* length of data in bytes */
char *out, /* output buffer, at least "t" bytes */
int t
)
{
sha512_ctx ictx, octx;
char isha[SHA512_DIGESTSIZE], osha[SHA512_DIGESTSIZE];
char key[SHA512_DIGESTSIZE];
char buf[SHA512_BLOCKSIZE];
int i;
/* If the key is longer than the hash algorithm block size,
let key = sha512(key), as per HMAC specifications. */
if (lk > SHA512_BLOCKSIZE)
{
sha512_ctx tctx;
sha512_begin (&tctx);
sha512_hash ((unsigned char *) k, lk, &tctx);
sha512_end ((unsigned char *) key, &tctx);
k = key;
lk = SHA512_DIGESTSIZE;
burn (&tctx, sizeof(tctx)); // Prevent leaks
}
/**** Inner Digest ****/
sha512_begin (&ictx);
/* Pad the key for inner digest */
for (i = 0; i < lk; ++i)
buf[i] = (char) (k[i] ^ 0x36);
for (i = lk; i < SHA512_BLOCKSIZE; ++i)
buf[i] = 0x36;
sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, &ictx);
sha512_hash ((unsigned char *) d, ld, &ictx);
sha512_end ((unsigned char *) isha, &ictx);
/**** Outer Digest ****/
sha512_begin (&octx);
for (i = 0; i < lk; ++i)
buf[i] = (char) (k[i] ^ 0x5C);
for (i = lk; i < SHA512_BLOCKSIZE; ++i)
buf[i] = 0x5C;
sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, &octx);
sha512_hash ((unsigned char *) isha, SHA512_DIGESTSIZE, &octx);
sha512_end ((unsigned char *) osha, &octx);
/* truncate and print the results */
t = t > SHA512_DIGESTSIZE ? SHA512_DIGESTSIZE : t;
hmac_truncate (osha, out, t);
/* Prevent leaks */
burn (&ictx, sizeof(ictx));
burn (&octx, sizeof(octx));
burn (isha, sizeof(isha));
burn (osha, sizeof(osha));
burn (buf, sizeof(buf));
burn (key, sizeof(key));
}
void derive_u_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
{
char j[SHA512_DIGESTSIZE], k[SHA512_DIGESTSIZE];
char init[128];
char counter[4];
int c, i;
/* iteration 1 */
memset (counter, 0, 4);
counter[3] = (char) b;
memcpy (init, salt, salt_len); /* salt */
memcpy (&init[salt_len], counter, 4); /* big-endian block number */
hmac_sha512 (pwd, pwd_len, init, salt_len + 4, j, SHA512_DIGESTSIZE);
memcpy (u, j, SHA512_DIGESTSIZE);
/* remaining iterations */
for (c = 1; c < iterations; c++)
{
hmac_sha512 (pwd, pwd_len, j, SHA512_DIGESTSIZE, k, SHA512_DIGESTSIZE);
for (i = 0; i < SHA512_DIGESTSIZE; i++)
{
u[i] ^= k[i];
j[i] = k[i];
}
}
/* Prevent possible leaks. */
burn (j, sizeof(j));
burn (k, sizeof(k));
}
void derive_key_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
{
char u[SHA512_DIGESTSIZE];
int b, l, r;
if (dklen % SHA512_DIGESTSIZE)
{
l = 1 + dklen / SHA512_DIGESTSIZE;
}
else
{
l = dklen / SHA512_DIGESTSIZE;
}
r = dklen - (l - 1) * SHA512_DIGESTSIZE;
/* first l - 1 blocks */
for (b = 1; b < l; b++)
{
derive_u_sha512 (pwd, pwd_len, salt, salt_len, iterations, u, b);
memcpy (dk, u, SHA512_DIGESTSIZE);
dk += SHA512_DIGESTSIZE;
}
/* last block */
derive_u_sha512 (pwd, pwd_len, salt, salt_len, iterations, u, b);
memcpy (dk, u, r);
/* Prevent possible leaks. */
burn (u, sizeof(u));
}
/* Deprecated/legacy */
void hmac_sha1
(
char *k, /* secret key */
int lk, /* length of the key in bytes */
char *d, /* data */
int ld, /* length of data in bytes */
char *out, /* output buffer, at least "t" bytes */
int t
)
{
sha1_ctx ictx, octx;
char isha[SHA1_DIGESTSIZE], osha[SHA1_DIGESTSIZE];
char key[SHA1_DIGESTSIZE];
char buf[SHA1_BLOCKSIZE];
int i;
/* If the key is longer than the hash algorithm block size,
let key = sha1(key), as per HMAC specifications. */
if (lk > SHA1_BLOCKSIZE)
{
sha1_ctx tctx;
sha1_begin (&tctx);
sha1_hash ((unsigned char *) k, lk, &tctx);
sha1_end ((unsigned char *) key, &tctx);
k = key;
lk = SHA1_DIGESTSIZE;
burn (&tctx, sizeof(tctx)); // Prevent leaks
}
/**** Inner Digest ****/
sha1_begin (&ictx);
/* Pad the key for inner digest */
for (i = 0; i < lk; ++i)
buf[i] = (char) (k[i] ^ 0x36);
for (i = lk; i < SHA1_BLOCKSIZE; ++i)
buf[i] = 0x36;
sha1_hash ((unsigned char *) buf, SHA1_BLOCKSIZE, &ictx);
sha1_hash ((unsigned char *) d, ld, &ictx);
sha1_end ((unsigned char *) isha, &ictx);
/**** Outer Digest ****/
sha1_begin (&octx);
for (i = 0; i < lk; ++i)
buf[i] = (char) (k[i] ^ 0x5C);
for (i = lk; i < SHA1_BLOCKSIZE; ++i)
buf[i] = 0x5C;
sha1_hash ((unsigned char *) buf, SHA1_BLOCKSIZE, &octx);
sha1_hash ((unsigned char *) isha, SHA1_DIGESTSIZE, &octx);
sha1_end ((unsigned char *) osha, &octx);
/* truncate and print the results */
t = t > SHA1_DIGESTSIZE ? SHA1_DIGESTSIZE : t;
hmac_truncate (osha, out, t);
/* Prevent leaks */
burn (&ictx, sizeof(ictx));
burn (&octx, sizeof(octx));
burn (isha, sizeof(isha));
burn (osha, sizeof(osha));
burn (buf, sizeof(buf));
burn (key, sizeof(key));
}
/* Deprecated/legacy */
void derive_u_sha1 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
{
char j[SHA1_DIGESTSIZE], k[SHA1_DIGESTSIZE];
char init[128];
char counter[4];
int c, i;
/* iteration 1 */
memset (counter, 0, 4);
counter[3] = (char) b;
memcpy (init, salt, salt_len); /* salt */
memcpy (&init[salt_len], counter, 4); /* big-endian block number */
hmac_sha1 (pwd, pwd_len, init, salt_len + 4, j, SHA1_DIGESTSIZE);
memcpy (u, j, SHA1_DIGESTSIZE);
/* remaining iterations */
for (c = 1; c < iterations; c++)
{
hmac_sha1 (pwd, pwd_len, j, SHA1_DIGESTSIZE, k, SHA1_DIGESTSIZE);
for (i = 0; i < SHA1_DIGESTSIZE; i++)
{
u[i] ^= k[i];
j[i] = k[i];
}
}
/* Prevent possible leaks. */
burn (j, sizeof(j));
burn (k, sizeof(k));
}
/* Deprecated/legacy */
void derive_key_sha1 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
{
char u[SHA1_DIGESTSIZE];
int b, l, r;
if (dklen % SHA1_DIGESTSIZE)
{
l = 1 + dklen / SHA1_DIGESTSIZE;
}
else
{
l = dklen / SHA1_DIGESTSIZE;
}
r = dklen - (l - 1) * SHA1_DIGESTSIZE;
/* first l - 1 blocks */
for (b = 1; b < l; b++)
{
derive_u_sha1 (pwd, pwd_len, salt, salt_len, iterations, u, b);
memcpy (dk, u, SHA1_DIGESTSIZE);
dk += SHA1_DIGESTSIZE;
}
/* last block */
derive_u_sha1 (pwd, pwd_len, salt, salt_len, iterations, u, b);
memcpy (dk, u, r);
/* Prevent possible leaks. */
burn (u, sizeof(u));
}
void hmac_ripemd160 (char *key, int keylen, char *input, int len, char *digest)
{
RMD160_CTX context;
unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */
unsigned char k_opad[65]; /* outer padding - key XORd with opad */
unsigned char tk[RIPEMD160_DIGESTSIZE];
int i;
/* If the key is longer than the hash algorithm block size,
let key = ripemd160(key), as per HMAC specifications. */
if (keylen > RIPEMD160_BLOCKSIZE)
{
RMD160_CTX tctx;
RMD160Init(&tctx);
RMD160Update(&tctx, (const uint8_t *) key, keylen);
RMD160Final(tk, &tctx);
key = (char *) tk;
keylen = RIPEMD160_DIGESTSIZE;
burn (&tctx, sizeof(tctx)); // Prevent leaks
}
/*
RMD160(K XOR opad, RMD160(K XOR ipad, text))
where K is an n byte key
ipad is the byte 0x36 repeated RIPEMD160_BLOCKSIZE times
opad is the byte 0x5c repeated RIPEMD160_BLOCKSIZE times
and text is the data being protected */
/* start out by storing key in pads */
memset(k_ipad, 0x36, sizeof(k_ipad));
memset(k_opad, 0x5c, sizeof(k_opad));
/* XOR key with ipad and opad values */
for (i=0; i<keylen; i++)
{
k_ipad[i] ^= key[i];
k_opad[i] ^= key[i];
}
/* perform inner RIPEMD-160 */
RMD160Init(&context); /* init context for 1st pass */
RMD160Update(&context, k_ipad, RIPEMD160_BLOCKSIZE); /* start with inner pad */
RMD160Update(&context, (uint8_t *) input, len); /* then text of datagram */
RMD160Final((uint8_t *) digest, &context); /* finish up 1st pass */
/* perform outer RIPEMD-160 */
RMD160Init(&context); /* init context for 2nd pass */
RMD160Update(&context, k_opad, RIPEMD160_BLOCKSIZE); /* start with outer pad */
/* results of 1st hash */
RMD160Update(&context, (uint8_t *) digest, RIPEMD160_DIGESTSIZE);
RMD160Final((uint8_t *) digest, &context); /* finish up 2nd pass */
/* Prevent possible leaks. */
burn (k_ipad, sizeof(k_ipad));
burn (k_opad, sizeof(k_opad));
burn (tk, sizeof(tk));
burn (&context, sizeof(context));
}
void derive_u_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
{
char j[RIPEMD160_DIGESTSIZE], k[RIPEMD160_DIGESTSIZE];
char init[128];
char counter[4];
int c, i;
/* iteration 1 */
memset (counter, 0, 4);
counter[3] = (char) b;
memcpy (init, salt, salt_len); /* salt */
memcpy (&init[salt_len], counter, 4); /* big-endian block number */
hmac_ripemd160 (pwd, pwd_len, init, salt_len + 4, j);
memcpy (u, j, RIPEMD160_DIGESTSIZE);
/* remaining iterations */
for (c = 1; c < iterations; c++)
{
hmac_ripemd160 (pwd, pwd_len, j, RIPEMD160_DIGESTSIZE, k);
for (i = 0; i < RIPEMD160_DIGESTSIZE; i++)
{
u[i] ^= k[i];
j[i] = k[i];
}
}
/* Prevent possible leaks. */
burn (j, sizeof(j));
burn (k, sizeof(k));
}
void derive_key_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
{
char u[RIPEMD160_DIGESTSIZE];
int b, l, r;
if (dklen % RIPEMD160_DIGESTSIZE)
{
l = 1 + dklen / RIPEMD160_DIGESTSIZE;
}
else
{
l = dklen / RIPEMD160_DIGESTSIZE;
}
r = dklen - (l - 1) * RIPEMD160_DIGESTSIZE;
/* first l - 1 blocks */
for (b = 1; b < l; b++)
{
derive_u_ripemd160 (pwd, pwd_len, salt, salt_len, iterations, u, b);
memcpy (dk, u, RIPEMD160_DIGESTSIZE);
dk += RIPEMD160_DIGESTSIZE;
}
/* last block */
derive_u_ripemd160 (pwd, pwd_len, salt, salt_len, iterations, u, b);
memcpy (dk, u, r);
/* Prevent possible leaks. */
burn (u, sizeof(u));
}
void hmac_whirlpool
(
char *k, /* secret key */
int lk, /* length of the key in bytes */
char *d, /* data */
int ld, /* length of data in bytes */
char *out, /* output buffer, at least "t" bytes */
int t
)
{
WHIRLPOOL_CTX ictx, octx;
char iwhi[WHIRLPOOL_DIGESTSIZE], owhi[WHIRLPOOL_DIGESTSIZE];
char key[WHIRLPOOL_DIGESTSIZE];
char buf[WHIRLPOOL_BLOCKSIZE];
int i;
/* If the key is longer than the hash algorithm block size,
let key = whirlpool(key), as per HMAC specifications. */
if (lk > WHIRLPOOL_BLOCKSIZE)
{
WHIRLPOOL_CTX tctx;
WHIRLPOOL_init (&tctx);
WHIRLPOOL_add ((unsigned char *) k, lk * 8, &tctx);
WHIRLPOOL_finalize (&tctx, (unsigned char *) key);
k = key;
lk = WHIRLPOOL_DIGESTSIZE;
burn (&tctx, sizeof(tctx)); // Prevent leaks
}
/**** Inner Digest ****/
WHIRLPOOL_init (&ictx);
/* Pad the key for inner digest */
for (i = 0; i < lk; ++i)
buf[i] = (char) (k[i] ^ 0x36);
for (i = lk; i < WHIRLPOOL_BLOCKSIZE; ++i)
buf[i] = 0x36;
WHIRLPOOL_add ((unsigned char *) buf, WHIRLPOOL_BLOCKSIZE * 8, &ictx);
WHIRLPOOL_add ((unsigned char *) d, ld * 8, &ictx);
WHIRLPOOL_finalize (&ictx, (unsigned char *) iwhi);
/**** Outer Digest ****/
WHIRLPOOL_init (&octx);
for (i = 0; i < lk; ++i)
buf[i] = (char) (k[i] ^ 0x5C);
for (i = lk; i < WHIRLPOOL_BLOCKSIZE; ++i)
buf[i] = 0x5C;
WHIRLPOOL_add ((unsigned char *) buf, WHIRLPOOL_BLOCKSIZE * 8, &octx);
WHIRLPOOL_add ((unsigned char *) iwhi, WHIRLPOOL_DIGESTSIZE * 8, &octx);
WHIRLPOOL_finalize (&octx, (unsigned char *) owhi);
/* truncate and print the results */
t = t > WHIRLPOOL_DIGESTSIZE ? WHIRLPOOL_DIGESTSIZE : t;
hmac_truncate (owhi, out, t);
/* Prevent possible leaks. */
burn (&ictx, sizeof(ictx));
burn (&octx, sizeof(octx));
burn (owhi, sizeof(owhi));
burn (iwhi, sizeof(iwhi));
burn (buf, sizeof(buf));
burn (key, sizeof(key));
}
void derive_u_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
{
char j[WHIRLPOOL_DIGESTSIZE], k[WHIRLPOOL_DIGESTSIZE];
char init[128];
char counter[4];
int c, i;
/* iteration 1 */
memset (counter, 0, 4);
counter[3] = (char) b;
memcpy (init, salt, salt_len); /* salt */
memcpy (&init[salt_len], counter, 4); /* big-endian block number */
hmac_whirlpool (pwd, pwd_len, init, salt_len + 4, j, WHIRLPOOL_DIGESTSIZE);
memcpy (u, j, WHIRLPOOL_DIGESTSIZE);
/* remaining iterations */
for (c = 1; c < iterations; c++)
{
hmac_whirlpool (pwd, pwd_len, j, WHIRLPOOL_DIGESTSIZE, k, WHIRLPOOL_DIGESTSIZE);
for (i = 0; i < WHIRLPOOL_DIGESTSIZE; i++)
{
u[i] ^= k[i];
j[i] = k[i];
}
}
/* Prevent possible leaks. */
burn (j, sizeof(j));
burn (k, sizeof(k));
}
void derive_key_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
{
char u[WHIRLPOOL_DIGESTSIZE];
int b, l, r;
if (dklen % WHIRLPOOL_DIGESTSIZE)
{
l = 1 + dklen / WHIRLPOOL_DIGESTSIZE;
}
else
{
l = dklen / WHIRLPOOL_DIGESTSIZE;
}
r = dklen - (l - 1) * WHIRLPOOL_DIGESTSIZE;
/* first l - 1 blocks */
for (b = 1; b < l; b++)
{
derive_u_whirlpool (pwd, pwd_len, salt, salt_len, iterations, u, b);
memcpy (dk, u, WHIRLPOOL_DIGESTSIZE);
dk += WHIRLPOOL_DIGESTSIZE;
}
/* last block */
derive_u_whirlpool (pwd, pwd_len, salt, salt_len, iterations, u, b);
memcpy (dk, u, r);
/* Prevent possible leaks. */
burn (u, sizeof(u));
}
char *get_pkcs5_prf_name (int pkcs5_prf_id)
{
switch (pkcs5_prf_id)
{
case SHA512:
return "HMAC-SHA-512";
case SHA1: // Deprecated/legacy
return "HMAC-SHA-1";
case RIPEMD160:
return "HMAC-RIPEMD-160";
case WHIRLPOOL:
return "HMAC-Whirlpool";
default:
return "(Unknown)";
}
}
int get_pkcs5_iteration_count (int pkcs5_prf_id, int bBoot)
{
switch (pkcs5_prf_id)
{
case RIPEMD160:
return (bBoot ? 1000 : 2000);
case SHA512:
return 1000;
case SHA1: // Deprecated/legacy
return 2000;
case WHIRLPOOL:
return 1000;
default:
TC_THROW_FATAL_EXCEPTION; // Unknown/wrong ID
}
return 0;
}

41
src/utils/common/pkcs5.h Normal file
View File

@@ -0,0 +1,41 @@
/*
Legal Notice: Some portions of the source code contained in this file were
derived from the source code of Encryption for the Masses 2.02a, which is
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
Agreement for Encryption for the Masses'. Modifications and additions to
the original source code (contained in this file) and all other portions of
this file are Copyright (c) 2003-2008 TrueCrypt Foundation and are governed
by the TrueCrypt License 2.4 the full text of which is contained in the
file License.txt included in TrueCrypt binary and source code distribution
packages. */
#ifndef TC_HEADER_PKCS5
#define TC_HEADER_PKCS5
#include "tcdefs.h"
#if defined(__cplusplus)
extern "C"
{
#endif
void hmac_sha512 (char *k, int lk, char *d, int ld, char *out, int t);
void derive_u_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b);
void derive_key_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen);
void hmac_sha1 (char *k, int lk, char *d, int ld, char *out, int t);
void derive_u_sha1 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b);
void derive_key_sha1 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen);
void hmac_ripemd160 (char *key, int keylen, char *input, int len, char *digest);
void derive_u_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b);
void derive_key_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen);
void hmac_whirlpool (char *k, int lk, char *d, int ld, char *out, int t);
void derive_u_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b);
void derive_key_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen);
int get_pkcs5_iteration_count (int pkcs5_prf_id, int bBoot);
char *get_pkcs5_prf_name (int pkcs5_prf_id);
#if defined(__cplusplus)
}
#endif
#endif // TC_HEADER_PKCS5

167
src/utils/common/tcdefs.h Normal file
View File

@@ -0,0 +1,167 @@
/*
Legal Notice: Some portions of the source code contained in this file were
derived from the source code of Encryption for the Masses 2.02a, which is
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
Agreement for Encryption for the Masses'. Modifications and additions to
the original source code (contained in this file) and all other portions of
this file are Copyright (c) 2003-2008 TrueCrypt Foundation and are governed
by the TrueCrypt License 2.4 the full text of which is contained in the
file License.txt included in TrueCrypt binary and source code distribution
packages. */
#ifndef TCDEFS_H
#define TCDEFS_H
#include <inttypes.h>
#include <stdlib.h>
#define TC_APP_NAME "TrueCrypt"
// Version displayed to user
#define VERSION_STRING "5.1a"
// Version number to compare against driver
#define VERSION_NUM 0x051a
// Version number written to volume header during format,
// specifies the minimum program version required to mount the volume
#define VOL_REQ_PROG_VERSION 0x0500
// Volume header version
#define VOLUME_HEADER_VERSION 0x0003
// Sector size of encrypted filesystem, which may differ from sector size
// of host filesystem/device (this is fully supported since v4.3).
#define SECTOR_SIZE 512
#define BYTES_PER_KB 1024LL
#define BYTES_PER_MB 1048576LL
#define BYTES_PER_GB 1073741824LL
#define BYTES_PER_TB 1099511627776LL
#define BYTES_PER_PB 1125899906842624LL
/* GUI/driver errors */
#define MAX_128BIT_BLOCK_VOLUME_SIZE BYTES_PER_PB // Security bound (128-bit block XTS mode)
#define MAX_VOLUME_SIZE_GENERAL 0x7fffFFFFffffFFFFLL // Signed 64-bit integer file offset values
#define MAX_VOLUME_SIZE MAX_128BIT_BLOCK_VOLUME_SIZE
#define MIN_FAT_VOLUME_SIZE 19456
#define MAX_FAT_VOLUME_SIZE 0x20000000000LL
#define MIN_NTFS_VOLUME_SIZE 2634752
#define OPTIMAL_MIN_NTFS_VOLUME_SIZE (4 * BYTES_PER_GB)
#define MAX_NTFS_VOLUME_SIZE (128LL * BYTES_PER_TB) // NTFS volume can theoretically be up to 16 exabytes, but Windows XP and 2003 limit the size to that addressable with 32-bit clusters, i.e. max size is 128 TB (if 64-KB clusters are used).
#define MAX_HIDDEN_VOLUME_HOST_SIZE MAX_NTFS_VOLUME_SIZE
#define MAX_HIDDEN_VOLUME_SIZE ( MAX_HIDDEN_VOLUME_HOST_SIZE - HIDDEN_VOL_HEADER_OFFSET - HEADER_SIZE )
#define MIN_VOLUME_SIZE MIN_FAT_VOLUME_SIZE
#define MIN_HIDDEN_VOLUME_HOST_SIZE ( MIN_VOLUME_SIZE * 2 + HIDDEN_VOL_HEADER_OFFSET + HEADER_SIZE )
#ifndef TC_NO_COMPILER_INT64
#if MAX_VOLUME_SIZE > MAX_VOLUME_SIZE_GENERAL
#error MAX_VOLUME_SIZE must be less than or equal to MAX_VOLUME_SIZE_GENERAL
#endif
#endif
#define TCalloc(X) calloc(1, X)
#define TCfree free
#define WIDE(x) (LPWSTR)L##x
typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef uint8_t byte;
typedef uint16_t uint16;
typedef uint32_t uint32;
#ifdef TC_NO_COMPILER_INT64
typedef uint32_t TC_LARGEST_COMPILER_UINT;
#else
typedef uint64_t TC_LARGEST_COMPILER_UINT;
typedef int64_t int64;
typedef uint64_t uint64;
#endif
// Needed by Cryptolib
typedef uint8_t uint_8t;
typedef uint16_t uint_16t;
typedef uint32_t uint_32t;
#ifndef TC_NO_COMPILER_INT64
typedef uint64_t uint_64t;
#endif
typedef union
{
struct
{
uint32_t LowPart;
uint32_t HighPart;
};
#ifndef TC_NO_COMPILER_INT64
uint64_t Value;
#endif
} UINT64_STRUCT;
#define TC_THROW_FATAL_EXCEPTION *(char *) 0 = 0
#define burn(mem,size) do { volatile char *burnm = (volatile char *)(mem); int burnc = size; while (burnc--) *burnm++ = 0; } while (0)
// The size of the memory area to wipe is in bytes amd it must be a multiple of 8.
#ifndef TC_NO_COMPILER_INT64
# define FAST_ERASE64(mem,size) do { volatile uint64_t *burnm = (volatile uint64_t *)(mem); int burnc = size >> 3; while (burnc--) *burnm++ = 0; } while (0)
#else
# define FAST_ERASE64(mem,size) do { volatile uint32_t *burnm = (volatile uint32_t *)(mem); int burnc = size >> 2; while (burnc--) *burnm++ = 0; } while (0)
#endif
#ifdef MAX_PATH
#define TC_MAX_PATH MAX_PATH
#else
#define TC_MAX_PATH 260 /* Includes the null terminator */
#endif
#define MAX_URL_LENGTH 2084 /* Internet Explorer limit. Includes the terminating null character. */
enum
{
/* WARNING: Add any new codes at the end (do NOT insert them between existing). Do NOT delete any
existing codes. Changing these values or their meanings may cause incompatibility with other
versions (for example, if a new version of the TrueCrypt installer receives an error code from
an installed driver whose version is lower, it will interpret the error incorrectly). */
ERR_SUCCESS = 0,
ERR_OS_ERROR = 1,
ERR_OUTOFMEMORY,
ERR_PASSWORD_WRONG,
ERR_VOL_FORMAT_BAD,
ERR_DRIVE_NOT_FOUND,
ERR_FILES_OPEN,
ERR_VOL_SIZE_WRONG,
ERR_COMPRESSION_NOT_SUPPORTED,
ERR_PASSWORD_CHANGE_VOL_TYPE,
ERR_PASSWORD_CHANGE_VOL_VERSION,
ERR_VOL_SEEKING,
ERR_VOL_WRITING,
ERR_FILES_OPEN_LOCK,
ERR_VOL_READING,
ERR_DRIVER_VERSION,
ERR_NEW_VERSION_REQUIRED,
ERR_CIPHER_INIT_FAILURE,
ERR_CIPHER_INIT_WEAK_KEY,
ERR_SELF_TESTS_FAILED,
ERR_SECTOR_SIZE_INCOMPATIBLE,
ERR_VOL_ALREADY_MOUNTED,
ERR_NO_FREE_DRIVES,
ERR_FILE_OPEN_FAILED,
ERR_VOL_MOUNT_FAILED,
ERR_INVALID_DEVICE,
ERR_ACCESS_DENIED,
ERR_MODE_INIT_FAILED,
ERR_DONT_REPORT,
ERR_ENCRYPTION_NOT_COMPLETED,
ERR_PARAMETER_INCORRECT
};
#endif // #ifndef TCDEFS_H

627
src/utils/common/xts.c Normal file
View File

@@ -0,0 +1,627 @@
/*
Copyright (c) 2008 TrueCrypt Foundation. All rights reserved.
Governed by the TrueCrypt License 2.4 the full text of which is contained
in the file License.txt included in TrueCrypt binary and source code
distribution packages.
*/
/* For low-memory environments, define XTS_LOW_RESOURCE_VERSION, which will save
0.5 KB of RAM, but the speed will be 15-20% lower. However, on multi-core CPUs,
the XTS_LOW_RESOURCE_VERSION code might eventually be faster when parallelized,
because it processes the buffer continuously as a whole -- it does not divide the
buffer into data units (nevertheless, note that GenerateWhiteningValues supports
more than one data unit).
Note that when TC_NO_COMPILER_INT64 is defined, XTS_LOW_RESOURCE_VERSION is implicitly
defined as well (because the non-low-resource version needs 64-bit types).
For big-endian platforms (PowerPC, SPARC, etc.) define BYTE_ORDER as BIG_ENDIAN. */
#ifdef TC_MINIMIZE_CODE_SIZE
# define XTS_LOW_RESOURCE_VERSION
# pragma optimize ("tl", on)
#endif
#ifdef TC_NO_COMPILER_INT64
# ifndef XTS_LOW_RESOURCE_VERSION
# define XTS_LOW_RESOURCE_VERSION
# endif
#endif
#include "xts.h"
#ifndef XTS_LOW_RESOURCE_VERSION
// length: number of bytes to encrypt; may be larger than one data unit and must be divisible by the cipher block size
// ks: the primary key schedule
// ks2: the secondary key schedule
// startDataUnitNo: The sequential number of the data unit with which the buffer starts.
// startCipherBlockNo: The sequential number of the first plaintext block to encrypt inside the data unit startDataUnitNo.
// When encrypting the data unit from its first block, startCipherBlockNo is 0.
// The startCipherBlockNo value applies only to the first data unit in the buffer; each successive
// data unit is encrypted from its first block. The start of the buffer does not have to be
// aligned with the start of a data unit. If it is aligned, startCipherBlockNo must be 0; if it
// is not aligned, startCipherBlockNo must reflect the misalignment accordingly.
void EncryptBufferXTS (uint8_t *buffer,
TC_LARGEST_COMPILER_UINT length,
const UINT64_STRUCT *startDataUnitNo,
unsigned int startCipherBlockNo,
uint8_t *ks,
uint8_t *ks2,
int cipher)
{
uint8_t finalCarry;
uint8_t whiteningValues [ENCRYPTION_DATA_UNIT_SIZE];
uint8_t whiteningValue [BYTES_PER_XTS_BLOCK];
uint8_t byteBufUnitNo [BYTES_PER_XTS_BLOCK];
uint64_t *whiteningValuesPtr64 = (uint64_t *) whiteningValues;
uint64_t *whiteningValuePtr64 = (uint64_t *) whiteningValue;
uint64_t *bufPtr = (uint64_t *) buffer;
unsigned int startBlock = startCipherBlockNo, endBlock, block;
uint64_t *const finalInt64WhiteningValuesPtr = whiteningValuesPtr64 + sizeof (whiteningValues) / sizeof (*whiteningValuesPtr64) - 1;
TC_LARGEST_COMPILER_UINT blockCount, dataUnitNo;
/* The encrypted data unit number (i.e. the resultant ciphertext block) is to be multiplied in the
finite field GF(2^128) by j-th power of n, where j is the sequential plaintext/ciphertext block
number and n is 2, a primitive element of GF(2^128). This can be (and is) simplified and implemented
as a left shift of the preceding whitening value by one bit (with carry propagating). In addition, if
the shift of the highest byte results in a carry, 135 is XORed into the lowest byte. The value 135 is
derived from the modulus of the Galois Field (x^128+x^7+x^2+x+1). */
// Convert the 64-bit data unit number into a little-endian 16-byte array.
// Note that as we are converting a 64-bit number into a 16-byte array we can always zero the last 8 bytes.
dataUnitNo = startDataUnitNo->Value;
*((uint64_t *) byteBufUnitNo) = LE64 (dataUnitNo);
*((uint64_t *) byteBufUnitNo + 1) = 0;
if (length % BYTES_PER_XTS_BLOCK)
TC_THROW_FATAL_EXCEPTION;
blockCount = length / BYTES_PER_XTS_BLOCK;
// Process all blocks in the buffer
// When length > ENCRYPTION_DATA_UNIT_SIZE, this can be parallelized (one data unit per core)
while (blockCount > 0)
{
if (blockCount < BLOCKS_PER_XTS_DATA_UNIT)
endBlock = startBlock + (unsigned int) blockCount;
else
endBlock = BLOCKS_PER_XTS_DATA_UNIT;
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
whiteningValuePtr64 = (uint64_t *) whiteningValue;
// Encrypt the data unit number using the secondary key (in order to generate the first
// whitening value for this data unit)
*whiteningValuePtr64 = *((uint64_t *) byteBufUnitNo);
*(whiteningValuePtr64 + 1) = 0;
EncipherBlock (cipher, whiteningValue, ks2);
// Generate subsequent whitening values for blocks in this data unit. Note that all generated 128-bit
// whitening values are stored in memory as a sequence of 64-bit integers in reverse order.
for (block = 0; block < endBlock; block++)
{
if (block >= startBlock)
{
*whiteningValuesPtr64-- = *whiteningValuePtr64++;
*whiteningValuesPtr64-- = *whiteningValuePtr64;
}
else
whiteningValuePtr64++;
// Derive the next whitening value
#if BYTE_ORDER == LITTLE_ENDIAN
// Little-endian platforms (Intel, AMD, etc.)
finalCarry =
(*whiteningValuePtr64 & 0x8000000000000000) ?
135 : 0;
*whiteningValuePtr64-- <<= 1;
if (*whiteningValuePtr64 & 0x8000000000000000)
*(whiteningValuePtr64 + 1) |= 1;
*whiteningValuePtr64 <<= 1;
#else
// Big-endian platforms (PowerPC, Motorola, etc.)
finalCarry =
(*whiteningValuePtr64 & 0x80) ?
135 : 0;
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
whiteningValuePtr64--;
if (*whiteningValuePtr64 & 0x80)
*(whiteningValuePtr64 + 1) |= 0x0100000000000000;
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
#endif
whiteningValue[0] ^= finalCarry;
}
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
// Encrypt all blocks in this data unit
// TO DO: This should be parallelized (one block per core)
for (block = startBlock; block < endBlock; block++)
{
// Pre-whitening
*bufPtr++ ^= *whiteningValuesPtr64--;
*bufPtr-- ^= *whiteningValuesPtr64++;
// Actual encryption
EncipherBlock (cipher, bufPtr, ks);
// Post-whitening
*bufPtr++ ^= *whiteningValuesPtr64--;
*bufPtr++ ^= *whiteningValuesPtr64--;
blockCount--;
}
startBlock = 0;
dataUnitNo++;
*((uint64_t *) byteBufUnitNo) = LE64 (dataUnitNo);
}
FAST_ERASE64 (whiteningValue, sizeof(whiteningValue));
FAST_ERASE64 (whiteningValues, sizeof(whiteningValues));
}
// For descriptions of the input parameters, see EncryptBufferXTS().
void DecryptBufferXTS (uint8_t *buffer,
TC_LARGEST_COMPILER_UINT length,
const UINT64_STRUCT *startDataUnitNo,
unsigned int startCipherBlockNo,
uint8_t *ks,
uint8_t *ks2,
int cipher)
{
uint8_t finalCarry;
uint8_t whiteningValues [ENCRYPTION_DATA_UNIT_SIZE];
uint8_t whiteningValue [BYTES_PER_XTS_BLOCK];
uint8_t byteBufUnitNo [BYTES_PER_XTS_BLOCK];
uint64_t *whiteningValuesPtr64 = (uint64_t *) whiteningValues;
uint64_t *whiteningValuePtr64 = (uint64_t *) whiteningValue;
uint64_t *bufPtr = (uint64_t *) buffer;
unsigned int startBlock = startCipherBlockNo, endBlock, block;
uint64_t *const finalInt64WhiteningValuesPtr = whiteningValuesPtr64 + sizeof (whiteningValues) / sizeof (*whiteningValuesPtr64) - 1;
TC_LARGEST_COMPILER_UINT blockCount, dataUnitNo;
// Convert the 64-bit data unit number into a little-endian 16-byte array.
// Note that as we are converting a 64-bit number into a 16-byte array we can always zero the last 8 bytes.
dataUnitNo = startDataUnitNo->Value;
*((uint64_t *) byteBufUnitNo) = LE64 (dataUnitNo);
*((uint64_t *) byteBufUnitNo + 1) = 0;
if (length % BYTES_PER_XTS_BLOCK)
TC_THROW_FATAL_EXCEPTION;
blockCount = length / BYTES_PER_XTS_BLOCK;
// Process all blocks in the buffer
// When length > ENCRYPTION_DATA_UNIT_SIZE, this can be parallelized (one data unit per core)
while (blockCount > 0)
{
if (blockCount < BLOCKS_PER_XTS_DATA_UNIT)
endBlock = startBlock + (unsigned int) blockCount;
else
endBlock = BLOCKS_PER_XTS_DATA_UNIT;
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
whiteningValuePtr64 = (uint64_t *) whiteningValue;
// Encrypt the data unit number using the secondary key (in order to generate the first
// whitening value for this data unit)
*whiteningValuePtr64 = *((uint64_t *) byteBufUnitNo);
*(whiteningValuePtr64 + 1) = 0;
EncipherBlock (cipher, whiteningValue, ks2);
// Generate subsequent whitening values for blocks in this data unit. Note that all generated 128-bit
// whitening values are stored in memory as a sequence of 64-bit integers in reverse order.
for (block = 0; block < endBlock; block++)
{
if (block >= startBlock)
{
*whiteningValuesPtr64-- = *whiteningValuePtr64++;
*whiteningValuesPtr64-- = *whiteningValuePtr64;
}
else
whiteningValuePtr64++;
// Derive the next whitening value
#if BYTE_ORDER == LITTLE_ENDIAN
// Little-endian platforms (Intel, AMD, etc.)
finalCarry =
(*whiteningValuePtr64 & 0x8000000000000000) ?
135 : 0;
*whiteningValuePtr64-- <<= 1;
if (*whiteningValuePtr64 & 0x8000000000000000)
*(whiteningValuePtr64 + 1) |= 1;
*whiteningValuePtr64 <<= 1;
#else
// Big-endian platforms (PowerPC, Motorola, etc.)
finalCarry =
(*whiteningValuePtr64 & 0x80) ?
135 : 0;
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
whiteningValuePtr64--;
if (*whiteningValuePtr64 & 0x80)
*(whiteningValuePtr64 + 1) |= 0x0100000000000000;
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
#endif
whiteningValue[0] ^= finalCarry;
}
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
// Decrypt blocks in this data unit
// TO DO: This should be parallelized (one block per core)
for (block = startBlock; block < endBlock; block++)
{
*bufPtr++ ^= *whiteningValuesPtr64--;
*bufPtr-- ^= *whiteningValuesPtr64++;
DecipherBlock (cipher, bufPtr, ks);
*bufPtr++ ^= *whiteningValuesPtr64--;
*bufPtr++ ^= *whiteningValuesPtr64--;
blockCount--;
}
startBlock = 0;
dataUnitNo++;
*((uint64_t *) byteBufUnitNo) = LE64 (dataUnitNo);
}
FAST_ERASE64 (whiteningValue, sizeof(whiteningValue));
FAST_ERASE64 (whiteningValues, sizeof(whiteningValues));
}
#if 0 // The following function is currently unused but may be useful in future
// Generates XTS whitening values. Use this function if you need to generate whitening values for more than
// one data unit in one pass (the value 'length' may be greater than the data unit size). 'buffer' must point
// to the LAST 8 bytes of the buffer for the whitening values. Note that the generated 128-bit whitening values
// are stored in memory as a sequence of 64-bit integers in reverse order. For descriptions of the input
// parameters, see EncryptBufferXTS().
static void GenerateWhiteningValues (uint64_t *bufPtr64,
TC_LARGEST_COMPILER_UINT length,
const UINT64_STRUCT *startDataUnitNo,
unsigned int startBlock,
uint8_t *ks2,
int cipher)
{
unsigned int block;
unsigned int endBlock;
uint8_t byteBufUnitNo [BYTES_PER_XTS_BLOCK];
uint8_t whiteningValue [BYTES_PER_XTS_BLOCK];
uint64_t *whiteningValuePtr64 = (uint64_t *) whiteningValue;
uint8_t finalCarry;
uint64_t *const finalInt64WhiteningValuePtr = whiteningValuePtr64 + sizeof (whiteningValue) / sizeof (*whiteningValuePtr64) - 1;
TC_LARGEST_COMPILER_UINT blockCount, dataUnitNo;
dataUnitNo = startDataUnitNo->Value;
blockCount = length / BYTES_PER_XTS_BLOCK;
// Convert the 64-bit data unit number into a little-endian 16-byte array.
// Note that as we are converting a 64-bit number into a 16-byte array we can always zero the last 8 bytes.
*((uint64_t *) byteBufUnitNo) = LE64 (dataUnitNo);
*((uint64_t *) byteBufUnitNo + 1) = 0;
// Generate the whitening values.
// When length > ENCRYPTION_DATA_UNIT_SIZE, this can be parallelized (one data unit per core)
while (blockCount > 0)
{
if (blockCount < BLOCKS_PER_XTS_DATA_UNIT)
endBlock = startBlock + (unsigned int) blockCount;
else
endBlock = BLOCKS_PER_XTS_DATA_UNIT;
// Encrypt the data unit number using the secondary key (in order to generate the first
// whitening value for this data unit)
memcpy (whiteningValue, byteBufUnitNo, BYTES_PER_XTS_BLOCK);
EncipherBlock (cipher, whiteningValue, ks2);
// Process all blocks in this data unit
for (block = 0; block < endBlock; block++)
{
if (block >= startBlock)
{
whiteningValuePtr64 = (uint64_t *) whiteningValue;
*bufPtr64-- = *whiteningValuePtr64++;
*bufPtr64-- = *whiteningValuePtr64;
blockCount--;
}
// Derive the next whitening value
whiteningValuePtr64 = finalInt64WhiteningValuePtr;
#if BYTE_ORDER == LITTLE_ENDIAN
// Little-endian platforms (Intel, AMD, etc.)
finalCarry =
(*whiteningValuePtr64 & 0x8000000000000000) ?
135 : 0;
*whiteningValuePtr64-- <<= 1;
if (*whiteningValuePtr64 & 0x8000000000000000)
*(whiteningValuePtr64 + 1) |= 1;
*whiteningValuePtr64 <<= 1;
#else
// Big-endian platforms (PowerPC, Motorola, etc.)
finalCarry =
(*whiteningValuePtr64 & 0x80) ?
135 : 0;
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
whiteningValuePtr64--;
if (*whiteningValuePtr64 & 0x80)
*(whiteningValuePtr64 + 1) |= 0x0100000000000000;
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
#endif
whiteningValue[0] ^= finalCarry;
}
startBlock = 0;
dataUnitNo++;
// Convert the 64-bit data unit number into a little-endian 16-byte array.
*((uint64_t *) byteBufUnitNo) = LE64 (dataUnitNo);
}
FAST_ERASE64 (whiteningValue, sizeof(whiteningValue));
}
#endif // #if 0
#else // XTS_LOW_RESOURCE_VERSION
#if BYTE_ORDER == BIG_ENDIAN
#error XTS_LOW_RESOURCE_VERSION is not compatible with big-endian platforms
#endif
// Increases a 64-bit value by one in a way compatible with non-64-bit environments/platforms
static void IncUint64Struct (UINT64_STRUCT *uint64Struct)
{
#ifdef TC_NO_COMPILER_INT64
if (!++uint64Struct->LowPart)
{
uint64Struct->HighPart++;
}
#else
uint64Struct->Value++;
#endif
}
// Converts a 64-bit unsigned integer (passed as two 32-bit integers for compatibility with non-64-bit
// environments/platforms) into a little-endian 16-byte array.
static void Uint64ToLE16ByteArray (uint8_t *byteBuf, unsigned __int32 highInt32, unsigned __int32 lowInt32)
{
unsigned __int32 *bufPtr32 = (unsigned __int32 *) byteBuf;
*bufPtr32++ = lowInt32;
*bufPtr32++ = highInt32;
// We're converting a 64-bit number into a little-endian 16-byte array so we can zero the last 8 bytes
*bufPtr32++ = 0;
*bufPtr32 = 0;
}
// Generates and XORs XTS whitening values into blocks in the buffer.
// For descriptions of the input parameters, see EncryptBufferXTS().
static void WhiteningPass (uint8_t *buffer,
TC_LARGEST_COMPILER_UINT length,
const UINT64_STRUCT *startDataUnitNo,
unsigned int startBlock,
uint8_t *ks2,
int cipher)
{
TC_LARGEST_COMPILER_UINT blockCount;
UINT64_STRUCT dataUnitNo;
unsigned int block;
unsigned int endBlock;
uint8_t byteBufUnitNo [BYTES_PER_XTS_BLOCK];
uint8_t whiteningValue [BYTES_PER_XTS_BLOCK];
unsigned __int32 *bufPtr32 = (unsigned __int32 *) buffer;
unsigned __int32 *whiteningValuePtr32 = (unsigned __int32 *) whiteningValue;
uint8_t finalCarry;
unsigned __int32 *const finalDwordWhiteningValuePtr = whiteningValuePtr32 + sizeof (whiteningValue) / sizeof (*whiteningValuePtr32) - 1;
// Store the 64-bit data unit number in a way compatible with non-64-bit environments/platforms
dataUnitNo.HighPart = startDataUnitNo->HighPart;
dataUnitNo.LowPart = startDataUnitNo->LowPart;
blockCount = length / BYTES_PER_XTS_BLOCK;
// Convert the 64-bit data unit number into a little-endian 16-byte array.
// (Passed as two 32-bit integers for compatibility with non-64-bit environments/platforms.)
Uint64ToLE16ByteArray (byteBufUnitNo, dataUnitNo.HighPart, dataUnitNo.LowPart);
// Generate whitening values for all blocks in the buffer
while (blockCount > 0)
{
if (blockCount < BLOCKS_PER_XTS_DATA_UNIT)
endBlock = startBlock + (unsigned int) blockCount;
else
endBlock = BLOCKS_PER_XTS_DATA_UNIT;
// Encrypt the data unit number using the secondary key (in order to generate the first
// whitening value for this data unit)
memcpy (whiteningValue, byteBufUnitNo, BYTES_PER_XTS_BLOCK);
EncipherBlock (cipher, whiteningValue, ks2);
// Generate subsequent whitening values and XOR each whitening value into corresponding
// ciphertext/plaintext block
for (block = 0; block < endBlock; block++)
{
if (block >= startBlock)
{
whiteningValuePtr32 = (unsigned __int32 *) whiteningValue;
// XOR the whitening value into this ciphertext/plaintext block
*bufPtr32++ ^= *whiteningValuePtr32++;
*bufPtr32++ ^= *whiteningValuePtr32++;
*bufPtr32++ ^= *whiteningValuePtr32++;
*bufPtr32++ ^= *whiteningValuePtr32;
blockCount--;
}
// Derive the next whitening value
finalCarry = 0;
for (whiteningValuePtr32 = finalDwordWhiteningValuePtr;
whiteningValuePtr32 >= (unsigned __int32 *) whiteningValue;
whiteningValuePtr32--)
{
if (*whiteningValuePtr32 & 0x80000000) // If the following shift results in a carry
{
if (whiteningValuePtr32 != finalDwordWhiteningValuePtr) // If not processing the highest double word
{
// A regular carry
*(whiteningValuePtr32 + 1) |= 1;
}
else
{
// The highest byte shift will result in a carry
finalCarry = 135;
}
}
*whiteningValuePtr32 <<= 1;
}
whiteningValue[0] ^= finalCarry;
}
startBlock = 0;
// Increase the data unit number by one
IncUint64Struct (&dataUnitNo);
// Convert the 64-bit data unit number into a little-endian 16-byte array.
Uint64ToLE16ByteArray (byteBufUnitNo, dataUnitNo.HighPart, dataUnitNo.LowPart);
}
FAST_ERASE64 (whiteningValue, sizeof(whiteningValue));
}
// length: number of bytes to encrypt; may be larger than one data unit and must be divisible by the cipher block size
// ks: the primary key schedule
// ks2: the secondary key schedule
// dataUnitNo: The sequential number of the data unit with which the buffer starts.
// startCipherBlockNo: The sequential number of the first plaintext block to encrypt inside the data unit dataUnitNo.
// When encrypting the data unit from its first block, startCipherBlockNo is 0.
// The startCipherBlockNo value applies only to the first data unit in the buffer; each successive
// data unit is encrypted from its first block. The start of the buffer does not have to be
// aligned with the start of a data unit. If it is aligned, startCipherBlockNo must be 0; if it
// is not aligned, startCipherBlockNo must reflect the misalignment accordingly.
void EncryptBufferXTS (uint8_t *buffer,
TC_LARGEST_COMPILER_UINT length,
const UINT64_STRUCT *dataUnitNo,
unsigned int startCipherBlockNo,
uint8_t *ks,
uint8_t *ks2,
int cipher)
{
TC_LARGEST_COMPILER_UINT blockCount;
uint8_t *bufPtr = buffer;
if (length % BYTES_PER_XTS_BLOCK)
TC_THROW_FATAL_EXCEPTION;
// Pre-whitening (all plaintext blocks in the buffer)
WhiteningPass (buffer, length, dataUnitNo, startCipherBlockNo, ks2, cipher);
// Encrypt all plaintext blocks in the buffer
for (blockCount = 0; blockCount < length / BYTES_PER_XTS_BLOCK; blockCount++)
{
EncipherBlock (cipher, bufPtr, ks);
bufPtr += BYTES_PER_XTS_BLOCK;
}
// Post-whitening (all ciphertext blocks in the buffer)
WhiteningPass (buffer, length, dataUnitNo, startCipherBlockNo, ks2, cipher);
}
// For descriptions of the input parameters, see EncryptBufferXTS().
void DecryptBufferXTS (uint8_t *buffer,
TC_LARGEST_COMPILER_UINT length,
const UINT64_STRUCT *dataUnitNo,
unsigned int startCipherBlockNo,
uint8_t *ks,
uint8_t *ks2,
int cipher)
{
TC_LARGEST_COMPILER_UINT blockCount;
uint8_t *bufPtr = buffer;
if (length % BYTES_PER_XTS_BLOCK)
TC_THROW_FATAL_EXCEPTION;
WhiteningPass (buffer, length, dataUnitNo, startCipherBlockNo, ks2, cipher);
for (blockCount = 0; blockCount < length / BYTES_PER_XTS_BLOCK; blockCount++)
{
DecipherBlock (cipher, bufPtr, ks);
bufPtr += BYTES_PER_XTS_BLOCK;
}
WhiteningPass (buffer, length, dataUnitNo, startCipherBlockNo, ks2, cipher);
}
#endif // XTS_LOW_RESOURCE_VERSION

79
src/utils/common/xts.h Normal file
View File

@@ -0,0 +1,79 @@
/*
Copyright (c) 2008 TrueCrypt Foundation. All rights reserved.
Governed by the TrueCrypt License 2.4 the full text of which is contained
in the file License.txt included in TrueCrypt binary and source code
distribution packages.
*/
#ifndef XTS_H
#define XTS_H
// Header files (optional)
#include <inttypes.h>
#include "tcdefs.h"
#include "../common/endian.h"
#include "crypto.h"
#ifdef __cplusplus
extern "C" {
#endif
// Macros
#ifndef LITTLE_ENDIAN
# define LITTLE_ENDIAN 1
#endif
#ifndef BIG_ENDIAN
# define BIG_ENDIAN 2
#endif
#ifndef BYTE_ORDER
# define BYTE_ORDER LITTLE_ENDIAN
#endif
#ifndef LE64
# if BYTE_ORDER == LITTLE_ENDIAN
# define LE64(x) (x)
# endif
#endif
// Custom data types
#ifndef TC_LARGEST_COMPILER_UINT
# ifdef TC_NO_COMPILER_INT64
typedef uint32_t TC_LARGEST_COMPILER_UINT;
# else
typedef uint64_t TC_LARGEST_COMPILER_UINT;
# endif
#endif
#ifndef TCDEFS_H
typedef union
{
struct
{
uint32_t LowPart;
uint32_t HighPart;
};
# ifndef TC_NO_COMPILER_INT64
uint64_t Value;
# endif
} UINT64_STRUCT;
#endif
// Public function prototypes
void EncryptBufferXTS (uint8_t *buffer, TC_LARGEST_COMPILER_UINT length, const UINT64_STRUCT *startDataUnitNo, unsigned int startCipherBlockNo, uint8_t *ks, uint8_t *ks2, int cipher);
void DecryptBufferXTS (uint8_t *buffer, TC_LARGEST_COMPILER_UINT length, const UINT64_STRUCT *startDataUnitNo, unsigned int startCipherBlockNo, uint8_t *ks, uint8_t *ks2, int cipher);
#ifdef __cplusplus
}
#endif
#endif // #ifndef XTS_H

215
src/utils/crypto/aes.h Normal file
View File

@@ -0,0 +1,215 @@
/*
---------------------------------------------------------------------------
Copyright (c) 1998-2007, Brian Gladman, Worcester, UK. All rights reserved.
LICENSE TERMS
The free distribution and use of this software is allowed (with or without
changes) provided that:
1. source code distributions include the above copyright notice, this
list of conditions and the following disclaimer;
2. binary distributions include the above copyright notice, this list
of conditions and the following disclaimer in their documentation;
3. the name of the copyright holder is not used to endorse products
built using this software without specific written permission.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue Date: 20/12/2007
This file contains the definitions required to use AES in C. See aesopt.h
for optimisation details.
*/
/* Adapted by the TrueCrypt Foundation */
#ifndef _AES_H
#define _AES_H
#include "../common/tcdefs.h"
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
#endif
#define INT_RETURN int
#if defined(__cplusplus)
extern "C"
{
#endif
#define AES_128 /* define if AES with 128 bit keys is needed */
#define AES_192 /* define if AES with 192 bit keys is needed */
#define AES_256 /* define if AES with 256 bit keys is needed */
#define AES_VAR /* define if a variable key size is needed */
// #define AES_MODES /* define if support is needed for modes */
/* The following must also be set in assembler files if being used */
#define AES_ENCRYPT /* if support for encryption is needed */
#define AES_DECRYPT /* if support for decryption is needed */
#define AES_ERR_CHK /* for parameter checks & error return codes */
#define AES_REV_DKS /* define to reverse decryption key schedule */
#define AES_BLOCK_SIZE 16 /* the AES block size in bytes */
#define N_COLS 4 /* the number of columns in the state */
/* The key schedule length is 11, 13 or 15 16-byte blocks for 128, */
/* 192 or 256-bit keys respectively. That is 176, 208 or 240 bytes */
/* or 44, 52 or 60 32-bit words. */
#if defined( AES_VAR ) || defined( AES_256 )
#define KS_LENGTH 60
#elif defined( AES_192 )
#define KS_LENGTH 52
#else
#define KS_LENGTH 44
#endif
#if defined( AES_ERR_CHK )
#define AES_RETURN INT_RETURN
#else
#define AES_RETURN VOID_RETURN
#endif
/* the character array 'inf' in the following structures is used */
/* to hold AES context information. This AES code uses cx->inf.b[0] */
/* to hold the number of rounds multiplied by 16. The other three */
/* elements can be used by code that implements additional modes */
typedef union
{ uint_32t l;
uint_8t b[4];
} aes_inf;
typedef struct
{ uint_32t ks[KS_LENGTH];
aes_inf inf;
} aes_encrypt_ctx;
typedef struct
{ uint_32t ks[KS_LENGTH];
aes_inf inf;
} aes_decrypt_ctx;
/* This routine must be called before first use if non-static */
/* tables are being used */
AES_RETURN aes_init(void);
/* Key lengths in the range 16 <= key_len <= 32 are given in bytes, */
/* those in the range 128 <= key_len <= 256 are given in bits */
#if defined( AES_ENCRYPT )
#if defined(AES_128) || defined(AES_VAR)
AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]);
#endif
#if defined(AES_192) || defined(AES_VAR)
AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]);
#endif
#if defined(AES_256) || defined(AES_VAR)
AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);
#endif
#if defined(AES_VAR)
AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]);
#endif
AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]);
#endif
#if defined( AES_DECRYPT )
#if defined(AES_128) || defined(AES_VAR)
AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]);
#endif
#if defined(AES_192) || defined(AES_VAR)
AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]);
#endif
#if defined(AES_256) || defined(AES_VAR)
AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);
#endif
#if defined(AES_VAR)
AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]);
#endif
AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]);
#endif
#if defined(AES_MODES)
/* Multiple calls to the following subroutines for multiple block */
/* ECB, CBC, CFB, OFB and CTR mode encryption can be used to handle */
/* long messages incremantally provided that the context AND the iv */
/* are preserved between all such calls. For the ECB and CBC modes */
/* each individual call within a series of incremental calls must */
/* process only full blocks (i.e. len must be a multiple of 16) but */
/* the CFB, OFB and CTR mode calls can handle multiple incremental */
/* calls of any length. Each mode is reset when a new AES key is */
/* set but ECB and CBC operations can be reset without setting a */
/* new key by setting a new IV value. To reset CFB, OFB and CTR */
/* without setting the key, aes_mode_reset() must be called and the */
/* IV must be set. NOTE: All these calls update the IV on exit so */
/* this has to be reset if a new operation with the same IV as the */
/* previous one is required (or decryption follows encryption with */
/* the same IV array). */
AES_RETURN aes_test_alignment_detection(unsigned int n);
AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
int len, const aes_encrypt_ctx cx[1]);
AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
int len, const aes_decrypt_ctx cx[1]);
AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
int len, unsigned char *iv, const aes_encrypt_ctx cx[1]);
AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,
int len, unsigned char *iv, const aes_decrypt_ctx cx[1]);
AES_RETURN aes_mode_reset(aes_encrypt_ctx cx[1]);
AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
#define aes_ofb_encrypt aes_ofb_crypt
#define aes_ofb_decrypt aes_ofb_crypt
AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,
int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
typedef void cbuf_inc(unsigned char *cbuf);
#define aes_ctr_encrypt aes_ctr_crypt
#define aes_ctr_decrypt aes_ctr_crypt
AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,
int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1]);
#endif
#if defined(__cplusplus)
}
#endif
#endif

View File

@@ -0,0 +1,904 @@
; ---------------------------------------------------------------------------
; Copyright (c) 1998-2007, Brian Gladman, Worcester, UK. All rights reserved.
;
; LICENSE TERMS
;
; The free distribution and use of this software is allowed (with or without
; changes) provided that:
;
; 1. source code distributions include the above copyright notice, this
; list of conditions and the following disclaimer;
;
; 2. binary distributions include the above copyright notice, this list
; of conditions and the following disclaimer in their documentation;
;
; 3. the name of the copyright holder is not used to endorse products
; built using this software without specific written permission.
;
; DISCLAIMER
;
; This software is provided 'as is' with no explicit or implied warranties
; in respect of its properties, including, but not limited to, correctness
; and/or fitness for purpose.
; ---------------------------------------------------------------------------
; Issue 20/12/2007
;
; I am grateful to Dag Arne Osvik for many discussions of the techniques that
; can be used to optimise AES assembler code on AMD64/EM64T architectures.
; Some of the techniques used in this implementation are the result of
; suggestions made by him for which I am most grateful.
; An AES implementation for AMD64 processors using the YASM assembler. This
; implemetation provides only encryption, decryption and hence requires key
; scheduling support in C. It uses 8k bytes of tables but its encryption and
; decryption performance is very close to that obtained using large tables.
; It can use either Windows or Gnu/Linux calling conventions, which are as
; follows:
; windows gnu/linux
;
; in_blk rcx rdi
; out_blk rdx rsi
; context (cx) r8 rdx
;
; preserved rsi - + rbx, rbp, rsp, r12, r13, r14 & r15
; registers rdi - on both
;
; destroyed - rsi + rax, rcx, rdx, r8, r9, r10 & r11
; registers - rdi on both
;
; The default convention is that for windows, the gnu/linux convention being
; used if __GNUC__ is defined.
;
; Define _SEH_ to include support for Win64 structured exception handling
; (this requires YASM version 0.6 or later).
;
; This code provides the standard AES block size (128 bits, 16 bytes) and the
; three standard AES key sizes (128, 192 and 256 bits). It has the same call
; interface as my C implementation. It uses the Microsoft C AMD64 calling
; conventions in which the three parameters are placed in rcx, rdx and r8
; respectively. The rbx, rsi, rdi, rbp and r12..r15 registers are preserved.
;
; AES_RETURN aes_encrypt(const unsigned char in_blk[],
; unsigned char out_blk[], const aes_encrypt_ctx cx[1]);
;
; AES_RETURN aes_decrypt(const unsigned char in_blk[],
; unsigned char out_blk[], const aes_decrypt_ctx cx[1]);
;
; AES_RETURN aes_encrypt_key<NNN>(const unsigned char key[],
; const aes_encrypt_ctx cx[1]);
;
; AES_RETURN aes_decrypt_key<NNN>(const unsigned char key[],
; const aes_decrypt_ctx cx[1]);
;
; AES_RETURN aes_encrypt_key(const unsigned char key[],
; unsigned int len, const aes_decrypt_ctx cx[1]);
;
; AES_RETURN aes_decrypt_key(const unsigned char key[],
; unsigned int len, const aes_decrypt_ctx cx[1]);
;
; where <NNN> is 128, 102 or 256. In the last two calls the length can be in
; either bits or bytes.
;
; Comment in/out the following lines to obtain the desired subroutines. These
; selections MUST match those in the C header file aes.h
; %define AES_128 ; define if AES with 128 bit keys is needed
; %define AES_192 ; define if AES with 192 bit keys is needed
%define AES_256 ; define if AES with 256 bit keys is needed
; %define AES_VAR ; define if a variable key size is needed
%define ENCRYPTION ; define if encryption is needed
%define DECRYPTION ; define if decryption is needed
%define AES_REV_DKS ; define if key decryption schedule is reversed
%define LAST_ROUND_TABLES ; define for the faster version using extra tables
; The encryption key schedule has the following in memory layout where N is the
; number of rounds (10, 12 or 14):
;
; lo: | input key (round 0) | ; each round is four 32-bit words
; | encryption round 1 |
; | encryption round 2 |
; ....
; | encryption round N-1 |
; hi: | encryption round N |
;
; The decryption key schedule is normally set up so that it has the same
; layout as above by actually reversing the order of the encryption key
; schedule in memory (this happens when AES_REV_DKS is set):
;
; lo: | decryption round 0 | = | encryption round N |
; | decryption round 1 | = INV_MIX_COL[ | encryption round N-1 | ]
; | decryption round 2 | = INV_MIX_COL[ | encryption round N-2 | ]
; .... ....
; | decryption round N-1 | = INV_MIX_COL[ | encryption round 1 | ]
; hi: | decryption round N | = | input key (round 0) |
;
; with rounds except the first and last modified using inv_mix_column()
; But if AES_REV_DKS is NOT set the order of keys is left as it is for
; encryption so that it has to be accessed in reverse when used for
; decryption (although the inverse mix column modifications are done)
;
; lo: | decryption round 0 | = | input key (round 0) |
; | decryption round 1 | = INV_MIX_COL[ | encryption round 1 | ]
; | decryption round 2 | = INV_MIX_COL[ | encryption round 2 | ]
; .... ....
; | decryption round N-1 | = INV_MIX_COL[ | encryption round N-1 | ]
; hi: | decryption round N | = | encryption round N |
;
; This layout is faster when the assembler key scheduling provided here
; is used.
;
; The DLL interface must use the _stdcall convention in which the number
; of bytes of parameter space is added after an @ to the sutine's name.
; We must also remove our parameters from the stack before return (see
; the do_exit macro). Define DLL_EXPORT for the Dynamic Link Library version.
;%define DLL_EXPORT
; End of user defines
%ifdef AES_VAR
%ifndef AES_128
%define AES_128
%endif
%ifndef AES_192
%define AES_192
%endif
%ifndef AES_256
%define AES_256
%endif
%endif
%ifdef AES_VAR
%define KS_LENGTH 60
%elifdef AES_256
%define KS_LENGTH 60
%elifdef AES_192
%define KS_LENGTH 52
%else
%define KS_LENGTH 44
%endif
%define r0 rax
%define r1 rdx
%define r2 rcx
%define r3 rbx
%define r4 rsi
%define r5 rdi
%define r6 rbp
%define r7 rsp
%define raxd eax
%define rdxd edx
%define rcxd ecx
%define rbxd ebx
%define rsid esi
%define rdid edi
%define rbpd ebp
%define rspd esp
%define raxb al
%define rdxb dl
%define rcxb cl
%define rbxb bl
%define rsib sil
%define rdib dil
%define rbpb bpl
%define rspb spl
%define r0h ah
%define r1h dh
%define r2h ch
%define r3h bh
%define r0d eax
%define r1d edx
%define r2d ecx
%define r3d ebx
; finite field multiplies by {02}, {04} and {08}
%define f2(x) ((x<<1)^(((x>>7)&1)*0x11b))
%define f4(x) ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b))
%define f8(x) ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b))
; finite field multiplies required in table generation
%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))
; macro for expanding S-box data
%macro enc_vals 1
db %1(0x63),%1(0x7c),%1(0x77),%1(0x7b),%1(0xf2),%1(0x6b),%1(0x6f),%1(0xc5)
db %1(0x30),%1(0x01),%1(0x67),%1(0x2b),%1(0xfe),%1(0xd7),%1(0xab),%1(0x76)
db %1(0xca),%1(0x82),%1(0xc9),%1(0x7d),%1(0xfa),%1(0x59),%1(0x47),%1(0xf0)
db %1(0xad),%1(0xd4),%1(0xa2),%1(0xaf),%1(0x9c),%1(0xa4),%1(0x72),%1(0xc0)
db %1(0xb7),%1(0xfd),%1(0x93),%1(0x26),%1(0x36),%1(0x3f),%1(0xf7),%1(0xcc)
db %1(0x34),%1(0xa5),%1(0xe5),%1(0xf1),%1(0x71),%1(0xd8),%1(0x31),%1(0x15)
db %1(0x04),%1(0xc7),%1(0x23),%1(0xc3),%1(0x18),%1(0x96),%1(0x05),%1(0x9a)
db %1(0x07),%1(0x12),%1(0x80),%1(0xe2),%1(0xeb),%1(0x27),%1(0xb2),%1(0x75)
db %1(0x09),%1(0x83),%1(0x2c),%1(0x1a),%1(0x1b),%1(0x6e),%1(0x5a),%1(0xa0)
db %1(0x52),%1(0x3b),%1(0xd6),%1(0xb3),%1(0x29),%1(0xe3),%1(0x2f),%1(0x84)
db %1(0x53),%1(0xd1),%1(0x00),%1(0xed),%1(0x20),%1(0xfc),%1(0xb1),%1(0x5b)
db %1(0x6a),%1(0xcb),%1(0xbe),%1(0x39),%1(0x4a),%1(0x4c),%1(0x58),%1(0xcf)
db %1(0xd0),%1(0xef),%1(0xaa),%1(0xfb),%1(0x43),%1(0x4d),%1(0x33),%1(0x85)
db %1(0x45),%1(0xf9),%1(0x02),%1(0x7f),%1(0x50),%1(0x3c),%1(0x9f),%1(0xa8)
db %1(0x51),%1(0xa3),%1(0x40),%1(0x8f),%1(0x92),%1(0x9d),%1(0x38),%1(0xf5)
db %1(0xbc),%1(0xb6),%1(0xda),%1(0x21),%1(0x10),%1(0xff),%1(0xf3),%1(0xd2)
db %1(0xcd),%1(0x0c),%1(0x13),%1(0xec),%1(0x5f),%1(0x97),%1(0x44),%1(0x17)
db %1(0xc4),%1(0xa7),%1(0x7e),%1(0x3d),%1(0x64),%1(0x5d),%1(0x19),%1(0x73)
db %1(0x60),%1(0x81),%1(0x4f),%1(0xdc),%1(0x22),%1(0x2a),%1(0x90),%1(0x88)
db %1(0x46),%1(0xee),%1(0xb8),%1(0x14),%1(0xde),%1(0x5e),%1(0x0b),%1(0xdb)
db %1(0xe0),%1(0x32),%1(0x3a),%1(0x0a),%1(0x49),%1(0x06),%1(0x24),%1(0x5c)
db %1(0xc2),%1(0xd3),%1(0xac),%1(0x62),%1(0x91),%1(0x95),%1(0xe4),%1(0x79)
db %1(0xe7),%1(0xc8),%1(0x37),%1(0x6d),%1(0x8d),%1(0xd5),%1(0x4e),%1(0xa9)
db %1(0x6c),%1(0x56),%1(0xf4),%1(0xea),%1(0x65),%1(0x7a),%1(0xae),%1(0x08)
db %1(0xba),%1(0x78),%1(0x25),%1(0x2e),%1(0x1c),%1(0xa6),%1(0xb4),%1(0xc6)
db %1(0xe8),%1(0xdd),%1(0x74),%1(0x1f),%1(0x4b),%1(0xbd),%1(0x8b),%1(0x8a)
db %1(0x70),%1(0x3e),%1(0xb5),%1(0x66),%1(0x48),%1(0x03),%1(0xf6),%1(0x0e)
db %1(0x61),%1(0x35),%1(0x57),%1(0xb9),%1(0x86),%1(0xc1),%1(0x1d),%1(0x9e)
db %1(0xe1),%1(0xf8),%1(0x98),%1(0x11),%1(0x69),%1(0xd9),%1(0x8e),%1(0x94)
db %1(0x9b),%1(0x1e),%1(0x87),%1(0xe9),%1(0xce),%1(0x55),%1(0x28),%1(0xdf)
db %1(0x8c),%1(0xa1),%1(0x89),%1(0x0d),%1(0xbf),%1(0xe6),%1(0x42),%1(0x68)
db %1(0x41),%1(0x99),%1(0x2d),%1(0x0f),%1(0xb0),%1(0x54),%1(0xbb),%1(0x16)
%endmacro
%macro dec_vals 1
db %1(0x52),%1(0x09),%1(0x6a),%1(0xd5),%1(0x30),%1(0x36),%1(0xa5),%1(0x38)
db %1(0xbf),%1(0x40),%1(0xa3),%1(0x9e),%1(0x81),%1(0xf3),%1(0xd7),%1(0xfb)
db %1(0x7c),%1(0xe3),%1(0x39),%1(0x82),%1(0x9b),%1(0x2f),%1(0xff),%1(0x87)
db %1(0x34),%1(0x8e),%1(0x43),%1(0x44),%1(0xc4),%1(0xde),%1(0xe9),%1(0xcb)
db %1(0x54),%1(0x7b),%1(0x94),%1(0x32),%1(0xa6),%1(0xc2),%1(0x23),%1(0x3d)
db %1(0xee),%1(0x4c),%1(0x95),%1(0x0b),%1(0x42),%1(0xfa),%1(0xc3),%1(0x4e)
db %1(0x08),%1(0x2e),%1(0xa1),%1(0x66),%1(0x28),%1(0xd9),%1(0x24),%1(0xb2)
db %1(0x76),%1(0x5b),%1(0xa2),%1(0x49),%1(0x6d),%1(0x8b),%1(0xd1),%1(0x25)
db %1(0x72),%1(0xf8),%1(0xf6),%1(0x64),%1(0x86),%1(0x68),%1(0x98),%1(0x16)
db %1(0xd4),%1(0xa4),%1(0x5c),%1(0xcc),%1(0x5d),%1(0x65),%1(0xb6),%1(0x92)
db %1(0x6c),%1(0x70),%1(0x48),%1(0x50),%1(0xfd),%1(0xed),%1(0xb9),%1(0xda)
db %1(0x5e),%1(0x15),%1(0x46),%1(0x57),%1(0xa7),%1(0x8d),%1(0x9d),%1(0x84)
db %1(0x90),%1(0xd8),%1(0xab),%1(0x00),%1(0x8c),%1(0xbc),%1(0xd3),%1(0x0a)
db %1(0xf7),%1(0xe4),%1(0x58),%1(0x05),%1(0xb8),%1(0xb3),%1(0x45),%1(0x06)
db %1(0xd0),%1(0x2c),%1(0x1e),%1(0x8f),%1(0xca),%1(0x3f),%1(0x0f),%1(0x02)
db %1(0xc1),%1(0xaf),%1(0xbd),%1(0x03),%1(0x01),%1(0x13),%1(0x8a),%1(0x6b)
db %1(0x3a),%1(0x91),%1(0x11),%1(0x41),%1(0x4f),%1(0x67),%1(0xdc),%1(0xea)
db %1(0x97),%1(0xf2),%1(0xcf),%1(0xce),%1(0xf0),%1(0xb4),%1(0xe6),%1(0x73)
db %1(0x96),%1(0xac),%1(0x74),%1(0x22),%1(0xe7),%1(0xad),%1(0x35),%1(0x85)
db %1(0xe2),%1(0xf9),%1(0x37),%1(0xe8),%1(0x1c),%1(0x75),%1(0xdf),%1(0x6e)
db %1(0x47),%1(0xf1),%1(0x1a),%1(0x71),%1(0x1d),%1(0x29),%1(0xc5),%1(0x89)
db %1(0x6f),%1(0xb7),%1(0x62),%1(0x0e),%1(0xaa),%1(0x18),%1(0xbe),%1(0x1b)
db %1(0xfc),%1(0x56),%1(0x3e),%1(0x4b),%1(0xc6),%1(0xd2),%1(0x79),%1(0x20)
db %1(0x9a),%1(0xdb),%1(0xc0),%1(0xfe),%1(0x78),%1(0xcd),%1(0x5a),%1(0xf4)
db %1(0x1f),%1(0xdd),%1(0xa8),%1(0x33),%1(0x88),%1(0x07),%1(0xc7),%1(0x31)
db %1(0xb1),%1(0x12),%1(0x10),%1(0x59),%1(0x27),%1(0x80),%1(0xec),%1(0x5f)
db %1(0x60),%1(0x51),%1(0x7f),%1(0xa9),%1(0x19),%1(0xb5),%1(0x4a),%1(0x0d)
db %1(0x2d),%1(0xe5),%1(0x7a),%1(0x9f),%1(0x93),%1(0xc9),%1(0x9c),%1(0xef)
db %1(0xa0),%1(0xe0),%1(0x3b),%1(0x4d),%1(0xae),%1(0x2a),%1(0xf5),%1(0xb0)
db %1(0xc8),%1(0xeb),%1(0xbb),%1(0x3c),%1(0x83),%1(0x53),%1(0x99),%1(0x61)
db %1(0x17),%1(0x2b),%1(0x04),%1(0x7e),%1(0xba),%1(0x77),%1(0xd6),%1(0x26)
db %1(0xe1),%1(0x69),%1(0x14),%1(0x63),%1(0x55),%1(0x21),%1(0x0c),%1(0x7d)
%endmacro
%define u8(x) f2(x), x, x, f3(x), f2(x), x, x, f3(x)
%define v8(x) fe(x), f9(x), fd(x), fb(x), fe(x), f9(x), fd(x), x
%define w8(x) x, 0, 0, 0, x, 0, 0, 0
%define tptr rbp ; table pointer
%define kptr r8 ; key schedule pointer
%define fofs 128 ; adjust offset in key schedule to keep |disp| < 128
%define fk_ref(x,y) [kptr-16*x+fofs+4*y]
%ifdef AES_REV_DKS
%define rofs 128
%define ik_ref(x,y) [kptr-16*x+rofs+4*y]
%else
%define rofs -128
%define ik_ref(x,y) [kptr+16*x+rofs+4*y]
%endif
%define tab_0(x) [tptr+8*x]
%define tab_1(x) [tptr+8*x+3]
%define tab_2(x) [tptr+8*x+2]
%define tab_3(x) [tptr+8*x+1]
%define tab_f(x) byte [tptr+8*x+1]
%define tab_i(x) byte [tptr+8*x+7]
%define t_ref(x,r) tab_ %+ x(r)
%macro ff_rnd 5 ; normal forward round
mov %1d, fk_ref(%5,0)
mov %2d, fk_ref(%5,1)
mov %3d, fk_ref(%5,2)
mov %4d, fk_ref(%5,3)
movzx esi, al
movzx edi, ah
shr eax, 16
xor %1d, t_ref(0,rsi)
xor %4d, t_ref(1,rdi)
movzx esi, al
movzx edi, ah
xor %3d, t_ref(2,rsi)
xor %2d, t_ref(3,rdi)
movzx esi, bl
movzx edi, bh
shr ebx, 16
xor %2d, t_ref(0,rsi)
xor %1d, t_ref(1,rdi)
movzx esi, bl
movzx edi, bh
xor %4d, t_ref(2,rsi)
xor %3d, t_ref(3,rdi)
movzx esi, cl
movzx edi, ch
shr ecx, 16
xor %3d, t_ref(0,rsi)
xor %2d, t_ref(1,rdi)
movzx esi, cl
movzx edi, ch
xor %1d, t_ref(2,rsi)
xor %4d, t_ref(3,rdi)
movzx esi, dl
movzx edi, dh
shr edx, 16
xor %4d, t_ref(0,rsi)
xor %3d, t_ref(1,rdi)
movzx esi, dl
movzx edi, dh
xor %2d, t_ref(2,rsi)
xor %1d, t_ref(3,rdi)
mov eax,%1d
mov ebx,%2d
mov ecx,%3d
mov edx,%4d
%endmacro
%ifdef LAST_ROUND_TABLES
%macro fl_rnd 5 ; last forward round
add tptr, 2048
mov %1d, fk_ref(%5,0)
mov %2d, fk_ref(%5,1)
mov %3d, fk_ref(%5,2)
mov %4d, fk_ref(%5,3)
movzx esi, al
movzx edi, ah
shr eax, 16
xor %1d, t_ref(0,rsi)
xor %4d, t_ref(1,rdi)
movzx esi, al
movzx edi, ah
xor %3d, t_ref(2,rsi)
xor %2d, t_ref(3,rdi)
movzx esi, bl
movzx edi, bh
shr ebx, 16
xor %2d, t_ref(0,rsi)
xor %1d, t_ref(1,rdi)
movzx esi, bl
movzx edi, bh
xor %4d, t_ref(2,rsi)
xor %3d, t_ref(3,rdi)
movzx esi, cl
movzx edi, ch
shr ecx, 16
xor %3d, t_ref(0,rsi)
xor %2d, t_ref(1,rdi)
movzx esi, cl
movzx edi, ch
xor %1d, t_ref(2,rsi)
xor %4d, t_ref(3,rdi)
movzx esi, dl
movzx edi, dh
shr edx, 16
xor %4d, t_ref(0,rsi)
xor %3d, t_ref(1,rdi)
movzx esi, dl
movzx edi, dh
xor %2d, t_ref(2,rsi)
xor %1d, t_ref(3,rdi)
%endmacro
%else
%macro fl_rnd 5 ; last forward round
mov %1d, fk_ref(%5,0)
mov %2d, fk_ref(%5,1)
mov %3d, fk_ref(%5,2)
mov %4d, fk_ref(%5,3)
movzx esi, al
movzx edi, ah
shr eax, 16
movzx esi, t_ref(f,rsi)
movzx edi, t_ref(f,rdi)
xor %1d, esi
rol edi, 8
xor %4d, edi
movzx esi, al
movzx edi, ah
movzx esi, t_ref(f,rsi)
movzx edi, t_ref(f,rdi)
rol esi, 16
rol edi, 24
xor %3d, esi
xor %2d, edi
movzx esi, bl
movzx edi, bh
shr ebx, 16
movzx esi, t_ref(f,rsi)
movzx edi, t_ref(f,rdi)
xor %2d, esi
rol edi, 8
xor %1d, edi
movzx esi, bl
movzx edi, bh
movzx esi, t_ref(f,rsi)
movzx edi, t_ref(f,rdi)
rol esi, 16
rol edi, 24
xor %4d, esi
xor %3d, edi
movzx esi, cl
movzx edi, ch
movzx esi, t_ref(f,rsi)
movzx edi, t_ref(f,rdi)
shr ecx, 16
xor %3d, esi
rol edi, 8
xor %2d, edi
movzx esi, cl
movzx edi, ch
movzx esi, t_ref(f,rsi)
movzx edi, t_ref(f,rdi)
rol esi, 16
rol edi, 24
xor %1d, esi
xor %4d, edi
movzx esi, dl
movzx edi, dh
movzx esi, t_ref(f,rsi)
movzx edi, t_ref(f,rdi)
shr edx, 16
xor %4d, esi
rol edi, 8
xor %3d, edi
movzx esi, dl
movzx edi, dh
movzx esi, t_ref(f,rsi)
movzx edi, t_ref(f,rdi)
rol esi, 16
rol edi, 24
xor %2d, esi
xor %1d, edi
%endmacro
%endif
%macro ii_rnd 5 ; normal inverse round
mov %1d, ik_ref(%5,0)
mov %2d, ik_ref(%5,1)
mov %3d, ik_ref(%5,2)
mov %4d, ik_ref(%5,3)
movzx esi, al
movzx edi, ah
shr eax, 16
xor %1d, t_ref(0,rsi)
xor %2d, t_ref(1,rdi)
movzx esi, al
movzx edi, ah
xor %3d, t_ref(2,rsi)
xor %4d, t_ref(3,rdi)
movzx esi, bl
movzx edi, bh
shr ebx, 16
xor %2d, t_ref(0,rsi)
xor %3d, t_ref(1,rdi)
movzx esi, bl
movzx edi, bh
xor %4d, t_ref(2,rsi)
xor %1d, t_ref(3,rdi)
movzx esi, cl
movzx edi, ch
shr ecx, 16
xor %3d, t_ref(0,rsi)
xor %4d, t_ref(1,rdi)
movzx esi, cl
movzx edi, ch
xor %1d, t_ref(2,rsi)
xor %2d, t_ref(3,rdi)
movzx esi, dl
movzx edi, dh
shr edx, 16
xor %4d, t_ref(0,rsi)
xor %1d, t_ref(1,rdi)
movzx esi, dl
movzx edi, dh
xor %2d, t_ref(2,rsi)
xor %3d, t_ref(3,rdi)
mov eax,%1d
mov ebx,%2d
mov ecx,%3d
mov edx,%4d
%endmacro
%ifdef LAST_ROUND_TABLES
%macro il_rnd 5 ; last inverse round
add tptr, 2048
mov %1d, ik_ref(%5,0)
mov %2d, ik_ref(%5,1)
mov %3d, ik_ref(%5,2)
mov %4d, ik_ref(%5,3)
movzx esi, al
movzx edi, ah
shr eax, 16
xor %1d, t_ref(0,rsi)
xor %2d, t_ref(1,rdi)
movzx esi, al
movzx edi, ah
xor %3d, t_ref(2,rsi)
xor %4d, t_ref(3,rdi)
movzx esi, bl
movzx edi, bh
shr ebx, 16
xor %2d, t_ref(0,rsi)
xor %3d, t_ref(1,rdi)
movzx esi, bl
movzx edi, bh
xor %4d, t_ref(2,rsi)
xor %1d, t_ref(3,rdi)
movzx esi, cl
movzx edi, ch
shr ecx, 16
xor %3d, t_ref(0,rsi)
xor %4d, t_ref(1,rdi)
movzx esi, cl
movzx edi, ch
xor %1d, t_ref(2,rsi)
xor %2d, t_ref(3,rdi)
movzx esi, dl
movzx edi, dh
shr edx, 16
xor %4d, t_ref(0,rsi)
xor %1d, t_ref(1,rdi)
movzx esi, dl
movzx edi, dh
xor %2d, t_ref(2,rsi)
xor %3d, t_ref(3,rdi)
%endmacro
%else
%macro il_rnd 5 ; last inverse round
mov %1d, ik_ref(%5,0)
mov %2d, ik_ref(%5,1)
mov %3d, ik_ref(%5,2)
mov %4d, ik_ref(%5,3)
movzx esi, al
movzx edi, ah
movzx esi, t_ref(i,rsi)
movzx edi, t_ref(i,rdi)
shr eax, 16
xor %1d, esi
rol edi, 8
xor %2d, edi
movzx esi, al
movzx edi, ah
movzx esi, t_ref(i,rsi)
movzx edi, t_ref(i,rdi)
rol esi, 16
rol edi, 24
xor %3d, esi
xor %4d, edi
movzx esi, bl
movzx edi, bh
movzx esi, t_ref(i,rsi)
movzx edi, t_ref(i,rdi)
shr ebx, 16
xor %2d, esi
rol edi, 8
xor %3d, edi
movzx esi, bl
movzx edi, bh
movzx esi, t_ref(i,rsi)
movzx edi, t_ref(i,rdi)
rol esi, 16
rol edi, 24
xor %4d, esi
xor %1d, edi
movzx esi, cl
movzx edi, ch
movzx esi, t_ref(i,rsi)
movzx edi, t_ref(i,rdi)
shr ecx, 16
xor %3d, esi
rol edi, 8
xor %4d, edi
movzx esi, cl
movzx edi, ch
movzx esi, t_ref(i,rsi)
movzx edi, t_ref(i,rdi)
rol esi, 16
rol edi, 24
xor %1d, esi
xor %2d, edi
movzx esi, dl
movzx edi, dh
movzx esi, t_ref(i,rsi)
movzx edi, t_ref(i,rdi)
shr edx, 16
xor %4d, esi
rol edi, 8
xor %1d, edi
movzx esi, dl
movzx edi, dh
movzx esi, t_ref(i,rsi)
movzx edi, t_ref(i,rdi)
rol esi, 16
rol edi, 24
xor %2d, esi
xor %3d, edi
%endmacro
%endif
%ifdef ENCRYPTION
global aes_encrypt
%ifdef DLL_EXPORT
export aes_encrypt
%endif
section .data align=64
align 64
enc_tab:
enc_vals u8
%ifdef LAST_ROUND_TABLES
enc_vals w8
%endif
section .text align=16
align 16
%ifdef _SEH_
proc_frame aes_encrypt
alloc_stack 7*8 ; 7 to align stack to 16 bytes
save_reg rsi,4*8
save_reg rdi,5*8
save_reg rbx,1*8
save_reg rbp,2*8
save_reg r12,3*8
end_prologue
mov rdi, rcx ; input pointer
mov [rsp+0*8], rdx ; output pointer
%else
aes_encrypt:
%ifdef __GNUC__
sub rsp, 4*8 ; gnu/linux binary interface
mov [rsp+0*8], rsi ; output pointer
mov r8, rdx ; context
%else
sub rsp, 6*8 ; windows binary interface
mov [rsp+4*8], rsi
mov [rsp+5*8], rdi
mov rdi, rcx ; input pointer
mov [rsp+0*8], rdx ; output pointer
%endif
mov [rsp+1*8], rbx ; input pointer in rdi
mov [rsp+2*8], rbp ; output pointer in [rsp]
mov [rsp+3*8], r12 ; context in r8
%endif
movzx esi, byte [kptr+4*KS_LENGTH]
lea tptr,[enc_tab wrt rip]
sub kptr, fofs
mov eax, [rdi+0*4]
mov ebx, [rdi+1*4]
mov ecx, [rdi+2*4]
mov edx, [rdi+3*4]
xor eax, [kptr+fofs]
xor ebx, [kptr+fofs+4]
xor ecx, [kptr+fofs+8]
xor edx, [kptr+fofs+12]
lea kptr,[kptr+rsi]
cmp esi, 10*16
je .3
cmp esi, 12*16
je .2
cmp esi, 14*16
je .1
mov rax, -1
jmp .4
.1: ff_rnd r9, r10, r11, r12, 13
ff_rnd r9, r10, r11, r12, 12
.2: ff_rnd r9, r10, r11, r12, 11
ff_rnd r9, r10, r11, r12, 10
.3: ff_rnd r9, r10, r11, r12, 9
ff_rnd r9, r10, r11, r12, 8
ff_rnd r9, r10, r11, r12, 7
ff_rnd r9, r10, r11, r12, 6
ff_rnd r9, r10, r11, r12, 5
ff_rnd r9, r10, r11, r12, 4
ff_rnd r9, r10, r11, r12, 3
ff_rnd r9, r10, r11, r12, 2
ff_rnd r9, r10, r11, r12, 1
fl_rnd r9, r10, r11, r12, 0
mov rbx, [rsp]
mov [rbx], r9d
mov [rbx+4], r10d
mov [rbx+8], r11d
mov [rbx+12], r12d
xor rax, rax
.4:
mov rbx, [rsp+1*8]
mov rbp, [rsp+2*8]
mov r12, [rsp+3*8]
%ifdef __GNUC__
add rsp, 4*8
ret
%else
mov rsi, [rsp+4*8]
mov rdi, [rsp+5*8]
%ifdef _SEH_
add rsp, 7*8
ret
endproc_frame
%else
add rsp, 6*8
ret
%endif
%endif
%endif
%ifdef DECRYPTION
global aes_decrypt
%ifdef DLL_EXPORT
export aes_decrypt
%endif
section .data
align 64
dec_tab:
dec_vals v8
%ifdef LAST_ROUND_TABLES
dec_vals w8
%endif
section .text
align 16
%ifdef _SEH_
proc_frame aes_decrypt
alloc_stack 7*8 ; 7 to align stack to 16 bytes
save_reg rsi,4*8
save_reg rdi,5*8
save_reg rbx,1*8
save_reg rbp,2*8
save_reg r12,3*8
end_prologue
mov rdi, rcx ; input pointer
mov [rsp+0*8], rdx ; output pointer
%else
aes_decrypt:
%ifdef __GNUC__
sub rsp, 4*8 ; gnu/linux binary interface
mov [rsp+0*8], rsi ; output pointer
mov r8, rdx ; context
%else
sub rsp, 6*8 ; windows binary interface
mov [rsp+4*8], rsi
mov [rsp+5*8], rdi
mov rdi, rcx ; input pointer
mov [rsp+0*8], rdx ; output pointer
%endif
mov [rsp+1*8], rbx ; input pointer in rdi
mov [rsp+2*8], rbp ; output pointer in [rsp]
mov [rsp+3*8], r12 ; context in r8
%endif
movzx esi,byte[kptr+4*KS_LENGTH]
lea tptr,[dec_tab wrt rip]
sub kptr, rofs
mov eax, [rdi+0*4]
mov ebx, [rdi+1*4]
mov ecx, [rdi+2*4]
mov edx, [rdi+3*4]
%ifdef AES_REV_DKS
mov rdi, kptr
lea kptr,[kptr+rsi]
%else
lea rdi,[kptr+rsi]
%endif
xor eax, [rdi+rofs]
xor ebx, [rdi+rofs+4]
xor ecx, [rdi+rofs+8]
xor edx, [rdi+rofs+12]
cmp esi, 10*16
je .3
cmp esi, 12*16
je .2
cmp esi, 14*16
je .1
mov rax, -1
jmp .4
.1: ii_rnd r9, r10, r11, r12, 13
ii_rnd r9, r10, r11, r12, 12
.2: ii_rnd r9, r10, r11, r12, 11
ii_rnd r9, r10, r11, r12, 10
.3: ii_rnd r9, r10, r11, r12, 9
ii_rnd r9, r10, r11, r12, 8
ii_rnd r9, r10, r11, r12, 7
ii_rnd r9, r10, r11, r12, 6
ii_rnd r9, r10, r11, r12, 5
ii_rnd r9, r10, r11, r12, 4
ii_rnd r9, r10, r11, r12, 3
ii_rnd r9, r10, r11, r12, 2
ii_rnd r9, r10, r11, r12, 1
il_rnd r9, r10, r11, r12, 0
mov rbx, [rsp]
mov [rbx], r9d
mov [rbx+4], r10d
mov [rbx+8], r11d
mov [rbx+12], r12d
xor rax, rax
.4: mov rbx, [rsp+1*8]
mov rbp, [rsp+2*8]
mov r12, [rsp+3*8]
%ifdef __GNUC__
add rsp, 4*8
ret
%else
mov rsi, [rsp+4*8]
mov rdi, [rsp+5*8]
%ifdef _SEH_
add rsp, 7*8
ret
endproc_frame
%else
add rsp, 6*8
ret
%endif
%endif
%endif
end

View File

@@ -0,0 +1,644 @@
; ---------------------------------------------------------------------------
; Copyright (c) 1998-2007, Brian Gladman, Worcester, UK. All rights reserved.
;
; LICENSE TERMS
;
; The free distribution and use of this software is allowed (with or without
; changes) provided that:
;
; 1. source code distributions include the above copyright notice, this
; list of conditions and the following disclaimer;
;
; 2. binary distributions include the above copyright notice, this list
; of conditions and the following disclaimer in their documentation;
;
; 3. the name of the copyright holder is not used to endorse products
; built using this software without specific written permission.
;
; DISCLAIMER
;
; This software is provided 'as is' with no explicit or implied warranties
; in respect of its properties, including, but not limited to, correctness
; and/or fitness for purpose.
; ---------------------------------------------------------------------------
; Issue 20/12/2007
;
; This code requires ASM_X86_V1C to be set in aesopt.h. It requires the C files
; aeskey.c and aestab.c for support.
; An AES implementation for x86 processors using the YASM (or NASM) assembler.
; This is an assembler implementation that covers encryption and decryption
; only and is intended as a replacement of the C file aescrypt.c. It hence
; requires the file aeskey.c for keying and aestab.c for the AES tables. It
; employs full tables rather than compressed tables.
; This code provides the standard AES block size (128 bits, 16 bytes) and the
; three standard AES key sizes (128, 192 and 256 bits). It has the same call
; interface as my C implementation. The ebx, esi, edi and ebp registers are
; preserved across calls but eax, ecx and edx and the artihmetic status flags
; are not. It is also important that the defines below match those used in the
; C code. This code uses the VC++ register saving conentions; if it is used
; with another compiler, conventions for using and saving registers may need to
; be checked (and calling conventions). The YASM command line for the VC++
; custom build step is:
;
; yasm -Xvc -f win32 -o "$(TargetDir)\$(InputName).obj" "$(InputPath)"
;
; The calling intefaces are:
;
; AES_RETURN aes_encrypt(const unsigned char in_blk[],
; unsigned char out_blk[], const aes_encrypt_ctx cx[1]);
;
; AES_RETURN aes_decrypt(const unsigned char in_blk[],
; unsigned char out_blk[], const aes_decrypt_ctx cx[1]);
;
; AES_RETURN aes_encrypt_key<NNN>(const unsigned char key[],
; const aes_encrypt_ctx cx[1]);
;
; AES_RETURN aes_decrypt_key<NNN>(const unsigned char key[],
; const aes_decrypt_ctx cx[1]);
;
; AES_RETURN aes_encrypt_key(const unsigned char key[],
; unsigned int len, const aes_decrypt_ctx cx[1]);
;
; AES_RETURN aes_decrypt_key(const unsigned char key[],
; unsigned int len, const aes_decrypt_ctx cx[1]);
;
; where <NNN> is 128, 102 or 256. In the last two calls the length can be in
; either bits or bytes.
;
; Comment in/out the following lines to obtain the desired subroutines. These
; selections MUST match those in the C header file aes.h
; %define AES_128 ; define if AES with 128 bit keys is needed
; %define AES_192 ; define if AES with 192 bit keys is needed
%define AES_256 ; define if AES with 256 bit keys is needed
; %define AES_VAR ; define if a variable key size is needed
%define ENCRYPTION ; define if encryption is needed
%define DECRYPTION ; define if decryption is needed
%define AES_REV_DKS ; define if key decryption schedule is reversed
%define LAST_ROUND_TABLES ; define if tables are to be used for last round
; offsets to parameters
in_blk equ 4 ; input byte array address parameter
out_blk equ 8 ; output byte array address parameter
ctx equ 12 ; AES context structure
stk_spc equ 20 ; stack space
%define parms 12 ; parameter space on stack
; The encryption key schedule has the following in memory layout where N is the
; number of rounds (10, 12 or 14):
;
; lo: | input key (round 0) | ; each round is four 32-bit words
; | encryption round 1 |
; | encryption round 2 |
; ....
; | encryption round N-1 |
; hi: | encryption round N |
;
; The decryption key schedule is normally set up so that it has the same
; layout as above by actually reversing the order of the encryption key
; schedule in memory (this happens when AES_REV_DKS is set):
;
; lo: | decryption round 0 | = | encryption round N |
; | decryption round 1 | = INV_MIX_COL[ | encryption round N-1 | ]
; | decryption round 2 | = INV_MIX_COL[ | encryption round N-2 | ]
; .... ....
; | decryption round N-1 | = INV_MIX_COL[ | encryption round 1 | ]
; hi: | decryption round N | = | input key (round 0) |
;
; with rounds except the first and last modified using inv_mix_column()
; But if AES_REV_DKS is NOT set the order of keys is left as it is for
; encryption so that it has to be accessed in reverse when used for
; decryption (although the inverse mix column modifications are done)
;
; lo: | decryption round 0 | = | input key (round 0) |
; | decryption round 1 | = INV_MIX_COL[ | encryption round 1 | ]
; | decryption round 2 | = INV_MIX_COL[ | encryption round 2 | ]
; .... ....
; | decryption round N-1 | = INV_MIX_COL[ | encryption round N-1 | ]
; hi: | decryption round N | = | encryption round N |
;
; This layout is faster when the assembler key scheduling provided here
; is used.
;
; The DLL interface must use the _stdcall convention in which the number
; of bytes of parameter space is added after an @ to the sutine's name.
; We must also remove our parameters from the stack before return (see
; the do_exit macro). Define DLL_EXPORT for the Dynamic Link Library version.
;%define DLL_EXPORT
; End of user defines
%ifdef AES_VAR
%ifndef AES_128
%define AES_128
%endif
%ifndef AES_192
%define AES_192
%endif
%ifndef AES_256
%define AES_256
%endif
%endif
%ifdef AES_VAR
%define KS_LENGTH 60
%elifdef AES_256
%define KS_LENGTH 60
%elifdef AES_192
%define KS_LENGTH 52
%else
%define KS_LENGTH 44
%endif
; These macros implement stack based local variables
%macro save 2
mov [esp+4*%1],%2
%endmacro
%macro restore 2
mov %1,[esp+4*%2]
%endmacro
; the DLL has to implement the _stdcall calling interface on return
; In this case we have to take our parameters (3 4-byte pointers)
; off the stack
%macro do_name 1-2 parms
%ifndef DLL_EXPORT
align 32
global %1
%1:
%else
align 32
global %1@%2
export %1@%2
%1@%2:
%endif
%endmacro
%macro do_call 1-2 parms
%ifndef DLL_EXPORT
call %1
add esp,%2
%else
call %1@%2
%endif
%endmacro
%macro do_exit 0-1 parms
%ifdef DLL_EXPORT
ret %1
%else
ret
%endif
%endmacro
%ifdef ENCRYPTION
extern _t_fn
%define etab_0(x) [_t_fn+4*x]
%define etab_1(x) [_t_fn+1024+4*x]
%define etab_2(x) [_t_fn+2048+4*x]
%define etab_3(x) [_t_fn+3072+4*x]
%ifdef LAST_ROUND_TABLES
extern _t_fl
%define eltab_0(x) [_t_fl+4*x]
%define eltab_1(x) [_t_fl+1024+4*x]
%define eltab_2(x) [_t_fl+2048+4*x]
%define eltab_3(x) [_t_fl+3072+4*x]
%else
%define etab_b(x) byte [_t_fn+3072+4*x]
%endif
; ROUND FUNCTION. Build column[2] on ESI and column[3] on EDI that have the
; round keys pre-loaded. Build column[0] in EBP and column[1] in EBX.
;
; Input:
;
; EAX column[0]
; EBX column[1]
; ECX column[2]
; EDX column[3]
; ESI column key[round][2]
; EDI column key[round][3]
; EBP scratch
;
; Output:
;
; EBP column[0] unkeyed
; EBX column[1] unkeyed
; ESI column[2] keyed
; EDI column[3] keyed
; EAX scratch
; ECX scratch
; EDX scratch
%macro rnd_fun 2
rol ebx,16
%1 esi, cl, 0, ebp
%1 esi, dh, 1, ebp
%1 esi, bh, 3, ebp
%1 edi, dl, 0, ebp
%1 edi, ah, 1, ebp
%1 edi, bl, 2, ebp
%2 ebp, al, 0, ebp
shr ebx,16
and eax,0xffff0000
or eax,ebx
shr edx,16
%1 ebp, ah, 1, ebx
%1 ebp, dh, 3, ebx
%2 ebx, dl, 2, ebx
%1 ebx, ch, 1, edx
%1 ebx, al, 0, edx
shr eax,16
shr ecx,16
%1 ebp, cl, 2, edx
%1 edi, ch, 3, edx
%1 esi, al, 2, edx
%1 ebx, ah, 3, edx
%endmacro
; Basic MOV and XOR Operations for normal rounds
%macro nr_xor 4
movzx %4,%2
xor %1,etab_%3(%4)
%endmacro
%macro nr_mov 4
movzx %4,%2
mov %1,etab_%3(%4)
%endmacro
; Basic MOV and XOR Operations for last round
%ifdef LAST_ROUND_TABLES
%macro lr_xor 4
movzx %4,%2
xor %1,eltab_%3(%4)
%endmacro
%macro lr_mov 4
movzx %4,%2
mov %1,eltab_%3(%4)
%endmacro
%else
%macro lr_xor 4
movzx %4,%2
movzx %4,etab_b(%4)
%if %3 != 0
shl %4,8*%3
%endif
xor %1,%4
%endmacro
%macro lr_mov 4
movzx %4,%2
movzx %1,etab_b(%4)
%if %3 != 0
shl %1,8*%3
%endif
%endmacro
%endif
%macro enc_round 0
add ebp,16
save 0,ebp
mov esi,[ebp+8]
mov edi,[ebp+12]
rnd_fun nr_xor, nr_mov
mov eax,ebp
mov ecx,esi
mov edx,edi
restore ebp,0
xor eax,[ebp]
xor ebx,[ebp+4]
%endmacro
%macro enc_last_round 0
add ebp,16
save 0,ebp
mov esi,[ebp+8]
mov edi,[ebp+12]
rnd_fun lr_xor, lr_mov
mov eax,ebp
restore ebp,0
xor eax,[ebp]
xor ebx,[ebp+4]
%endmacro
section .text align=32
; AES Encryption Subroutine
do_name _aes_encrypt
sub esp,stk_spc
mov [esp+16],ebp
mov [esp+12],ebx
mov [esp+ 8],esi
mov [esp+ 4],edi
mov esi,[esp+in_blk+stk_spc] ; input pointer
mov eax,[esi ]
mov ebx,[esi+ 4]
mov ecx,[esi+ 8]
mov edx,[esi+12]
mov ebp,[esp+ctx+stk_spc] ; key pointer
movzx edi,byte [ebp+4*KS_LENGTH]
xor eax,[ebp ]
xor ebx,[ebp+ 4]
xor ecx,[ebp+ 8]
xor edx,[ebp+12]
; determine the number of rounds
cmp edi,10*16
je .3
cmp edi,12*16
je .2
cmp edi,14*16
je .1
mov eax,-1
jmp .5
.1: enc_round
enc_round
.2: enc_round
enc_round
.3: enc_round
enc_round
enc_round
enc_round
enc_round
enc_round
enc_round
enc_round
enc_round
enc_last_round
mov edx,[esp+out_blk+stk_spc]
mov [edx],eax
mov [edx+4],ebx
mov [edx+8],esi
mov [edx+12],edi
xor eax,eax
.5: mov ebp,[esp+16]
mov ebx,[esp+12]
mov esi,[esp+ 8]
mov edi,[esp+ 4]
add esp,stk_spc
do_exit
%endif
%ifdef DECRYPTION
extern _t_in
%define dtab_0(x) [_t_in+4*x]
%define dtab_1(x) [_t_in+1024+4*x]
%define dtab_2(x) [_t_in+2048+4*x]
%define dtab_3(x) [_t_in+3072+4*x]
%ifdef LAST_ROUND_TABLES
extern _t_il
%define dltab_0(x) [_t_il+4*x]
%define dltab_1(x) [_t_il+1024+4*x]
%define dltab_2(x) [_t_il+2048+4*x]
%define dltab_3(x) [_t_il+3072+4*x]
%else
extern _t_ibox
%define dtab_x(x) byte [_t_ibox+x]
%endif
%macro irn_fun 2
rol eax,16
%1 esi, cl, 0, ebp
%1 esi, bh, 1, ebp
%1 esi, al, 2, ebp
%1 edi, dl, 0, ebp
%1 edi, ch, 1, ebp
%1 edi, ah, 3, ebp
%2 ebp, bl, 0, ebp
shr eax,16
and ebx,0xffff0000
or ebx,eax
shr ecx,16
%1 ebp, bh, 1, eax
%1 ebp, ch, 3, eax
%2 eax, cl, 2, ecx
%1 eax, bl, 0, ecx
%1 eax, dh, 1, ecx
shr ebx,16
shr edx,16
%1 esi, dh, 3, ecx
%1 ebp, dl, 2, ecx
%1 eax, bh, 3, ecx
%1 edi, bl, 2, ecx
%endmacro
; Basic MOV and XOR Operations for normal rounds
%macro ni_xor 4
movzx %4,%2
xor %1,dtab_%3(%4)
%endmacro
%macro ni_mov 4
movzx %4,%2
mov %1,dtab_%3(%4)
%endmacro
; Basic MOV and XOR Operations for last round
%ifdef LAST_ROUND_TABLES
%macro li_xor 4
movzx %4,%2
xor %1,dltab_%3(%4)
%endmacro
%macro li_mov 4
movzx %4,%2
mov %1,dltab_%3(%4)
%endmacro
%else
%macro li_xor 4
movzx %4,%2
movzx %4,dtab_x(%4)
%if %3 != 0
shl %4,8*%3
%endif
xor %1,%4
%endmacro
%macro li_mov 4
movzx %4,%2
movzx %1,dtab_x(%4)
%if %3 != 0
shl %1,8*%3
%endif
%endmacro
%endif
%macro dec_round 0
%ifdef AES_REV_DKS
add ebp,16
%else
sub ebp,16
%endif
save 0,ebp
mov esi,[ebp+8]
mov edi,[ebp+12]
irn_fun ni_xor, ni_mov
mov ebx,ebp
mov ecx,esi
mov edx,edi
restore ebp,0
xor eax,[ebp]
xor ebx,[ebp+4]
%endmacro
%macro dec_last_round 0
%ifdef AES_REV_DKS
add ebp,16
%else
sub ebp,16
%endif
save 0,ebp
mov esi,[ebp+8]
mov edi,[ebp+12]
irn_fun li_xor, li_mov
mov ebx,ebp
restore ebp,0
xor eax,[ebp]
xor ebx,[ebp+4]
%endmacro
section .text
; AES Decryption Subroutine
do_name _aes_decrypt
sub esp,stk_spc
mov [esp+16],ebp
mov [esp+12],ebx
mov [esp+ 8],esi
mov [esp+ 4],edi
; input four columns and xor in first round key
mov esi,[esp+in_blk+stk_spc] ; input pointer
mov eax,[esi ]
mov ebx,[esi+ 4]
mov ecx,[esi+ 8]
mov edx,[esi+12]
lea esi,[esi+16]
mov ebp,[esp+ctx+stk_spc] ; key pointer
movzx edi,byte[ebp+4*KS_LENGTH]
%ifndef AES_REV_DKS ; if decryption key schedule is not reversed
lea ebp,[ebp+edi] ; we have to access it from the top down
%endif
xor eax,[ebp ] ; key schedule
xor ebx,[ebp+ 4]
xor ecx,[ebp+ 8]
xor edx,[ebp+12]
; determine the number of rounds
cmp edi,10*16
je .3
cmp edi,12*16
je .2
cmp edi,14*16
je .1
mov eax,-1
jmp .5
.1: dec_round
dec_round
.2: dec_round
dec_round
.3: dec_round
dec_round
dec_round
dec_round
dec_round
dec_round
dec_round
dec_round
dec_round
dec_last_round
; move final values to the output array.
mov ebp,[esp+out_blk+stk_spc]
mov [ebp],eax
mov [ebp+4],ebx
mov [ebp+8],esi
mov [ebp+12],edi
xor eax,eax
.5: mov ebp,[esp+16]
mov ebx,[esp+12]
mov esi,[esp+ 8]
mov edi,[esp+ 4]
add esp,stk_spc
do_exit
%endif
end

311
src/utils/crypto/aescrypt.c Normal file
View File

@@ -0,0 +1,311 @@
/*
---------------------------------------------------------------------------
Copyright (c) 1998-2007, Brian Gladman, Worcester, UK. All rights reserved.
LICENSE TERMS
The free distribution and use of this software is allowed (with or without
changes) provided that:
1. source code distributions include the above copyright notice, this
list of conditions and the following disclaimer;
2. binary distributions include the above copyright notice, this list
of conditions and the following disclaimer in their documentation;
3. the name of the copyright holder is not used to endorse products
built using this software without specific written permission.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue Date: 20/12/2007
*/
#include "aesopt.h"
#include "aestab.h"
#if defined(__cplusplus)
extern "C"
{
#endif
#define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
#define so(y,x,c) word_out(y, c, s(x,c))
#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
#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)
#if ( FUNCS_IN_C & ENCRYPTION_IN_C )
/* Visual C++ .Net v7.1 provides the fastest encryption code when using
Pentium optimiation with small code but this is poor for decryption
so we need to control this with the following VC++ pragmas
*/
#if defined( _MSC_VER ) && !defined( _WIN64 )
#pragma optimize( "s", on )
#endif
/* Given the column (c) of the output state variable, the following
macros give the input state variables which are needed in its
computation for each row (r) of the state. All the alternative
macros give the same end values but expand into different ways
of calculating these values. In particular the complex macro
used for dynamically variable block sizes is designed to expand
to a compile time constant whenever possible but will expand to
conditional clauses on some branches (I am grateful to Frank
Yellin for this construction)
*/
#define fwd_var(x,r,c)\
( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
: r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
: r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
: ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
#if defined(FT4_SET)
#undef dec_fmvars
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
#elif defined(FT1_SET)
#undef dec_fmvars
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c))
#else
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c)))
#endif
#if defined(FL4_SET)
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
#elif defined(FL1_SET)
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c))
#else
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c))
#endif
AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
{ uint_32t locals(b0, b1);
const uint_32t *kp;
#if defined( dec_fmvars )
dec_fmvars; /* declare variables for fwd_mcol() if needed */
#endif
#if defined( AES_ERR_CHK )
if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )
return EXIT_FAILURE;
#endif
kp = cx->ks;
state_in(b0, in, kp);
#if (ENC_UNROLL == FULL)
switch(cx->inf.b[0])
{
case 14 * 16:
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
kp += 2 * N_COLS;
case 12 * 16:
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
kp += 2 * N_COLS;
case 10 * 16:
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
round(fwd_rnd, b1, b0, kp + 3 * N_COLS);
round(fwd_rnd, b0, b1, kp + 4 * N_COLS);
round(fwd_rnd, b1, b0, kp + 5 * N_COLS);
round(fwd_rnd, b0, b1, kp + 6 * N_COLS);
round(fwd_rnd, b1, b0, kp + 7 * N_COLS);
round(fwd_rnd, b0, b1, kp + 8 * N_COLS);
round(fwd_rnd, b1, b0, kp + 9 * N_COLS);
round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
}
#else
#if (ENC_UNROLL == PARTIAL)
{ uint_32t rnd;
for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
{
kp += N_COLS;
round(fwd_rnd, b1, b0, kp);
kp += N_COLS;
round(fwd_rnd, b0, b1, kp);
}
kp += N_COLS;
round(fwd_rnd, b1, b0, kp);
#else
{ uint_32t rnd;
for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
{
kp += N_COLS;
round(fwd_rnd, b1, b0, kp);
l_copy(b0, b1);
}
#endif
kp += N_COLS;
round(fwd_lrnd, b0, b1, kp);
}
#endif
state_out(out, b0);
#if defined( AES_ERR_CHK )
return EXIT_SUCCESS;
#endif
}
#endif
#if ( FUNCS_IN_C & DECRYPTION_IN_C)
/* Visual C++ .Net v7.1 provides the fastest encryption code when using
Pentium optimiation with small code but this is poor for decryption
so we need to control this with the following VC++ pragmas
*/
#if defined( _MSC_VER ) && !defined( _WIN64 )
#pragma optimize( "t", on )
#endif
/* Given the column (c) of the output state variable, the following
macros give the input state variables which are needed in its
computation for each row (r) of the state. All the alternative
macros give the same end values but expand into different ways
of calculating these values. In particular the complex macro
used for dynamically variable block sizes is designed to expand
to a compile time constant whenever possible but will expand to
conditional clauses on some branches (I am grateful to Frank
Yellin for this construction)
*/
#define inv_var(x,r,c)\
( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
: r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
: r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
: ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
#if defined(IT4_SET)
#undef dec_imvars
#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
#elif defined(IT1_SET)
#undef dec_imvars
#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c))
#else
#define inv_rnd(y,x,k,c) (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c)))
#endif
#if defined(IL4_SET)
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
#elif defined(IL1_SET)
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c))
#else
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))
#endif
/* This code can work with the decryption key schedule in the */
/* order that is used for encrytpion (where the 1st decryption */
/* round key is at the high end ot the schedule) or with a key */
/* schedule that has been reversed to put the 1st decryption */
/* round key at the low end of the schedule in memory (when */
/* AES_REV_DKS is defined) */
#ifdef AES_REV_DKS
#define key_ofs 0
#define rnd_key(n) (kp + n * N_COLS)
#else
#define key_ofs 1
#define rnd_key(n) (kp - n * N_COLS)
#endif
AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
{ uint_32t locals(b0, b1);
#if defined( dec_imvars )
dec_imvars; /* declare variables for inv_mcol() if needed */
#endif
const uint_32t *kp;
#if defined( AES_ERR_CHK )
if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )
return EXIT_FAILURE;
#endif
kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
state_in(b0, in, kp);
#if (DEC_UNROLL == FULL)
kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
switch(cx->inf.b[0])
{
case 14 * 16:
round(inv_rnd, b1, b0, rnd_key(-13));
round(inv_rnd, b0, b1, rnd_key(-12));
case 12 * 16:
round(inv_rnd, b1, b0, rnd_key(-11));
round(inv_rnd, b0, b1, rnd_key(-10));
case 10 * 16:
round(inv_rnd, b1, b0, rnd_key(-9));
round(inv_rnd, b0, b1, rnd_key(-8));
round(inv_rnd, b1, b0, rnd_key(-7));
round(inv_rnd, b0, b1, rnd_key(-6));
round(inv_rnd, b1, b0, rnd_key(-5));
round(inv_rnd, b0, b1, rnd_key(-4));
round(inv_rnd, b1, b0, rnd_key(-3));
round(inv_rnd, b0, b1, rnd_key(-2));
round(inv_rnd, b1, b0, rnd_key(-1));
round(inv_lrnd, b0, b1, rnd_key( 0));
}
#else
#if (DEC_UNROLL == PARTIAL)
{ uint_32t rnd;
for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
{
kp = rnd_key(1);
round(inv_rnd, b1, b0, kp);
kp = rnd_key(1);
round(inv_rnd, b0, b1, kp);
}
kp = rnd_key(1);
round(inv_rnd, b1, b0, kp);
#else
{ uint_32t rnd;
for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
{
kp = rnd_key(1);
round(inv_rnd, b1, b0, kp);
l_copy(b0, b1);
}
#endif
kp = rnd_key(1);
round(inv_lrnd, b0, b1, kp);
}
#endif
state_out(out, b0);
#if defined( AES_ERR_CHK )
return EXIT_SUCCESS;
#endif
}
#endif
#if defined(__cplusplus)
}
#endif

577
src/utils/crypto/aeskey.c Normal file
View File

@@ -0,0 +1,577 @@
/*
---------------------------------------------------------------------------
Copyright (c) 1998-2007, Brian Gladman, Worcester, UK. All rights reserved.
LICENSE TERMS
The free distribution and use of this software is allowed (with or without
changes) provided that:
1. source code distributions include the above copyright notice, this
list of conditions and the following disclaimer;
2. binary distributions include the above copyright notice, this list
of conditions and the following disclaimer in their documentation;
3. the name of the copyright holder is not used to endorse products
built using this software without specific written permission.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue Date: 20/12/2007
*/
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsequence-point"
#include "aesopt.h"
#include "aestab.h"
#ifdef USE_VIA_ACE_IF_PRESENT
# include "aes_via_ace.h"
#endif
#if defined(__cplusplus)
extern "C"
{
#endif
/* Initialise the key schedule from the user supplied key. The key
length can be specified in bytes, with legal values of 16, 24
and 32, or in bits, with legal values of 128, 192 and 256. These
values correspond with 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
*/
#if (FUNCS_IN_C & ENC_KEYING_IN_C)
#if defined(AES_128) || defined(AES_VAR)
#define ke4(k,i) \
{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[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]; \
}
AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
{ uint_32t ss[4];
cx->ks[0] = ss[0] = word_in(key, 0);
cx->ks[1] = ss[1] = word_in(key, 1);
cx->ks[2] = ss[2] = word_in(key, 2);
cx->ks[3] = ss[3] = word_in(key, 3);
#if ENC_UNROLL == NONE
{ uint_32t i;
for(i = 0; i < 9; ++i)
ke4(cx->ks, i);
}
#else
ke4(cx->ks, 0); ke4(cx->ks, 1);
ke4(cx->ks, 2); ke4(cx->ks, 3);
ke4(cx->ks, 4); ke4(cx->ks, 5);
ke4(cx->ks, 6); ke4(cx->ks, 7);
ke4(cx->ks, 8);
#endif
ke4(cx->ks, 9);
cx->inf.l = 0;
cx->inf.b[0] = 10 * 16;
#ifdef USE_VIA_ACE_IF_PRESENT
if(VIA_ACE_AVAILABLE)
cx->inf.b[1] = 0xff;
#endif
#if defined( AES_ERR_CHK )
return EXIT_SUCCESS;
#endif
}
#endif
#if defined(AES_192) || defined(AES_VAR)
#define kef6(k,i) \
{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[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 ke6(k,i) \
{ kef6(k,i); \
k[6*(i)+10] = ss[4] ^= ss[3]; \
k[6*(i)+11] = ss[5] ^= ss[4]; \
}
AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
{ uint_32t ss[6];
cx->ks[0] = ss[0] = word_in(key, 0);
cx->ks[1] = ss[1] = word_in(key, 1);
cx->ks[2] = ss[2] = word_in(key, 2);
cx->ks[3] = ss[3] = word_in(key, 3);
cx->ks[4] = ss[4] = word_in(key, 4);
cx->ks[5] = ss[5] = word_in(key, 5);
#if ENC_UNROLL == NONE
{ uint_32t i;
for(i = 0; i < 7; ++i)
ke6(cx->ks, i);
}
#else
ke6(cx->ks, 0); ke6(cx->ks, 1);
ke6(cx->ks, 2); ke6(cx->ks, 3);
ke6(cx->ks, 4); ke6(cx->ks, 5);
ke6(cx->ks, 6);
#endif
kef6(cx->ks, 7);
cx->inf.l = 0;
cx->inf.b[0] = 12 * 16;
#ifdef USE_VIA_ACE_IF_PRESENT
if(VIA_ACE_AVAILABLE)
cx->inf.b[1] = 0xff;
#endif
#if defined( AES_ERR_CHK )
return EXIT_SUCCESS;
#endif
}
#endif
#if defined(AES_256) || defined(AES_VAR)
#define kef8(k,i) \
{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[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]; \
}
#define ke8(k,i) \
{ kef8(k,i); \
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]; \
}
AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
{ uint_32t ss[8];
cx->ks[0] = ss[0] = word_in(key, 0);
cx->ks[1] = ss[1] = word_in(key, 1);
cx->ks[2] = ss[2] = word_in(key, 2);
cx->ks[3] = ss[3] = word_in(key, 3);
cx->ks[4] = ss[4] = word_in(key, 4);
cx->ks[5] = ss[5] = word_in(key, 5);
cx->ks[6] = ss[6] = word_in(key, 6);
cx->ks[7] = ss[7] = word_in(key, 7);
#if ENC_UNROLL == NONE
{ uint_32t i;
for(i = 0; i < 6; ++i)
ke8(cx->ks, i);
}
#else
ke8(cx->ks, 0); ke8(cx->ks, 1);
ke8(cx->ks, 2); ke8(cx->ks, 3);
ke8(cx->ks, 4); ke8(cx->ks, 5);
#endif
kef8(cx->ks, 6);
cx->inf.l = 0;
cx->inf.b[0] = 14 * 16;
#ifdef USE_VIA_ACE_IF_PRESENT
if(VIA_ACE_AVAILABLE)
cx->inf.b[1] = 0xff;
#endif
#if defined( AES_ERR_CHK )
return EXIT_SUCCESS;
#endif
}
#endif
#if defined(AES_VAR)
AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
{
switch(key_len)
{
#if defined( AES_ERR_CHK )
case 16: case 128: return aes_encrypt_key128(key, cx);
case 24: case 192: return aes_encrypt_key192(key, cx);
case 32: case 256: return aes_encrypt_key256(key, cx);
default: return EXIT_FAILURE;
#else
case 16: case 128: aes_encrypt_key128(key, cx); return;
case 24: case 192: aes_encrypt_key192(key, cx); return;
case 32: case 256: aes_encrypt_key256(key, cx); return;
#endif
}
}
#endif
#endif
#if (FUNCS_IN_C & DEC_KEYING_IN_C)
/* this is used to store the decryption round keys */
/* in forward or reverse order */
#ifdef AES_REV_DKS
#define v(n,i) ((n) - (i) + 2 * ((i) & 3))
#else
#define v(n,i) (i)
#endif
#if DEC_ROUND == NO_TABLES
#define ff(x) (x)
#else
#define ff(x) inv_mcol(x)
#if defined( dec_imvars )
#define d_vars dec_imvars
#endif
#endif
#if defined(AES_128) || defined(AES_VAR)
#define k4e(k,i) \
{ k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \
k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \
k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \
}
#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[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
ss[i % 4] ^= ss[4]; \
ss[4] ^= k[v(40,(4*(i)))]; k[v(40,(4*(i))+4)] = ff(ss[4]); \
ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \
ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \
ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \
}
#define kd4(k,i) \
{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \
k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \
k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \
k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \
}
#define kdl4(k,i) \
{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \
k[v(40,(4*(i))+6)] = ss[0]; \
k[v(40,(4*(i))+7)] = ss[1]; \
}
#else
#define kdf4(k,i) \
{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ff(ss[0]); \
ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ff(ss[1]); \
ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ff(ss[2]); \
ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ff(ss[3]); \
}
#define kd4(k,i) \
{ ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \
ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[v(40,(4*(i))+ 4)] = ss[4] ^= k[v(40,(4*(i)))]; \
ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[4] ^= k[v(40,(4*(i))+ 1)]; \
ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[4] ^= k[v(40,(4*(i))+ 2)]; \
ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[4] ^= k[v(40,(4*(i))+ 3)]; \
}
#define kdl4(k,i) \
{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ss[0]; \
ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[1]; \
ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[2]; \
ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[3]; \
}
#endif
AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
{ uint_32t ss[5];
#if defined( d_vars )
d_vars;
#endif
cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);
cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);
cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);
cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);
#if DEC_UNROLL == NONE
{ uint_32t i;
for(i = 0; i < 10; ++i)
k4e(cx->ks, i);
#if !(DEC_ROUND == NO_TABLES)
for(i = N_COLS; i < 10 * N_COLS; ++i)
cx->ks[i] = inv_mcol(cx->ks[i]);
#endif
}
#else
kdf4(cx->ks, 0); kd4(cx->ks, 1);
kd4(cx->ks, 2); kd4(cx->ks, 3);
kd4(cx->ks, 4); kd4(cx->ks, 5);
kd4(cx->ks, 6); kd4(cx->ks, 7);
kd4(cx->ks, 8); kdl4(cx->ks, 9);
#endif
cx->inf.l = 0;
cx->inf.b[0] = 10 * 16;
#ifdef USE_VIA_ACE_IF_PRESENT
if(VIA_ACE_AVAILABLE)
cx->inf.b[1] = 0xff;
#endif
#if defined( AES_ERR_CHK )
return EXIT_SUCCESS;
#endif
}
#endif
#if defined(AES_192) || defined(AES_VAR)
#define k6ef(k,i) \
{ k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
}
#define k6e(k,i) \
{ k6ef(k,i); \
k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
}
#define kdf6(k,i) \
{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
}
#define kd6(k,i) \
{ ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
}
#define kdl6(k,i) \
{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
}
AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
{ uint_32t ss[7];
#if defined( d_vars )
d_vars;
#endif
cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);
cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);
cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
#if DEC_UNROLL == NONE
cx->ks[v(48,(4))] = ss[4] = word_in(key, 4);
cx->ks[v(48,(5))] = ss[5] = word_in(key, 5);
{ uint_32t i;
for(i = 0; i < 7; ++i)
k6e(cx->ks, i);
k6ef(cx->ks, 7);
#if !(DEC_ROUND == NO_TABLES)
for(i = N_COLS; i < 12 * N_COLS; ++i)
cx->ks[i] = inv_mcol(cx->ks[i]);
#endif
}
#else
cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
kdf6(cx->ks, 0); kd6(cx->ks, 1);
kd6(cx->ks, 2); kd6(cx->ks, 3);
kd6(cx->ks, 4); kd6(cx->ks, 5);
kd6(cx->ks, 6); kdl6(cx->ks, 7);
#endif
cx->inf.l = 0;
cx->inf.b[0] = 12 * 16;
#ifdef USE_VIA_ACE_IF_PRESENT
if(VIA_ACE_AVAILABLE)
cx->inf.b[1] = 0xff;
#endif
#if defined( AES_ERR_CHK )
return EXIT_SUCCESS;
#endif
}
#endif
#if defined(AES_256) || defined(AES_VAR)
#define k8ef(k,i) \
{ k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \
k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \
k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \
}
#define k8e(k,i) \
{ k8ef(k,i); \
k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \
k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \
k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \
k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \
}
#define kdf8(k,i) \
{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \
ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \
ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \
ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \
ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \
ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \
ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \
ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \
}
#define kd8(k,i) \
{ ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \
ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \
ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \
ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \
ss[8] = ls_box(ss[3],0); \
ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \
ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \
ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \
ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \
}
#define kdl8(k,i) \
{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \
ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \
ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \
ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
}
AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
{ uint_32t ss[9];
#if defined( d_vars )
d_vars;
#endif
cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);
cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);
cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);
cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
#if DEC_UNROLL == NONE
cx->ks[v(56,(4))] = ss[4] = word_in(key, 4);
cx->ks[v(56,(5))] = ss[5] = word_in(key, 5);
cx->ks[v(56,(6))] = ss[6] = word_in(key, 6);
cx->ks[v(56,(7))] = ss[7] = word_in(key, 7);
{ uint_32t i;
for(i = 0; i < 6; ++i)
k8e(cx->ks, i);
k8ef(cx->ks, 6);
#if !(DEC_ROUND == NO_TABLES)
for(i = N_COLS; i < 14 * N_COLS; ++i)
cx->ks[i] = inv_mcol(cx->ks[i]);
#endif
}
#else
cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));
cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));
cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));
cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));
kdf8(cx->ks, 0); kd8(cx->ks, 1);
kd8(cx->ks, 2); kd8(cx->ks, 3);
kd8(cx->ks, 4); kd8(cx->ks, 5);
kdl8(cx->ks, 6);
#endif
cx->inf.l = 0;
cx->inf.b[0] = 14 * 16;
#ifdef USE_VIA_ACE_IF_PRESENT
if(VIA_ACE_AVAILABLE)
cx->inf.b[1] = 0xff;
#endif
#if defined( AES_ERR_CHK )
return EXIT_SUCCESS;
#endif
}
#endif
#if defined(AES_VAR)
AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
{
switch(key_len)
{
#if defined( AES_ERR_CHK )
case 16: case 128: return aes_decrypt_key128(key, cx);
case 24: case 192: return aes_decrypt_key192(key, cx);
case 32: case 256: return aes_decrypt_key256(key, cx);
default: return EXIT_FAILURE;
#else
case 16: case 128: aes_decrypt_key128(key, cx); return;
case 24: case 192: aes_decrypt_key192(key, cx); return;
case 32: case 256: aes_decrypt_key256(key, cx); return;
#endif
}
}
#endif
#endif
#if defined(__cplusplus)
}
#endif
#pragma GCC diagnostic pop

731
src/utils/crypto/aesopt.h Normal file
View File

@@ -0,0 +1,731 @@
/*
---------------------------------------------------------------------------
Copyright (c) 1998-2007, Brian Gladman, Worcester, UK. All rights reserved.
LICENSE TERMS
The free distribution and use of this software is allowed (with or without
changes) provided that:
1. source code distributions include the above copyright notice, this
list of conditions and the following disclaimer;
2. binary distributions include the above copyright notice, this list
of conditions and the following disclaimer in their documentation;
3. the name of the copyright holder is not used to endorse products
built using this software without specific written permission.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue Date: 20/12/2007
This 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. This version is designed for the standard
block size of 16 bytes and for key sizes of 128, 192 and 256 bits (16, 24
and 32 bytes).
This version is designed for flexibility and speed using operations on
32-bit words rather than operations on bytes. It can be compiled with
either big or little endian internal byte order but is faster when the
native byte order for the processor is used.
THE CIPHER INTERFACE
The cipher interface is implemented as an array of bytes in which lower
AES bit sequence indexes map to higher numeric significance within bytes.
uint_8t (an unsigned 8-bit type)
uint_32t (an unsigned 32-bit type)
struct aes_encrypt_ctx (structure for the cipher encryption context)
struct aes_decrypt_ctx (structure for the cipher decryption context)
AES_RETURN the function return type
C subroutine calls:
AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]);
AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]);
AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);
AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out,
const aes_encrypt_ctx cx[1]);
AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]);
AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]);
AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);
AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out,
const aes_decrypt_ctx cx[1]);
IMPORTANT NOTE: If you are using this C interface with dynamic tables make sure that
you call aes_init() before AES is used so that the tables are initialised.
C++ aes class subroutines:
Class AESencrypt for encryption
Construtors:
AESencrypt(void)
AESencrypt(const unsigned char *key) - 128 bit key
Members:
AES_RETURN key128(const unsigned char *key)
AES_RETURN key192(const unsigned char *key)
AES_RETURN key256(const unsigned char *key)
AES_RETURN encrypt(const unsigned char *in, unsigned char *out) const
Class AESdecrypt for encryption
Construtors:
AESdecrypt(void)
AESdecrypt(const unsigned char *key) - 128 bit key
Members:
AES_RETURN key128(const unsigned char *key)
AES_RETURN key192(const unsigned char *key)
AES_RETURN key256(const unsigned char *key)
AES_RETURN decrypt(const unsigned char *in, unsigned char *out) const
*/
/* Adapted for TrueCrypt by the TrueCrypt Foundation */
#if !defined( _AESOPT_H )
#define _AESOPT_H
#if defined( __cplusplus )
#include "aescpp.h"
#else
#include "aes.h"
#endif
#include "../common/endian.h"
#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
#define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
#if BYTE_ORDER == LITTLE_ENDIAN
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#endif
#if BYTE_ORDER == BIG_ENDIAN
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#endif
/* CONFIGURATION - THE 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. The following local defines should not be changed.
*/
#define ENCRYPTION_IN_C 1
#define DECRYPTION_IN_C 2
#define ENC_KEYING_IN_C 4
#define DEC_KEYING_IN_C 8
#define NO_TABLES 0
#define ONE_TABLE 1
#define FOUR_TABLES 4
#define NONE 0
#define PARTIAL 1
#define FULL 2
/* --- START OF USER CONFIGURED OPTIONS --- */
/* 1. 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
WARNING: Assembler code versions rely on PLATFORM_BYTE_ORDER being set.
This define will hence be redefined later (in section 4) if necessary
*/
#if 1
#define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER
#elif 0
#define ALGORITHM_BYTE_ORDER IS_LITTLE_ENDIAN
#elif 0
#define ALGORITHM_BYTE_ORDER IS_BIG_ENDIAN
#else
#error The algorithm byte order is not defined
#endif
/* 2. VIA ACE SUPPORT
Define this option if support for the VIA ACE is required. This uses
inline assembler instructions and is only implemented for the Microsoft,
Intel and GCC compilers. If VIA ACE is known to be present, then defining
ASSUME_VIA_ACE_PRESENT will remove the ordinary encryption/decryption
code. If USE_VIA_ACE_IF_PRESENT is defined then VIA ACE will be used if
it is detected (both present and enabled) but the normal AES code will
also be present.
When VIA ACE is to be used, all AES encryption contexts MUST be 16 byte
aligned; other input/output buffers do not need to be 16 byte aligned
but there are very large performance gains if this can be arranged.
VIA ACE also requires the decryption key schedule to be in reverse
order (which later checks below ensure).
*/
#if 0 && !defined( USE_VIA_ACE_IF_PRESENT )
# define USE_VIA_ACE_IF_PRESENT
#endif
#if 0 && !defined( ASSUME_VIA_ACE_PRESENT )
# define ASSUME_VIA_ACE_PRESENT
# endif
#if defined ( _WIN64 ) || defined( _WIN32_WCE ) || \
defined( _MSC_VER ) && ( _MSC_VER <= 800 )
# if defined( USE_VIA_ACE_IF_PRESENT )
# undef USE_VIA_ACE_IF_PRESENT
# endif
# if defined( ASSUME_VIA_ACE_PRESENT )
# undef ASSUME_VIA_ACE_PRESENT
# endif
#endif
/* 3. ASSEMBLER SUPPORT
This define (which can be on the command line) enables the use of the
assembler code routines for encryption, decryption and key scheduling
as follows:
ASM_X86_V1C uses the assembler (aes_x86_v1.asm) with large tables for
encryption and decryption and but with key scheduling in C
ASM_X86_V2 uses assembler (aes_x86_v2.asm) with compressed tables for
encryption, decryption and key scheduling
ASM_X86_V2C uses assembler (aes_x86_v2.asm) with compressed tables for
encryption and decryption and but with key scheduling in C
ASM_AMD64_C uses assembler (aes_amd64.asm) with compressed tables for
encryption and decryption and but with key scheduling in C
Change one 'if 0' below to 'if 1' to select the version or define
as a compilation option.
*/
#if 0 && !defined( ASM_X86_V1C )
# define ASM_X86_V1C
#elif 0 && !defined( ASM_X86_V2 )
# define ASM_X86_V2
#elif 0 && !defined( ASM_X86_V2C )
# define ASM_X86_V2C
#elif 0 && !defined( ASM_AMD64_C )
# define ASM_AMD64_C
#endif
#if (defined ( ASM_X86_V1C ) || defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) \
&& !defined( _M_IX86 ) || defined( ASM_AMD64_C ) && !defined( _M_X64 )
//# error Assembler code is only available for x86 and AMD64 systems
#endif
/* 4. 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 && !defined( _MSC_VER )
#define SAFE_IO
#endif
/* 5. 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
/* 6. FAST FINITE FIELD OPERATIONS
If this section is included, tables are used to provide faster finite
field arithmetic (this has no effect if FIXED_TABLES is defined).
*/
#if !defined (TC_WINDOWS_BOOT)
#define FF_TABLES
#endif
/* 7. INTERNAL STATE VARIABLE FORMAT
The internal state of Rijndael is stored in a number of local 32-bit
word varaibles which can be defined either as an array or as individual
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
/* 8. FIXED OR DYNAMIC TABLES
When this section is included the tables used by the code are compiled
statically into the binary file. Otherwise the subroutine aes_init()
must be called to compute them before the code is first used.
*/
#if !defined (TC_WINDOWS_BOOT) && !(defined( _MSC_VER ) && ( _MSC_VER <= 800 ))
#define FIXED_TABLES
#endif
/* 9. TABLE ALIGNMENT
On some sytsems speed will be improved by aligning the AES large lookup
tables on particular boundaries. This define should be set to a power of
two giving the desired alignment. It can be left undefined if alignment
is not needed. This option is specific to the Microsft VC++ compiler -
it seems to sometimes cause trouble for the VC++ version 6 compiler.
*/
#if 1 && defined( _MSC_VER ) && ( _MSC_VER >= 1300 )
#define TABLE_ALIGN 32
#endif
/* 10. TABLE OPTIONS
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 USER CONFIGURED OPTIONS ---- */
/* VIA ACE support is only available for VC++ and GCC */
#if !defined( _MSC_VER ) && !defined( __GNUC__ )
# if defined( ASSUME_VIA_ACE_PRESENT )
# undef ASSUME_VIA_ACE_PRESENT
# endif
# if defined( USE_VIA_ACE_IF_PRESENT )
# undef USE_VIA_ACE_IF_PRESENT
# endif
#endif
#if defined( ASSUME_VIA_ACE_PRESENT ) && !defined( USE_VIA_ACE_IF_PRESENT )
#define USE_VIA_ACE_IF_PRESENT
#endif
#if defined( USE_VIA_ACE_IF_PRESENT ) && !defined ( AES_REV_DKS )
#define AES_REV_DKS
#endif
/* Assembler support requires the use of platform byte order */
#if ( defined( ASM_X86_V1C ) || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) ) \
&& (ALGORITHM_BYTE_ORDER != PLATFORM_BYTE_ORDER)
#undef ALGORITHM_BYTE_ORDER
#define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER
#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
/* This implementation provides subroutines for encryption, decryption
and for setting the three key lengths (separately) for encryption
and decryption. Since not all functions are needed, masks are set
up here to determine which will be implemented in C
*/
#if !defined( AES_ENCRYPT )
# define EFUNCS_IN_C 0
#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \
|| defined( ASM_X86_V2C ) || defined( ASM_AMD64_C )
# define EFUNCS_IN_C ENC_KEYING_IN_C
#elif !defined( ASM_X86_V2 )
# define EFUNCS_IN_C ( ENCRYPTION_IN_C | ENC_KEYING_IN_C )
#else
# define EFUNCS_IN_C 0
#endif
#if !defined( AES_DECRYPT )
# define DFUNCS_IN_C 0
#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \
|| defined( ASM_X86_V2C ) || defined( ASM_AMD64_C )
# define DFUNCS_IN_C DEC_KEYING_IN_C
#elif !defined( ASM_X86_V2 )
# define DFUNCS_IN_C ( DECRYPTION_IN_C | DEC_KEYING_IN_C )
#else
# define DFUNCS_IN_C 0
#endif
#define FUNCS_IN_C ( EFUNCS_IN_C | DFUNCS_IN_C )
/* END OF CONFIGURATION OPTIONS */
#define RC_LENGTH (5 * (AES_BLOCK_SIZE / 4 - 2))
/* Disable or report errors on some 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
#if defined( bswap32 )
#define aes_sw32 bswap32
#elif defined( bswap_32 )
#define aes_sw32 bswap_32
#else
#define brot(x,n) (((uint_32t)(x) << n) | ((uint_32t)(x) >> (32 - n)))
#define aes_sw32(x) ((brot((x),8) & 0x00ff00ff) | (brot((x),24) & 0xff00ff00))
#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
WARNING: The definitions given here are intended only for use with
unsigned variables and with shift counts that are compile
time constants
*/
#if ( ALGORITHM_BYTE_ORDER == IS_LITTLE_ENDIAN )
#define upr(x,n) (((uint_32t)(x) << (8 * (n))) | ((uint_32t)(x) >> (32 - 8 * (n))))
#define ups(x,n) ((uint_32t) (x) << (8 * (n)))
#define bval(x,n) ((uint_8t)((x) >> (8 * (n))))
#define bytes2word(b0, b1, b2, b3) \
(((uint_32t)(b3) << 24) | ((uint_32t)(b2) << 16) | ((uint_32t)(b1) << 8) | (b0))
#endif
#if ( ALGORITHM_BYTE_ORDER == IS_BIG_ENDIAN )
#define upr(x,n) (((uint_32t)(x) >> (8 * (n))) | ((uint_32t)(x) << (32 - 8 * (n))))
#define ups(x,n) ((uint_32t) (x) >> (8 * (n)))
#define bval(x,n) ((uint_8t)((x) >> (24 - 8 * (n))))
#define bytes2word(b0, b1, b2, b3) \
(((uint_32t)(b0) << 24) | ((uint_32t)(b1) << 16) | ((uint_32t)(b2) << 8) | (b3))
#endif
#if defined( SAFE_IO )
#define word_in(x,c) bytes2word(((const uint_8t*)(x)+4*c)[0], ((const uint_8t*)(x)+4*c)[1], \
((const uint_8t*)(x)+4*c)[2], ((const uint_8t*)(x)+4*c)[3])
#define word_out(x,c,v) { ((uint_8t*)(x)+4*c)[0] = bval(v,0); ((uint_8t*)(x)+4*c)[1] = bval(v,1); \
((uint_8t*)(x)+4*c)[2] = bval(v,2); ((uint_8t*)(x)+4*c)[3] = bval(v,3); }
#elif ( ALGORITHM_BYTE_ORDER == PLATFORM_BYTE_ORDER )
#define word_in(x,c) (*((uint_32t*)(x)+(c)))
#define word_out(x,c,v) (*((uint_32t*)(x)+(c)) = (v))
#else
#define word_in(x,c) aes_sw32(*((uint_32t*)(x)+(c)))
#define word_out(x,c,v) (*((uint_32t*)(x)+(c)) = aes_sw32(v))
#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 gf_mulx(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * BPOLY))
/* The following defines provide alternative definitions of gf_mulx that might
give improved performance if a fast 32-bit multiply is not available. Note
that a temporary variable u needs to be defined where gf_mulx is used.
#define gf_mulx(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
#define m4 (0x01010101 * BPOLY)
#define gf_mulx(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
*/
/* Work out which tables are needed for the different options */
#if defined( ASM_X86_V1C )
#if defined( ENC_ROUND )
#undef ENC_ROUND
#endif
#define ENC_ROUND FOUR_TABLES
#if defined( LAST_ENC_ROUND )
#undef LAST_ENC_ROUND
#endif
#define LAST_ENC_ROUND FOUR_TABLES
#if defined( DEC_ROUND )
#undef DEC_ROUND
#endif
#define DEC_ROUND FOUR_TABLES
#if defined( LAST_DEC_ROUND )
#undef LAST_DEC_ROUND
#endif
#define LAST_DEC_ROUND FOUR_TABLES
#if defined( KEY_SCHED )
#undef KEY_SCHED
#define KEY_SCHED FOUR_TABLES
#endif
#endif
#if ( FUNCS_IN_C & ENCRYPTION_IN_C ) || defined( ASM_X86_V1C )
#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 ( FUNCS_IN_C & DECRYPTION_IN_C ) || defined( ASM_X86_V1C )
#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 (FUNCS_IN_C & ENC_KEYING_IN_C) || (FUNCS_IN_C & DEC_KEYING_IN_C)
#if KEY_SCHED == ONE_TABLE
#define LS1_SET
#elif KEY_SCHED == FOUR_TABLES
#define LS4_SET
#elif !defined( SBX_SET )
#define SBX_SET
#endif
#endif
#if (FUNCS_IN_C & DEC_KEYING_IN_C)
#if KEY_SCHED == ONE_TABLE
#define IM1_SET
#elif KEY_SCHED == FOUR_TABLES
#define IM4_SET
#elif !defined( SBX_SET )
#define SBX_SET
#endif
#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) ((8+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. */
#if defined( FM4_SET ) /* not currently used */
#define fwd_mcol(x) four_tables(x,t_use(f,m),vf1,rf1,0)
#elif defined( FM1_SET ) /* not currently used */
#define fwd_mcol(x) one_table(x,upr,t_use(f,m),vf1,rf1,0)
#else
#define dec_fmvars uint_32t g2
#define fwd_mcol(x) (g2 = gf_mulx(x), g2 ^ upr((x) ^ g2, 3) ^ upr((x), 2) ^ upr((x), 1))
#endif
#if defined( IM4_SET )
#define inv_mcol(x) four_tables(x,t_use(i,m),vf1,rf1,0)
#elif defined( IM1_SET )
#define inv_mcol(x) one_table(x,upr,t_use(i,m),vf1,rf1,0)
#else
#define dec_imvars uint_32t g2, g4, g9
#define inv_mcol(x) (g2 = gf_mulx(x), g4 = gf_mulx(g2), g9 = (x) ^ gf_mulx(g4), g4 ^= g9, \
(x) ^ g2 ^ g4 ^ upr(g2 ^ g9, 3) ^ upr(g4, 2) ^ upr(g9, 1))
#endif
#if defined( FL4_SET )
#define ls_box(x,c) four_tables(x,t_use(f,l),vf1,rf2,c)
#elif defined( LS4_SET )
#define ls_box(x,c) four_tables(x,t_use(l,s),vf1,rf2,c)
#elif defined( FL1_SET )
#define ls_box(x,c) one_table(x,upr,t_use(f,l),vf1,rf2,c)
#elif defined( LS1_SET )
#define ls_box(x,c) one_table(x,upr,t_use(l,s),vf1,rf2,c)
#else
#define ls_box(x,c) no_table(x,t_use(s,box),vf1,rf2,c)
#endif
#if defined( ASM_X86_V1C ) && defined( AES_DECRYPT ) && !defined( ISB_SET )
#define ISB_SET
#endif
#endif

921
src/utils/crypto/aessmall.c Normal file
View File

@@ -0,0 +1,921 @@
/*
---------------------------------------------------------------------------
Copyright (c) 1998-2006, Brian Gladman, Worcester, UK. All rights reserved.
LICENSE TERMS
The free distribution and use of this software is allowed (with or without
changes) provided that:
1. source code distributions include the above copyright notice, this
list of conditions and the following disclaimer;
2. binary distributions include the above copyright notice, this list
of conditions and the following disclaimer in their documentation;
3. the name of the copyright holder is not used to endorse products
built using this software without specific written permission.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue 09/09/2006
This is an AES implementation that uses only 8-bit byte operations on the
cipher state (there are options to use 32-bit types if available).
The combination of mix columns and byte substitution used here is based on
that developed by Karl Malbrain. His contribution is acknowledged.
*/
/* Adapted by TrueCrypt Foundation:
- Macro-generated tables were replaced with static data to enable compiling
with MSVC++ 1.5 which runs out of resources when expanding large macros.
*/
// #pragma optimize ("t", on)
/* define if you have a fast memcpy function on your system */
#if 1
# define HAVE_MEMCPY
# include <string.h>
# if defined( _MSC_VER )
# ifndef DEBUG
# pragma intrinsic( memcpy )
# endif
# endif
#endif
/* define if you have fast 32-bit types on your system */
#if 1
# define HAVE_UINT_32T
#endif
/* alternative versions (test for performance on your system) */
#if 0
# define VERSION_1
#endif
#include <stdint.h>
#include "aessmall.h"
#define WPOLY 0x011b
#define DPOLY 0x008d
#define f1(x) (x)
#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 d2(x) (((x) >> 1) ^ ((x) & 1 ? DPOLY : 0))
#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))
static const uint_8t s_box[256] = {
0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,
0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,
0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,
0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,
0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,
0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,
0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,
0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,
0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,
0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,
0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,
0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,
0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,
0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,
0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,
0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,
0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
};
static const uint_8t inv_s_box[256] = {
0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,
0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,
0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,
0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,
0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,
0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,
0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,
0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,
0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,
0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,
0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,
0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,
0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,
0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,
0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,
0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,
0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,
0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,
0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,
0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,
0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,
0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,
0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,
0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,
0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,
0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,
0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,
0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,
0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,
0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,
0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,
0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
};
static const uint_8t gfm2_s_box[256] = {
0xc6,0xf8,0xee,0xf6,0xff,0xd6,0xde,0x91,
0x60,0x02,0xce,0x56,0xe7,0xb5,0x4d,0xec,
0x8f,0x1f,0x89,0xfa,0xef,0xb2,0x8e,0xfb,
0x41,0xb3,0x5f,0x45,0x23,0x53,0xe4,0x9b,
0x75,0xe1,0x3d,0x4c,0x6c,0x7e,0xf5,0x83,
0x68,0x51,0xd1,0xf9,0xe2,0xab,0x62,0x2a,
0x08,0x95,0x46,0x9d,0x30,0x37,0x0a,0x2f,
0x0e,0x24,0x1b,0xdf,0xcd,0x4e,0x7f,0xea,
0x12,0x1d,0x58,0x34,0x36,0xdc,0xb4,0x5b,
0xa4,0x76,0xb7,0x7d,0x52,0xdd,0x5e,0x13,
0xa6,0xb9,0x00,0xc1,0x40,0xe3,0x79,0xb6,
0xd4,0x8d,0x67,0x72,0x94,0x98,0xb0,0x85,
0xbb,0xc5,0x4f,0xed,0x86,0x9a,0x66,0x11,
0x8a,0xe9,0x04,0xfe,0xa0,0x78,0x25,0x4b,
0xa2,0x5d,0x80,0x05,0x3f,0x21,0x70,0xf1,
0x63,0x77,0xaf,0x42,0x20,0xe5,0xfd,0xbf,
0x81,0x18,0x26,0xc3,0xbe,0x35,0x88,0x2e,
0x93,0x55,0xfc,0x7a,0xc8,0xba,0x32,0xe6,
0xc0,0x19,0x9e,0xa3,0x44,0x54,0x3b,0x0b,
0x8c,0xc7,0x6b,0x28,0xa7,0xbc,0x16,0xad,
0xdb,0x64,0x74,0x14,0x92,0x0c,0x48,0xb8,
0x9f,0xbd,0x43,0xc4,0x39,0x31,0xd3,0xf2,
0xd5,0x8b,0x6e,0xda,0x01,0xb1,0x9c,0x49,
0xd8,0xac,0xf3,0xcf,0xca,0xf4,0x47,0x10,
0x6f,0xf0,0x4a,0x5c,0x38,0x57,0x73,0x97,
0xcb,0xa1,0xe8,0x3e,0x96,0x61,0x0d,0x0f,
0xe0,0x7c,0x71,0xcc,0x90,0x06,0xf7,0x1c,
0xc2,0x6a,0xae,0x69,0x17,0x99,0x3a,0x27,
0xd9,0xeb,0x2b,0x22,0xd2,0xa9,0x07,0x33,
0x2d,0x3c,0x15,0xc9,0x87,0xaa,0x50,0xa5,
0x03,0x59,0x09,0x1a,0x65,0xd7,0x84,0xd0,
0x82,0x29,0x5a,0x1e,0x7b,0xa8,0x6d,0x2c
};
static const uint_8t gfm3_s_box[256] = {
0xa5,0x84,0x99,0x8d,0x0d,0xbd,0xb1,0x54,
0x50,0x03,0xa9,0x7d,0x19,0x62,0xe6,0x9a,
0x45,0x9d,0x40,0x87,0x15,0xeb,0xc9,0x0b,
0xec,0x67,0xfd,0xea,0xbf,0xf7,0x96,0x5b,
0xc2,0x1c,0xae,0x6a,0x5a,0x41,0x02,0x4f,
0x5c,0xf4,0x34,0x08,0x93,0x73,0x53,0x3f,
0x0c,0x52,0x65,0x5e,0x28,0xa1,0x0f,0xb5,
0x09,0x36,0x9b,0x3d,0x26,0x69,0xcd,0x9f,
0x1b,0x9e,0x74,0x2e,0x2d,0xb2,0xee,0xfb,
0xf6,0x4d,0x61,0xce,0x7b,0x3e,0x71,0x97,
0xf5,0x68,0x00,0x2c,0x60,0x1f,0xc8,0xed,
0xbe,0x46,0xd9,0x4b,0xde,0xd4,0xe8,0x4a,
0x6b,0x2a,0xe5,0x16,0xc5,0xd7,0x55,0x94,
0xcf,0x10,0x06,0x81,0xf0,0x44,0xba,0xe3,
0xf3,0xfe,0xc0,0x8a,0xad,0xbc,0x48,0x04,
0xdf,0xc1,0x75,0x63,0x30,0x1a,0x0e,0x6d,
0x4c,0x14,0x35,0x2f,0xe1,0xa2,0xcc,0x39,
0x57,0xf2,0x82,0x47,0xac,0xe7,0x2b,0x95,
0xa0,0x98,0xd1,0x7f,0x66,0x7e,0xab,0x83,
0xca,0x29,0xd3,0x3c,0x79,0xe2,0x1d,0x76,
0x3b,0x56,0x4e,0x1e,0xdb,0x0a,0x6c,0xe4,
0x5d,0x6e,0xef,0xa6,0xa8,0xa4,0x37,0x8b,
0x32,0x43,0x59,0xb7,0x8c,0x64,0xd2,0xe0,
0xb4,0xfa,0x07,0x25,0xaf,0x8e,0xe9,0x18,
0xd5,0x88,0x6f,0x72,0x24,0xf1,0xc7,0x51,
0x23,0x7c,0x9c,0x21,0xdd,0xdc,0x86,0x85,
0x90,0x42,0xc4,0xaa,0xd8,0x05,0x01,0x12,
0xa3,0x5f,0xf9,0xd0,0x91,0x58,0x27,0xb9,
0x38,0x13,0xb3,0x33,0xbb,0x70,0x89,0xa7,
0xb6,0x22,0x92,0x20,0x49,0xff,0x78,0x7a,
0x8f,0xf8,0x80,0x17,0xda,0x31,0xc6,0xb8,
0xc3,0xb0,0x77,0x11,0xcb,0xfc,0xd6,0x3a
};
static const uint_8t gfmul_9[256] = {
0x00,0x09,0x12,0x1b,0x24,0x2d,0x36,0x3f,
0x48,0x41,0x5a,0x53,0x6c,0x65,0x7e,0x77,
0x90,0x99,0x82,0x8b,0xb4,0xbd,0xa6,0xaf,
0xd8,0xd1,0xca,0xc3,0xfc,0xf5,0xee,0xe7,
0x3b,0x32,0x29,0x20,0x1f,0x16,0x0d,0x04,
0x73,0x7a,0x61,0x68,0x57,0x5e,0x45,0x4c,
0xab,0xa2,0xb9,0xb0,0x8f,0x86,0x9d,0x94,
0xe3,0xea,0xf1,0xf8,0xc7,0xce,0xd5,0xdc,
0x76,0x7f,0x64,0x6d,0x52,0x5b,0x40,0x49,
0x3e,0x37,0x2c,0x25,0x1a,0x13,0x08,0x01,
0xe6,0xef,0xf4,0xfd,0xc2,0xcb,0xd0,0xd9,
0xae,0xa7,0xbc,0xb5,0x8a,0x83,0x98,0x91,
0x4d,0x44,0x5f,0x56,0x69,0x60,0x7b,0x72,
0x05,0x0c,0x17,0x1e,0x21,0x28,0x33,0x3a,
0xdd,0xd4,0xcf,0xc6,0xf9,0xf0,0xeb,0xe2,
0x95,0x9c,0x87,0x8e,0xb1,0xb8,0xa3,0xaa,
0xec,0xe5,0xfe,0xf7,0xc8,0xc1,0xda,0xd3,
0xa4,0xad,0xb6,0xbf,0x80,0x89,0x92,0x9b,
0x7c,0x75,0x6e,0x67,0x58,0x51,0x4a,0x43,
0x34,0x3d,0x26,0x2f,0x10,0x19,0x02,0x0b,
0xd7,0xde,0xc5,0xcc,0xf3,0xfa,0xe1,0xe8,
0x9f,0x96,0x8d,0x84,0xbb,0xb2,0xa9,0xa0,
0x47,0x4e,0x55,0x5c,0x63,0x6a,0x71,0x78,
0x0f,0x06,0x1d,0x14,0x2b,0x22,0x39,0x30,
0x9a,0x93,0x88,0x81,0xbe,0xb7,0xac,0xa5,
0xd2,0xdb,0xc0,0xc9,0xf6,0xff,0xe4,0xed,
0x0a,0x03,0x18,0x11,0x2e,0x27,0x3c,0x35,
0x42,0x4b,0x50,0x59,0x66,0x6f,0x74,0x7d,
0xa1,0xa8,0xb3,0xba,0x85,0x8c,0x97,0x9e,
0xe9,0xe0,0xfb,0xf2,0xcd,0xc4,0xdf,0xd6,
0x31,0x38,0x23,0x2a,0x15,0x1c,0x07,0x0e,
0x79,0x70,0x6b,0x62,0x5d,0x54,0x4f,0x46
};
static const uint_8t gfmul_b[256] = {
0x00,0x0b,0x16,0x1d,0x2c,0x27,0x3a,0x31,
0x58,0x53,0x4e,0x45,0x74,0x7f,0x62,0x69,
0xb0,0xbb,0xa6,0xad,0x9c,0x97,0x8a,0x81,
0xe8,0xe3,0xfe,0xf5,0xc4,0xcf,0xd2,0xd9,
0x7b,0x70,0x6d,0x66,0x57,0x5c,0x41,0x4a,
0x23,0x28,0x35,0x3e,0x0f,0x04,0x19,0x12,
0xcb,0xc0,0xdd,0xd6,0xe7,0xec,0xf1,0xfa,
0x93,0x98,0x85,0x8e,0xbf,0xb4,0xa9,0xa2,
0xf6,0xfd,0xe0,0xeb,0xda,0xd1,0xcc,0xc7,
0xae,0xa5,0xb8,0xb3,0x82,0x89,0x94,0x9f,
0x46,0x4d,0x50,0x5b,0x6a,0x61,0x7c,0x77,
0x1e,0x15,0x08,0x03,0x32,0x39,0x24,0x2f,
0x8d,0x86,0x9b,0x90,0xa1,0xaa,0xb7,0xbc,
0xd5,0xde,0xc3,0xc8,0xf9,0xf2,0xef,0xe4,
0x3d,0x36,0x2b,0x20,0x11,0x1a,0x07,0x0c,
0x65,0x6e,0x73,0x78,0x49,0x42,0x5f,0x54,
0xf7,0xfc,0xe1,0xea,0xdb,0xd0,0xcd,0xc6,
0xaf,0xa4,0xb9,0xb2,0x83,0x88,0x95,0x9e,
0x47,0x4c,0x51,0x5a,0x6b,0x60,0x7d,0x76,
0x1f,0x14,0x09,0x02,0x33,0x38,0x25,0x2e,
0x8c,0x87,0x9a,0x91,0xa0,0xab,0xb6,0xbd,
0xd4,0xdf,0xc2,0xc9,0xf8,0xf3,0xee,0xe5,
0x3c,0x37,0x2a,0x21,0x10,0x1b,0x06,0x0d,
0x64,0x6f,0x72,0x79,0x48,0x43,0x5e,0x55,
0x01,0x0a,0x17,0x1c,0x2d,0x26,0x3b,0x30,
0x59,0x52,0x4f,0x44,0x75,0x7e,0x63,0x68,
0xb1,0xba,0xa7,0xac,0x9d,0x96,0x8b,0x80,
0xe9,0xe2,0xff,0xf4,0xc5,0xce,0xd3,0xd8,
0x7a,0x71,0x6c,0x67,0x56,0x5d,0x40,0x4b,
0x22,0x29,0x34,0x3f,0x0e,0x05,0x18,0x13,
0xca,0xc1,0xdc,0xd7,0xe6,0xed,0xf0,0xfb,
0x92,0x99,0x84,0x8f,0xbe,0xb5,0xa8,0xa3
};
static const uint_8t gfmul_d[256] = {
0x00,0x0d,0x1a,0x17,0x34,0x39,0x2e,0x23,
0x68,0x65,0x72,0x7f,0x5c,0x51,0x46,0x4b,
0xd0,0xdd,0xca,0xc7,0xe4,0xe9,0xfe,0xf3,
0xb8,0xb5,0xa2,0xaf,0x8c,0x81,0x96,0x9b,
0xbb,0xb6,0xa1,0xac,0x8f,0x82,0x95,0x98,
0xd3,0xde,0xc9,0xc4,0xe7,0xea,0xfd,0xf0,
0x6b,0x66,0x71,0x7c,0x5f,0x52,0x45,0x48,
0x03,0x0e,0x19,0x14,0x37,0x3a,0x2d,0x20,
0x6d,0x60,0x77,0x7a,0x59,0x54,0x43,0x4e,
0x05,0x08,0x1f,0x12,0x31,0x3c,0x2b,0x26,
0xbd,0xb0,0xa7,0xaa,0x89,0x84,0x93,0x9e,
0xd5,0xd8,0xcf,0xc2,0xe1,0xec,0xfb,0xf6,
0xd6,0xdb,0xcc,0xc1,0xe2,0xef,0xf8,0xf5,
0xbe,0xb3,0xa4,0xa9,0x8a,0x87,0x90,0x9d,
0x06,0x0b,0x1c,0x11,0x32,0x3f,0x28,0x25,
0x6e,0x63,0x74,0x79,0x5a,0x57,0x40,0x4d,
0xda,0xd7,0xc0,0xcd,0xee,0xe3,0xf4,0xf9,
0xb2,0xbf,0xa8,0xa5,0x86,0x8b,0x9c,0x91,
0x0a,0x07,0x10,0x1d,0x3e,0x33,0x24,0x29,
0x62,0x6f,0x78,0x75,0x56,0x5b,0x4c,0x41,
0x61,0x6c,0x7b,0x76,0x55,0x58,0x4f,0x42,
0x09,0x04,0x13,0x1e,0x3d,0x30,0x27,0x2a,
0xb1,0xbc,0xab,0xa6,0x85,0x88,0x9f,0x92,
0xd9,0xd4,0xc3,0xce,0xed,0xe0,0xf7,0xfa,
0xb7,0xba,0xad,0xa0,0x83,0x8e,0x99,0x94,
0xdf,0xd2,0xc5,0xc8,0xeb,0xe6,0xf1,0xfc,
0x67,0x6a,0x7d,0x70,0x53,0x5e,0x49,0x44,
0x0f,0x02,0x15,0x18,0x3b,0x36,0x21,0x2c,
0x0c,0x01,0x16,0x1b,0x38,0x35,0x22,0x2f,
0x64,0x69,0x7e,0x73,0x50,0x5d,0x4a,0x47,
0xdc,0xd1,0xc6,0xcb,0xe8,0xe5,0xf2,0xff,
0xb4,0xb9,0xae,0xa3,0x80,0x8d,0x9a,0x97
};
static const uint_8t gfmul_e[256] = {
0x00,0x0e,0x1c,0x12,0x38,0x36,0x24,0x2a,
0x70,0x7e,0x6c,0x62,0x48,0x46,0x54,0x5a,
0xe0,0xee,0xfc,0xf2,0xd8,0xd6,0xc4,0xca,
0x90,0x9e,0x8c,0x82,0xa8,0xa6,0xb4,0xba,
0xdb,0xd5,0xc7,0xc9,0xe3,0xed,0xff,0xf1,
0xab,0xa5,0xb7,0xb9,0x93,0x9d,0x8f,0x81,
0x3b,0x35,0x27,0x29,0x03,0x0d,0x1f,0x11,
0x4b,0x45,0x57,0x59,0x73,0x7d,0x6f,0x61,
0xad,0xa3,0xb1,0xbf,0x95,0x9b,0x89,0x87,
0xdd,0xd3,0xc1,0xcf,0xe5,0xeb,0xf9,0xf7,
0x4d,0x43,0x51,0x5f,0x75,0x7b,0x69,0x67,
0x3d,0x33,0x21,0x2f,0x05,0x0b,0x19,0x17,
0x76,0x78,0x6a,0x64,0x4e,0x40,0x52,0x5c,
0x06,0x08,0x1a,0x14,0x3e,0x30,0x22,0x2c,
0x96,0x98,0x8a,0x84,0xae,0xa0,0xb2,0xbc,
0xe6,0xe8,0xfa,0xf4,0xde,0xd0,0xc2,0xcc,
0x41,0x4f,0x5d,0x53,0x79,0x77,0x65,0x6b,
0x31,0x3f,0x2d,0x23,0x09,0x07,0x15,0x1b,
0xa1,0xaf,0xbd,0xb3,0x99,0x97,0x85,0x8b,
0xd1,0xdf,0xcd,0xc3,0xe9,0xe7,0xf5,0xfb,
0x9a,0x94,0x86,0x88,0xa2,0xac,0xbe,0xb0,
0xea,0xe4,0xf6,0xf8,0xd2,0xdc,0xce,0xc0,
0x7a,0x74,0x66,0x68,0x42,0x4c,0x5e,0x50,
0x0a,0x04,0x16,0x18,0x32,0x3c,0x2e,0x20,
0xec,0xe2,0xf0,0xfe,0xd4,0xda,0xc8,0xc6,
0x9c,0x92,0x80,0x8e,0xa4,0xaa,0xb8,0xb6,
0x0c,0x02,0x10,0x1e,0x34,0x3a,0x28,0x26,
0x7c,0x72,0x60,0x6e,0x44,0x4a,0x58,0x56,
0x37,0x39,0x2b,0x25,0x0f,0x01,0x13,0x1d,
0x47,0x49,0x5b,0x55,0x7f,0x71,0x63,0x6d,
0xd7,0xd9,0xcb,0xc5,0xef,0xe1,0xf3,0xfd,
0xa7,0xa9,0xbb,0xb5,0x9f,0x91,0x83,0x8d
};
#if defined( HAVE_UINT_32T )
typedef unsigned long uint_32t;
#endif
#if defined( HAVE_MEMCPY )
# define block_copy(d, s, l) memcpy(d, s, l)
# define block16_copy(d, s) memcpy(d, s, N_BLOCK)
#else
# define block_copy(d, s, l) copy_block(d, s, l)
# define block16_copy(d, s) copy_block16(d, s)
/* block size 'nn' must be a multiple of four */
static void copy_block16( void *d, const void *s )
{
#if defined( HAVE_UINT_32T )
((uint_32t*)d)[ 0] = ((uint_32t*)s)[ 0];
((uint_32t*)d)[ 1] = ((uint_32t*)s)[ 1];
((uint_32t*)d)[ 2] = ((uint_32t*)s)[ 2];
((uint_32t*)d)[ 3] = ((uint_32t*)s)[ 3];
#else
((uint_8t*)d)[ 0] = ((uint_8t*)s)[ 0];
((uint_8t*)d)[ 1] = ((uint_8t*)s)[ 1];
((uint_8t*)d)[ 2] = ((uint_8t*)s)[ 2];
((uint_8t*)d)[ 3] = ((uint_8t*)s)[ 3];
((uint_8t*)d)[ 4] = ((uint_8t*)s)[ 4];
((uint_8t*)d)[ 5] = ((uint_8t*)s)[ 5];
((uint_8t*)d)[ 6] = ((uint_8t*)s)[ 6];
((uint_8t*)d)[ 7] = ((uint_8t*)s)[ 7];
((uint_8t*)d)[ 8] = ((uint_8t*)s)[ 8];
((uint_8t*)d)[ 9] = ((uint_8t*)s)[ 9];
((uint_8t*)d)[10] = ((uint_8t*)s)[10];
((uint_8t*)d)[11] = ((uint_8t*)s)[11];
((uint_8t*)d)[12] = ((uint_8t*)s)[12];
((uint_8t*)d)[13] = ((uint_8t*)s)[13];
((uint_8t*)d)[14] = ((uint_8t*)s)[14];
((uint_8t*)d)[15] = ((uint_8t*)s)[15];
#endif
}
static void copy_block( void * d, void *s, uint_8t nn )
{
while( nn-- )
*((uint8_t*)d)++ = *((uint8_t*)s)++;
}
#endif
static void copy_and_key( void *d, const void *s, const void *k )
{
#if defined( HAVE_UINT_32T )
((uint_32t*)d)[ 0] = ((uint_32t*)s)[ 0] ^ ((uint_32t*)k)[ 0];
((uint_32t*)d)[ 1] = ((uint_32t*)s)[ 1] ^ ((uint_32t*)k)[ 1];
((uint_32t*)d)[ 2] = ((uint_32t*)s)[ 2] ^ ((uint_32t*)k)[ 2];
((uint_32t*)d)[ 3] = ((uint_32t*)s)[ 3] ^ ((uint_32t*)k)[ 3];
#elif 1
((uint_8t*)d)[ 0] = ((uint_8t*)s)[ 0] ^ ((uint_8t*)k)[ 0];
((uint_8t*)d)[ 1] = ((uint_8t*)s)[ 1] ^ ((uint_8t*)k)[ 1];
((uint_8t*)d)[ 2] = ((uint_8t*)s)[ 2] ^ ((uint_8t*)k)[ 2];
((uint_8t*)d)[ 3] = ((uint_8t*)s)[ 3] ^ ((uint_8t*)k)[ 3];
((uint_8t*)d)[ 4] = ((uint_8t*)s)[ 4] ^ ((uint_8t*)k)[ 4];
((uint_8t*)d)[ 5] = ((uint_8t*)s)[ 5] ^ ((uint_8t*)k)[ 5];
((uint_8t*)d)[ 6] = ((uint_8t*)s)[ 6] ^ ((uint_8t*)k)[ 6];
((uint_8t*)d)[ 7] = ((uint_8t*)s)[ 7] ^ ((uint_8t*)k)[ 7];
((uint_8t*)d)[ 8] = ((uint_8t*)s)[ 8] ^ ((uint_8t*)k)[ 8];
((uint_8t*)d)[ 9] = ((uint_8t*)s)[ 9] ^ ((uint_8t*)k)[ 9];
((uint_8t*)d)[10] = ((uint_8t*)s)[10] ^ ((uint_8t*)k)[10];
((uint_8t*)d)[11] = ((uint_8t*)s)[11] ^ ((uint_8t*)k)[11];
((uint_8t*)d)[12] = ((uint_8t*)s)[12] ^ ((uint_8t*)k)[12];
((uint_8t*)d)[13] = ((uint_8t*)s)[13] ^ ((uint_8t*)k)[13];
((uint_8t*)d)[14] = ((uint_8t*)s)[14] ^ ((uint_8t*)k)[14];
((uint_8t*)d)[15] = ((uint_8t*)s)[15] ^ ((uint_8t*)k)[15];
#else
block16_copy(d, s);
xor_block(d, k);
#endif
}
static void shift_sub_rows( uint_8t st[N_BLOCK] )
{ uint_8t tt;
st[ 0] = s_box[st[ 0]]; st[ 4] = s_box[st[ 4]];
st[ 8] = s_box[st[ 8]]; st[12] = s_box[st[12]];
tt = st[1]; st[ 1] = s_box[st[ 5]]; st[ 5] = s_box[st[ 9]];
st[ 9] = s_box[st[13]]; st[13] = s_box[ tt ];
tt = st[2]; st[ 2] = s_box[st[10]]; st[10] = s_box[ tt ];
tt = st[6]; st[ 6] = s_box[st[14]]; st[14] = s_box[ tt ];
tt = st[15]; st[15] = s_box[st[11]]; st[11] = s_box[st[ 7]];
st[ 7] = s_box[st[ 3]]; st[ 3] = s_box[ tt ];
}
static void inv_shift_sub_rows( uint_8t st[N_BLOCK] )
{ uint_8t tt;
st[ 0] = inv_s_box[st[ 0]]; st[ 4] = inv_s_box[st[ 4]];
st[ 8] = inv_s_box[st[ 8]]; st[12] = inv_s_box[st[12]];
tt = st[13]; st[13] = inv_s_box[st[9]]; st[ 9] = inv_s_box[st[5]];
st[ 5] = inv_s_box[st[1]]; st[ 1] = inv_s_box[ tt ];
tt = st[2]; st[ 2] = inv_s_box[st[10]]; st[10] = inv_s_box[ tt ];
tt = st[6]; st[ 6] = inv_s_box[st[14]]; st[14] = inv_s_box[ tt ];
tt = st[3]; st[ 3] = inv_s_box[st[ 7]]; st[ 7] = inv_s_box[st[11]];
st[11] = inv_s_box[st[15]]; st[15] = inv_s_box[ tt ];
}
#if defined( VERSION_1 )
static void mix_sub_columns( uint_8t dt[N_BLOCK] )
{ uint_8t st[N_BLOCK];
block16_copy(st, dt);
#else
static void mix_sub_columns( uint_8t dt[N_BLOCK], uint_8t st[N_BLOCK] )
{
#endif
dt[ 0] = gfm2_s_box[st[0]] ^ gfm3_s_box[st[5]] ^ s_box[st[10]] ^ s_box[st[15]];
dt[ 1] = s_box[st[0]] ^ gfm2_s_box[st[5]] ^ gfm3_s_box[st[10]] ^ s_box[st[15]];
dt[ 2] = s_box[st[0]] ^ s_box[st[5]] ^ gfm2_s_box[st[10]] ^ gfm3_s_box[st[15]];
dt[ 3] = gfm3_s_box[st[0]] ^ s_box[st[5]] ^ s_box[st[10]] ^ gfm2_s_box[st[15]];
dt[ 4] = gfm2_s_box[st[4]] ^ gfm3_s_box[st[9]] ^ s_box[st[14]] ^ s_box[st[3]];
dt[ 5] = s_box[st[4]] ^ gfm2_s_box[st[9]] ^ gfm3_s_box[st[14]] ^ s_box[st[3]];
dt[ 6] = s_box[st[4]] ^ s_box[st[9]] ^ gfm2_s_box[st[14]] ^ gfm3_s_box[st[3]];
dt[ 7] = gfm3_s_box[st[4]] ^ s_box[st[9]] ^ s_box[st[14]] ^ gfm2_s_box[st[3]];
dt[ 8] = gfm2_s_box[st[8]] ^ gfm3_s_box[st[13]] ^ s_box[st[2]] ^ s_box[st[7]];
dt[ 9] = s_box[st[8]] ^ gfm2_s_box[st[13]] ^ gfm3_s_box[st[2]] ^ s_box[st[7]];
dt[10] = s_box[st[8]] ^ s_box[st[13]] ^ gfm2_s_box[st[2]] ^ gfm3_s_box[st[7]];
dt[11] = gfm3_s_box[st[8]] ^ s_box[st[13]] ^ s_box[st[2]] ^ gfm2_s_box[st[7]];
dt[12] = gfm2_s_box[st[12]] ^ gfm3_s_box[st[1]] ^ s_box[st[6]] ^ s_box[st[11]];
dt[13] = s_box[st[12]] ^ gfm2_s_box[st[1]] ^ gfm3_s_box[st[6]] ^ s_box[st[11]];
dt[14] = s_box[st[12]] ^ s_box[st[1]] ^ gfm2_s_box[st[6]] ^ gfm3_s_box[st[11]];
dt[15] = gfm3_s_box[st[12]] ^ s_box[st[1]] ^ s_box[st[6]] ^ gfm2_s_box[st[11]];
}
#if defined( VERSION_1 )
static void inv_mix_sub_columns( uint_8t dt[N_BLOCK] )
{ uint_8t st[N_BLOCK];
block16_copy(st, dt);
#else
static void inv_mix_sub_columns( uint_8t dt[N_BLOCK], uint_8t st[N_BLOCK] )
{
#endif
dt[ 0] = inv_s_box[gfmul_e[st[ 0]] ^ gfmul_b[st[ 1]] ^ gfmul_d[st[ 2]] ^ gfmul_9[st[ 3]]];
dt[ 5] = inv_s_box[gfmul_9[st[ 0]] ^ gfmul_e[st[ 1]] ^ gfmul_b[st[ 2]] ^ gfmul_d[st[ 3]]];
dt[10] = inv_s_box[gfmul_d[st[ 0]] ^ gfmul_9[st[ 1]] ^ gfmul_e[st[ 2]] ^ gfmul_b[st[ 3]]];
dt[15] = inv_s_box[gfmul_b[st[ 0]] ^ gfmul_d[st[ 1]] ^ gfmul_9[st[ 2]] ^ gfmul_e[st[ 3]]];
dt[ 4] = inv_s_box[gfmul_e[st[ 4]] ^ gfmul_b[st[ 5]] ^ gfmul_d[st[ 6]] ^ gfmul_9[st[ 7]]];
dt[ 9] = inv_s_box[gfmul_9[st[ 4]] ^ gfmul_e[st[ 5]] ^ gfmul_b[st[ 6]] ^ gfmul_d[st[ 7]]];
dt[14] = inv_s_box[gfmul_d[st[ 4]] ^ gfmul_9[st[ 5]] ^ gfmul_e[st[ 6]] ^ gfmul_b[st[ 7]]];
dt[ 3] = inv_s_box[gfmul_b[st[ 4]] ^ gfmul_d[st[ 5]] ^ gfmul_9[st[ 6]] ^ gfmul_e[st[ 7]]];
dt[ 8] = inv_s_box[gfmul_e[st[ 8]] ^ gfmul_b[st[ 9]] ^ gfmul_d[st[10]] ^ gfmul_9[st[11]]];
dt[13] = inv_s_box[gfmul_9[st[ 8]] ^ gfmul_e[st[ 9]] ^ gfmul_b[st[10]] ^ gfmul_d[st[11]]];
dt[ 2] = inv_s_box[gfmul_d[st[ 8]] ^ gfmul_9[st[ 9]] ^ gfmul_e[st[10]] ^ gfmul_b[st[11]]];
dt[ 7] = inv_s_box[gfmul_b[st[ 8]] ^ gfmul_d[st[ 9]] ^ gfmul_9[st[10]] ^ gfmul_e[st[11]]];
dt[12] = inv_s_box[gfmul_e[st[12]] ^ gfmul_b[st[13]] ^ gfmul_d[st[14]] ^ gfmul_9[st[15]]];
dt[ 1] = inv_s_box[gfmul_9[st[12]] ^ gfmul_e[st[13]] ^ gfmul_b[st[14]] ^ gfmul_d[st[15]]];
dt[ 6] = inv_s_box[gfmul_d[st[12]] ^ gfmul_9[st[13]] ^ gfmul_e[st[14]] ^ gfmul_b[st[15]]];
dt[11] = inv_s_box[gfmul_b[st[12]] ^ gfmul_d[st[13]] ^ gfmul_9[st[14]] ^ gfmul_e[st[15]]];
}
#if defined( AES_ENC_PREKEYED ) || defined( AES_DEC_PREKEYED )
/* Set the cipher key for the pre-keyed version */
return_type aes_set_key( const unsigned char key[], length_type keylen, aes_context ctx[1] )
{
uint_8t cc, rc, hi;
switch( keylen )
{
case 16:
case 128:
keylen = 16;
break;
case 24:
case 192:
keylen = 24;
break;
case 32:
keylen = 32;
break;
default:
ctx->rnd = 0;
return -1;
}
block_copy(ctx->ksch, key, keylen);
hi = (keylen + 28) << 2;
ctx->rnd = (hi >> 4) - 1;
for( cc = keylen, rc = 1; cc < hi; cc += 4 )
{ uint_8t tt, t0, t1, t2, t3;
t0 = ctx->ksch[cc - 4];
t1 = ctx->ksch[cc - 3];
t2 = ctx->ksch[cc - 2];
t3 = ctx->ksch[cc - 1];
if( cc % keylen == 0 )
{
tt = t0;
t0 = s_box[t1] ^ rc;
t1 = s_box[t2];
t2 = s_box[t3];
t3 = s_box[tt];
rc = f2(rc);
}
else if( keylen > 24 && cc % keylen == 16 )
{
t0 = s_box[t0];
t1 = s_box[t1];
t2 = s_box[t2];
t3 = s_box[t3];
}
tt = cc - keylen;
ctx->ksch[cc + 0] = ctx->ksch[tt + 0] ^ t0;
ctx->ksch[cc + 1] = ctx->ksch[tt + 1] ^ t1;
ctx->ksch[cc + 2] = ctx->ksch[tt + 2] ^ t2;
ctx->ksch[cc + 3] = ctx->ksch[tt + 3] ^ t3;
}
return 0;
}
#endif
#if defined( AES_ENC_PREKEYED )
/* Encrypt a single block of 16 bytes */
return_type aes_encrypt( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK], const aes_context ctx[1] )
{
if( ctx->rnd )
{
uint_8t s1[N_BLOCK], r;
copy_and_key( s1, in, ctx->ksch );
for( r = 1 ; r < ctx->rnd ; ++r )
#if defined( VERSION_1 )
{
mix_sub_columns( s1 );
add_round_key( s1, ctx->ksch + r * N_BLOCK);
}
#else
{ uint_8t s2[N_BLOCK];
mix_sub_columns( s2, s1 );
copy_and_key( s1, s2, ctx->ksch + r * N_BLOCK);
}
#endif
shift_sub_rows( s1 );
copy_and_key( out, s1, ctx->ksch + r * N_BLOCK );
}
else
return -1;
return 0;
}
#endif
#if defined( AES_DEC_PREKEYED )
/* Decrypt a single block of 16 bytes */
return_type aes_decrypt( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK], const aes_context ctx[1] )
{
if( ctx->rnd )
{
uint_8t s1[N_BLOCK], r;
copy_and_key( s1, in, ctx->ksch + ctx->rnd * N_BLOCK );
inv_shift_sub_rows( s1 );
for( r = ctx->rnd ; --r ; )
#if defined( VERSION_1 )
{
add_round_key( s1, ctx->ksch + r * N_BLOCK );
inv_mix_sub_columns( s1 );
}
#else
{ uint_8t s2[N_BLOCK];
copy_and_key( s2, s1, ctx->ksch + r * N_BLOCK );
inv_mix_sub_columns( s1, s2 );
}
#endif
copy_and_key( out, s1, ctx->ksch );
}
else
return -1;
return 0;
}
#endif
#if defined( AES_ENC_128_OTFK )
/* The 'on the fly' encryption key update for for 128 bit keys */
static void update_encrypt_key_128( uint_8t k[N_BLOCK], uint_8t *rc )
{ uint_8t cc;
k[0] ^= s_box[k[13]] ^ *rc;
k[1] ^= s_box[k[14]];
k[2] ^= s_box[k[15]];
k[3] ^= s_box[k[12]];
*rc = f2( *rc );
for(cc = 4; cc < 16; cc += 4 )
{
k[cc + 0] ^= k[cc - 4];
k[cc + 1] ^= k[cc - 3];
k[cc + 2] ^= k[cc - 2];
k[cc + 3] ^= k[cc - 1];
}
}
/* Encrypt a single block of 16 bytes with 'on the fly' 128 bit keying */
void aes_encrypt_128( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK],
const unsigned char key[N_BLOCK], unsigned char o_key[N_BLOCK] )
{ uint_8t s1[N_BLOCK], r, rc = 1;
if(o_key != key)
block16_copy( o_key, key );
copy_and_key( s1, in, o_key );
for( r = 1 ; r < 10 ; ++r )
#if defined( VERSION_1 )
{
mix_sub_columns( s1 );
update_encrypt_key_128( o_key, &rc );
add_round_key( s1, o_key );
}
#else
{ uint_8t s2[N_BLOCK];
mix_sub_columns( s2, s1 );
update_encrypt_key_128( o_key, &rc );
copy_and_key( s1, s2, o_key );
}
#endif
shift_sub_rows( s1 );
update_encrypt_key_128( o_key, &rc );
copy_and_key( out, s1, o_key );
}
#endif
#if defined( AES_DEC_128_OTFK )
/* The 'on the fly' decryption key update for for 128 bit keys */
static void update_decrypt_key_128( uint_8t k[N_BLOCK], uint_8t *rc )
{ uint_8t cc;
for( cc = 12; cc > 0; cc -= 4 )
{
k[cc + 0] ^= k[cc - 4];
k[cc + 1] ^= k[cc - 3];
k[cc + 2] ^= k[cc - 2];
k[cc + 3] ^= k[cc - 1];
}
*rc = d2(*rc);
k[0] ^= s_box[k[13]] ^ *rc;
k[1] ^= s_box[k[14]];
k[2] ^= s_box[k[15]];
k[3] ^= s_box[k[12]];
}
/* Decrypt a single block of 16 bytes with 'on the fly' 128 bit keying */
void aes_decrypt_128( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK],
const unsigned char key[N_BLOCK], unsigned char o_key[N_BLOCK] )
{
uint_8t s1[N_BLOCK], r, rc = 0x6c;
if(o_key != key)
block16_copy( o_key, key );
copy_and_key( s1, in, o_key );
inv_shift_sub_rows( s1 );
for( r = 10 ; --r ; )
#if defined( VERSION_1 )
{
update_decrypt_key_128( o_key, &rc );
add_round_key( s1, o_key );
inv_mix_sub_columns( s1 );
}
#else
{ uint_8t s2[N_BLOCK];
update_decrypt_key_128( o_key, &rc );
copy_and_key( s2, s1, o_key );
inv_mix_sub_columns( s1, s2 );
}
#endif
update_decrypt_key_128( o_key, &rc );
copy_and_key( out, s1, o_key );
}
#endif
#if defined( AES_ENC_256_OTFK )
/* The 'on the fly' encryption key update for for 256 bit keys */
static void update_encrypt_key_256( uint_8t k[2 * N_BLOCK], uint_8t *rc )
{ uint_8t cc;
k[0] ^= s_box[k[29]] ^ *rc;
k[1] ^= s_box[k[30]];
k[2] ^= s_box[k[31]];
k[3] ^= s_box[k[28]];
*rc = f2( *rc );
for(cc = 4; cc < 16; cc += 4)
{
k[cc + 0] ^= k[cc - 4];
k[cc + 1] ^= k[cc - 3];
k[cc + 2] ^= k[cc - 2];
k[cc + 3] ^= k[cc - 1];
}
k[16] ^= s_box[k[12]];
k[17] ^= s_box[k[13]];
k[18] ^= s_box[k[14]];
k[19] ^= s_box[k[15]];
for( cc = 20; cc < 32; cc += 4 )
{
k[cc + 0] ^= k[cc - 4];
k[cc + 1] ^= k[cc - 3];
k[cc + 2] ^= k[cc - 2];
k[cc + 3] ^= k[cc - 1];
}
}
/* Encrypt a single block of 16 bytes with 'on the fly' 256 bit keying */
void aes_encrypt_256( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK],
const unsigned char key[2 * N_BLOCK], unsigned char o_key[2 * N_BLOCK] )
{
uint_8t s1[N_BLOCK], r, rc = 1;
if(o_key != key)
{
block16_copy( o_key, key );
block16_copy( o_key + 16, key + 16 );
}
copy_and_key( s1, in, o_key );
for( r = 1 ; r < 14 ; ++r )
#if defined( VERSION_1 )
{
mix_sub_columns(s1);
if( r & 1 )
add_round_key( s1, o_key + 16 );
else
{
update_encrypt_key_256( o_key, &rc );
add_round_key( s1, o_key );
}
}
#else
{ uint_8t s2[N_BLOCK];
mix_sub_columns( s2, s1 );
if( r & 1 )
copy_and_key( s1, s2, o_key + 16 );
else
{
update_encrypt_key_256( o_key, &rc );
copy_and_key( s1, s2, o_key );
}
}
#endif
shift_sub_rows( s1 );
update_encrypt_key_256( o_key, &rc );
copy_and_key( out, s1, o_key );
}
#endif
#if defined( AES_DEC_256_OTFK )
/* The 'on the fly' encryption key update for for 256 bit keys */
static void update_decrypt_key_256( uint_8t k[2 * N_BLOCK], uint_8t *rc )
{ uint_8t cc;
for(cc = 28; cc > 16; cc -= 4)
{
k[cc + 0] ^= k[cc - 4];
k[cc + 1] ^= k[cc - 3];
k[cc + 2] ^= k[cc - 2];
k[cc + 3] ^= k[cc - 1];
}
k[16] ^= s_box[k[12]];
k[17] ^= s_box[k[13]];
k[18] ^= s_box[k[14]];
k[19] ^= s_box[k[15]];
for(cc = 12; cc > 0; cc -= 4)
{
k[cc + 0] ^= k[cc - 4];
k[cc + 1] ^= k[cc - 3];
k[cc + 2] ^= k[cc - 2];
k[cc + 3] ^= k[cc - 1];
}
*rc = d2(*rc);
k[0] ^= s_box[k[29]] ^ *rc;
k[1] ^= s_box[k[30]];
k[2] ^= s_box[k[31]];
k[3] ^= s_box[k[28]];
}
/* Decrypt a single block of 16 bytes with 'on the fly'
256 bit keying
*/
void aes_decrypt_256( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK],
const unsigned char key[2 * N_BLOCK], unsigned char o_key[2 * N_BLOCK] )
{
uint_8t s1[N_BLOCK], r, rc = 0x80;
if(o_key != key)
{
block16_copy( o_key, key );
block16_copy( o_key + 16, key + 16 );
}
copy_and_key( s1, in, o_key );
inv_shift_sub_rows( s1 );
for( r = 14 ; --r ; )
#if defined( VERSION_1 )
{
if( ( r & 1 ) )
{
update_decrypt_key_256( o_key, &rc );
add_round_key( s1, o_key + 16 );
}
else
add_round_key( s1, o_key );
inv_mix_sub_columns( s1 );
}
#else
{ uint_8t s2[N_BLOCK];
if( ( r & 1 ) )
{
update_decrypt_key_256( o_key, &rc );
copy_and_key( s2, s1, o_key + 16 );
}
else
copy_and_key( s2, s1, o_key );
inv_mix_sub_columns( s1, s2 );
}
#endif
copy_and_key( out, s1, o_key );
}
#endif

169
src/utils/crypto/aessmall.h Normal file
View File

@@ -0,0 +1,169 @@
/*
---------------------------------------------------------------------------
Copyright (c) 1998-2006, Brian Gladman, Worcester, UK. All rights reserved.
LICENSE TERMS
The free distribution and use of this software in both source and binary
form is allowed (with or without changes) provided that:
1. distributions of this source code include the above copyright
notice, this list of conditions and the following disclaimer;
2. distributions in binary form include the above copyright
notice, this list of conditions and the following disclaimer
in the documentation and/or other associated materials;
3. the copyright holder's name is not used to endorse products
built using this software without specific written permission.
ALTERNATIVELY, provided that this notice is retained in full, this product
may be distributed under the terms of the GNU General Public License (GPL),
in which case the provisions of the GPL apply INSTEAD OF those given above.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue 09/09/2006
This is an AES implementation that uses only 8-bit byte operations on the
cipher state.
*/
#ifndef AES_H
#define AES_H
#if defined(__cplusplus)
extern "C"
{
#endif
/* This provides speed optimisation opportunities if 32-bit word
operations are available
*/
#if 1
# define HAVE_UINT_32T
#endif
#if 1
# define AES_ENC_PREKEYED /* AES encryption with a precomputed key schedule */
#endif
#if 1
# define AES_DEC_PREKEYED /* AES decryption with a precomputed key schedule */
#endif
#if 0
# define AES_ENC_128_OTFK /* AES encryption with 'on the fly' 128 bit keying */
#endif
#if 0
# define AES_DEC_128_OTFK /* AES decryption with 'on the fly' 128 bit keying */
#endif
#if 0
# define AES_ENC_256_OTFK /* AES encryption with 'on the fly' 256 bit keying */
#endif
#if 0
# define AES_DEC_256_OTFK /* AES decryption with 'on the fly' 256 bit keying */
#endif
#define N_ROW 4
#define N_COL 4
#define N_BLOCK (N_ROW * N_COL)
#define N_MAX_ROUNDS 14
typedef unsigned char uint_8t;
typedef uint_8t return_type;
typedef uint_8t length_type;
typedef uint_8t uint_type;
typedef unsigned char uint_8t;
typedef struct
{ uint_8t ksch[(N_MAX_ROUNDS + 1) * N_BLOCK];
uint_8t rnd;
} aes_context;
/* The following calls are for a precomputed key schedule
NOTE: If the length_type used for the key length is an
unsigned 8-bit character, a key length of 256 bits must
be entered as a length in bytes (valid inputs are hence
128, 192, 16, 24 and 32).
*/
#if defined( AES_ENC_PREKEYED ) || defined( AES_DEC_PREKEYED )
return_type aes_set_key( const unsigned char key[],
length_type keylen,
aes_context ctx[1] );
#endif
#if defined( AES_ENC_PREKEYED )
return_type aes_encrypt( const unsigned char in[N_BLOCK],
unsigned char out[N_BLOCK],
const aes_context ctx[1] );
#endif
#if defined( AES_DEC_PREKEYED )
return_type aes_decrypt( const unsigned char in[N_BLOCK],
unsigned char out[N_BLOCK],
const aes_context ctx[1] );
#endif
/* The following calls are for 'on the fly' keying. In this case the
encryption and decryption keys are different.
The encryption subroutines take a key in an array of bytes in
key[L] where L is 16, 24 or 32 bytes for key lengths of 128,
192, and 256 bits respectively. They then encrypts the input
data, in[] with this key and put the reult in the output array
out[]. In addition, the second key array, o_key[L], is used
to output the key that is needed by the decryption subroutine
to reverse the encryption operation. The two key arrays can
be the same array but in this case the original key will be
overwritten.
In the same way, the decryption subroutines output keys that
can be used to reverse their effect when used for encryption.
Only 128 and 256 bit keys are supported in these 'on the fly'
modes.
*/
#if defined( AES_ENC_128_OTFK )
void aes_encrypt_128( const unsigned char in[N_BLOCK],
unsigned char out[N_BLOCK],
const unsigned char key[N_BLOCK],
uint_8t o_key[N_BLOCK] );
#endif
#if defined( AES_DEC_128_OTFK )
void aes_decrypt_128( const unsigned char in[N_BLOCK],
unsigned char out[N_BLOCK],
const unsigned char key[N_BLOCK],
unsigned char o_key[N_BLOCK] );
#endif
#if defined( AES_ENC_256_OTFK )
void aes_encrypt_256( const unsigned char in[N_BLOCK],
unsigned char out[N_BLOCK],
const unsigned char key[2 * N_BLOCK],
unsigned char o_key[2 * N_BLOCK] );
#endif
#if defined( AES_DEC_256_OTFK )
void aes_decrypt_256( const unsigned char in[N_BLOCK],
unsigned char out[N_BLOCK],
const unsigned char key[2 * N_BLOCK],
unsigned char o_key[2 * N_BLOCK] );
#endif
#if defined(__cplusplus)
}
#endif
#endif

File diff suppressed because it is too large Load Diff

427
src/utils/crypto/aestab.c Normal file
View File

@@ -0,0 +1,427 @@
/*
---------------------------------------------------------------------------
Copyright (c) 1998-2007, Brian Gladman, Worcester, UK. All rights reserved.
LICENSE TERMS
The free distribution and use of this software is allowed (with or without
changes) provided that:
1. source code distributions include the above copyright notice, this
list of conditions and the following disclaimer;
2. binary distributions include the above copyright notice, this list
of conditions and the following disclaimer in their documentation;
3. the name of the copyright holder is not used to endorse products
built using this software without specific written permission.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue Date: 20/12/2007
*/
/* Adapted for TrueCrypt by the TrueCrypt Foundation:
- Added run-time table generator for Aes_x86_v2.asm
*/
#define DO_TABLES
#include "aes.h"
#include "aesopt.h"
#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 rc_data(w) {\
w(0x01), w(0x02), w(0x04), w(0x08), w(0x10),w(0x20), w(0x40), w(0x80),\
w(0x1b), w(0x36) }
#define h0(x) (x)
#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)
#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))
#endif
#if defined(FIXED_TABLES) || !defined(FF_TABLES)
#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY))
#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
#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))
#else
#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
#include "aestab.h"
#if defined(__cplusplus)
extern "C"
{
#endif
#if defined(FIXED_TABLES)
/* implemented in case of wrong call for fixed tables */
AES_RETURN aes_init(void)
{
return EXIT_SUCCESS;
}
#else /* dynamic table generation */
#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 uint_8t hibit(const uint_32t x)
{ uint_8t r = (uint_8t)((x >> 1) | (x >> 2));
r |= (r >> 2);
r |= (r >> 4);
return (r + 1) >> 1;
}
/* return the inverse of the finite field element x */
static uint_8t fi(const uint_8t x)
{ uint_8t 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);
}
}
}
#endif
/* The forward and inverse affine transformations used in the S-box */
#define fwd_affine(x) \
(w = (uint_32t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(uint_8t)(w^(w>>8)))
#define inv_affine(x) \
(w = (uint_32t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(uint_8t)(w^(w>>8)))
static int init = 0;
#ifdef TC_WINDOWS_BOOT
#pragma optimize ("l", on)
uint_8t aes_enc_tab[256][8];
uint_8t aes_dec_tab[256][8];
#endif
AES_RETURN aes_init(void)
{ uint_32t i, w;
#ifdef TC_WINDOWS_BOOT
if (init)
return EXIT_SUCCESS;
for (i = 0; i < 256; ++i)
{
uint_8t x = fwd_affine(fi((uint_8t)i));
aes_enc_tab[i][0] = 0;
aes_enc_tab[i][1] = x;
aes_enc_tab[i][2] = x;
aes_enc_tab[i][3] = f3(x);
aes_enc_tab[i][4] = f2(x);
aes_enc_tab[i][5] = x;
aes_enc_tab[i][6] = x;
aes_enc_tab[i][7] = f3(x);
x = fi((uint_8t)inv_affine((uint_8t)i));
aes_dec_tab[i][0] = fe(x);
aes_dec_tab[i][1] = f9(x);
aes_dec_tab[i][2] = fd(x);
aes_dec_tab[i][3] = fb(x);
aes_dec_tab[i][4] = fe(x);
aes_dec_tab[i][5] = f9(x);
aes_dec_tab[i][6] = fd(x);
aes_dec_tab[i][7] = x;
}
#else // TC_WINDOWS_BOOT
#if defined(FF_TABLES)
uint_8t pow[512], log[256];
if(init)
return EXIT_SUCCESS;
/* 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] = (uint_8t)w;
pow[i + 255] = (uint_8t)w;
log[w] = (uint_8t)i++;
w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0);
}
while (w != 1);
#else
if(init)
return EXIT_SUCCESS;
#endif
for(i = 0, w = 1; i < RC_LENGTH; ++i)
{
t_set(r,c)[i] = bytes2word(w, 0, 0, 0);
w = f2(w);
}
for(i = 0; i < 256; ++i)
{ uint_8t b;
b = fwd_affine(fi((uint_8t)i));
w = bytes2word(f2(b), b, b, f3(b));
#if defined( SBX_SET )
t_set(s,box)[i] = b;
#endif
#if defined( FT1_SET ) /* tables for a normal encryption round */
t_set(f,n)[i] = w;
#endif
#if defined( FT4_SET )
t_set(f,n)[0][i] = w;
t_set(f,n)[1][i] = upr(w,1);
t_set(f,n)[2][i] = upr(w,2);
t_set(f,n)[3][i] = upr(w,3);
#endif
w = bytes2word(b, 0, 0, 0);
#if defined( FL1_SET ) /* tables for last encryption round (may also */
t_set(f,l)[i] = w; /* be used in the key schedule) */
#endif
#if defined( FL4_SET )
t_set(f,l)[0][i] = w;
t_set(f,l)[1][i] = upr(w,1);
t_set(f,l)[2][i] = upr(w,2);
t_set(f,l)[3][i] = upr(w,3);
#endif
#if defined( LS1_SET ) /* table for key schedule if t_set(f,l) above is*/
t_set(l,s)[i] = w; /* not of the required form */
#endif
#if defined( LS4_SET )
t_set(l,s)[0][i] = w;
t_set(l,s)[1][i] = upr(w,1);
t_set(l,s)[2][i] = upr(w,2);
t_set(l,s)[3][i] = upr(w,3);
#endif
b = fi(inv_affine((uint_8t)i));
w = bytes2word(fe(b), f9(b), fd(b), fb(b));
#if defined( IM1_SET ) /* tables for the inverse mix column operation */
t_set(i,m)[b] = w;
#endif
#if defined( IM4_SET )
t_set(i,m)[0][b] = w;
t_set(i,m)[1][b] = upr(w,1);
t_set(i,m)[2][b] = upr(w,2);
t_set(i,m)[3][b] = upr(w,3);
#endif
#if defined( ISB_SET )
t_set(i,box)[i] = b;
#endif
#if defined( IT1_SET ) /* tables for a normal decryption round */
t_set(i,n)[i] = w;
#endif
#if defined( IT4_SET )
t_set(i,n)[0][i] = w;
t_set(i,n)[1][i] = upr(w,1);
t_set(i,n)[2][i] = upr(w,2);
t_set(i,n)[3][i] = upr(w,3);
#endif
w = bytes2word(b, 0, 0, 0);
#if defined( IL1_SET ) /* tables for last decryption round */
t_set(i,l)[i] = w;
#endif
#if defined( IL4_SET )
t_set(i,l)[0][i] = w;
t_set(i,l)[1][i] = upr(w,1);
t_set(i,l)[2][i] = upr(w,2);
t_set(i,l)[3][i] = upr(w,3);
#endif
}
#endif // TC_WINDOWS_BOOT
init = 1;
return EXIT_SUCCESS;
}
#endif
#if defined(__cplusplus)
}
#endif

174
src/utils/crypto/aestab.h Normal file
View File

@@ -0,0 +1,174 @@
/*
---------------------------------------------------------------------------
Copyright (c) 1998-2007, Brian Gladman, Worcester, UK. All rights reserved.
LICENSE TERMS
The free distribution and use of this software is allowed (with or without
changes) provided that:
1. source code distributions include the above copyright notice, this
list of conditions and the following disclaimer;
2. binary distributions include the above copyright notice, this list
of conditions and the following disclaimer in their documentation;
3. the name of the copyright holder is not used to endorse products
built using this software without specific written permission.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue Date: 20/12/2007
This file contains the code for declaring the tables needed to implement
AES. The file aesopt.h is assumed to be included before this header file.
If there are no global variables, the definitions here can be used to put
the AES tables in a structure so that a pointer can then be added to the
AES context to pass them to the AES routines that need them. If this
facility is used, the calling program has to ensure that this pointer is
managed appropriately. In particular, the value of the t_dec(in,it) item
in the table structure must be set to zero in order to ensure that the
tables are initialised. In practice the three code sequences in aeskey.c
that control the calls to aes_init() and the aes_init() routine itself will
have to be changed for a specific implementation. If global variables are
available it will generally be preferable to use them with the precomputed
FIXED_TABLES option that uses static global tables.
The following defines can be used to control the way the tables
are defined, initialised and used in embedded environments that
require special features for these purposes
the 't_dec' construction is used to declare fixed table arrays
the 't_set' construction is used to set fixed table values
the 't_use' construction is used to access fixed table values
256 byte tables:
t_xxx(s,box) => forward S box
t_xxx(i,box) => inverse S box
256 32-bit word OR 4 x 256 32-bit word tables:
t_xxx(f,n) => forward normal round
t_xxx(f,l) => forward last round
t_xxx(i,n) => inverse normal round
t_xxx(i,l) => inverse last round
t_xxx(l,s) => key schedule table
t_xxx(i,m) => key schedule table
Other variables and tables:
t_xxx(r,c) => the rcon table
*/
#if !defined( _AESTAB_H )
#define _AESTAB_H
#define t_dec(m,n) t_##m##n
#define t_set(m,n) t_##m##n
#define t_use(m,n) t_##m##n
#if defined(FIXED_TABLES)
# if !defined( __GNUC__ ) && (defined( __MSDOS__ ) || defined( __WIN16__ ))
/* make tables far data to avoid using too much DGROUP space (PG) */
# define CONST const far
# else
# define CONST const
# endif
#else
# define CONST
#endif
#if defined(__cplusplus)
# define EXTERN extern "C"
#elif defined(DO_TABLES)
# define EXTERN
#else
# define EXTERN extern
#endif
#if defined(_MSC_VER) && defined(TABLE_ALIGN)
#define ALIGN __declspec(align(TABLE_ALIGN))
#else
#define ALIGN
#endif
#if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
# define XP_DIR __cdecl
#else
# define XP_DIR
#endif
#if defined(DO_TABLES) && defined(FIXED_TABLES)
#define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256] = b(e)
#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] = { b(e), b(f), b(g), b(h) }
EXTERN ALIGN CONST uint_32t t_dec(r,c)[RC_LENGTH] = rc_data(w0);
#else
#define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256]
#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256]
EXTERN ALIGN CONST uint_32t t_dec(r,c)[RC_LENGTH];
#endif
#if defined( SBX_SET )
d_1(uint_8t, t_dec(s,box), sb_data, h0);
#endif
#if defined( ISB_SET )
d_1(uint_8t, t_dec(i,box), isb_data, h0);
#endif
#if defined( FT1_SET )
d_1(uint_32t, t_dec(f,n), sb_data, u0);
#endif
#if defined( FT4_SET )
d_4(uint_32t, t_dec(f,n), sb_data, u0, u1, u2, u3);
#endif
#if defined( FL1_SET )
d_1(uint_32t, t_dec(f,l), sb_data, w0);
#endif
#if defined( FL4_SET )
d_4(uint_32t, t_dec(f,l), sb_data, w0, w1, w2, w3);
#endif
#if defined( IT1_SET )
d_1(uint_32t, t_dec(i,n), isb_data, v0);
#endif
#if defined( IT4_SET )
d_4(uint_32t, t_dec(i,n), isb_data, v0, v1, v2, v3);
#endif
#if defined( IL1_SET )
d_1(uint_32t, t_dec(i,l), isb_data, w0);
#endif
#if defined( IL4_SET )
d_4(uint_32t, t_dec(i,l), isb_data, w0, w1, w2, w3);
#endif
#if defined( LS1_SET )
#if defined( FL1_SET )
#undef LS1_SET
#else
d_1(uint_32t, t_dec(l,s), sb_data, w0);
#endif
#endif
#if defined( LS4_SET )
#if defined( FL4_SET )
#undef LS4_SET
#else
d_4(uint_32t, t_dec(l,s), sb_data, w0, w1, w2, w3);
#endif
#endif
#if defined( IM1_SET )
d_1(uint_32t, t_dec(i,m), mm_data, v0);
#endif
#if defined( IM4_SET )
d_4(uint_32t, t_dec(i,m), mm_data, v0, v1, v2, v3);
#endif
#endif

113
src/utils/crypto/bf_ecb.c Normal file
View File

@@ -0,0 +1,113 @@
/* Deprecated/legacy */
/* crypto/bf/bf_ecb.c */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* Adapted for TrueCrypt by the TrueCrypt Foundation */
#include "blowfish.h"
#include "bf_locl.h"
#include "../common/endian.h"
/* Blowfish as implemented from 'Blowfish: Springer-Verlag paper'
* (From LECTURE NOTES IN COIMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION,
* CAMBRIDGE SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993)
*/
char *BF_version="BlowFish part of SSLeay 0.8.2b 08-Jan-1998";
char *BF_options(void)
{
#ifdef BF_PTR
return("blowfish(ptr)");
#elif defined(BF_PTR2)
return("blowfish(ptr2)");
#else
return("blowfish(idx)");
#endif
}
void BF_ecb_encrypt(unsigned char *in, unsigned char *out, BF_KEY *ks, int encrypt)
{
BF_LONG l,d[2];
n2l(in,l); d[0]=l;
n2l(in,l); d[1]=l;
if (encrypt)
BF_encrypt(d,ks);
else
BF_decrypt(d,ks);
l=d[0]; l2n(l,out);
l=d[1]; l2n(l,out);
l=d[0]=d[1]=0;
}
void BF_ecb_le_encrypt(unsigned char *in, unsigned char *out, BF_KEY *ks, int encrypt)
{
BF_LONG d[2];
d[0] = LE32(((BF_LONG *)in)[0]);
d[1] = LE32(((BF_LONG *)in)[1]);
if (encrypt)
BF_encrypt(d,ks);
else
BF_decrypt(d,ks);
((BF_LONG *)out)[0] = LE32(d[0]);
((BF_LONG *)out)[1] = LE32(d[1]);
d[0]=d[1]=0;
}

235
src/utils/crypto/bf_enc.c Normal file
View File

@@ -0,0 +1,235 @@
/* Deprecated/legacy */
/* crypto/bf/bf_enc.c */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include "blowfish.h"
#include "bf_locl.h"
/* Blowfish as implemented from 'Blowfish: Springer-Verlag paper'
* (From LECTURE NOTES IN COIMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION,
* CAMBRIDGE SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993)
*/
#if (BF_ROUNDS != 16) && (BF_ROUNDS != 20)
If you set BF_ROUNDS to some value other than 16 or 20, you will have
to modify the code.
#endif
void BF_encrypt(BF_LONG *data, BF_KEY *key)
{
register BF_LONG l,r,*p,*s;
p=key->P;
s= &(key->S[0]);
l=data[0];
r=data[1];
l^=p[0];
BF_ENC(r,l,s,p[ 1]);
BF_ENC(l,r,s,p[ 2]);
BF_ENC(r,l,s,p[ 3]);
BF_ENC(l,r,s,p[ 4]);
BF_ENC(r,l,s,p[ 5]);
BF_ENC(l,r,s,p[ 6]);
BF_ENC(r,l,s,p[ 7]);
BF_ENC(l,r,s,p[ 8]);
BF_ENC(r,l,s,p[ 9]);
BF_ENC(l,r,s,p[10]);
BF_ENC(r,l,s,p[11]);
BF_ENC(l,r,s,p[12]);
BF_ENC(r,l,s,p[13]);
BF_ENC(l,r,s,p[14]);
BF_ENC(r,l,s,p[15]);
BF_ENC(l,r,s,p[16]);
#if BF_ROUNDS == 20
BF_ENC(r,l,s,p[17]);
BF_ENC(l,r,s,p[18]);
BF_ENC(r,l,s,p[19]);
BF_ENC(l,r,s,p[20]);
#endif
r^=p[BF_ROUNDS+1];
data[1]=l&0xffffffffL;
data[0]=r&0xffffffffL;
}
#ifndef BF_DEFAULT_OPTIONS
void BF_decrypt(BF_LONG *data, BF_KEY *key)
{
register BF_LONG l,r,*p,*s;
p=key->P;
s= &(key->S[0]);
l=data[0];
r=data[1];
l^=p[BF_ROUNDS+1];
#if BF_ROUNDS == 20
BF_ENC(r,l,s,p[20]);
BF_ENC(l,r,s,p[19]);
BF_ENC(r,l,s,p[18]);
BF_ENC(l,r,s,p[17]);
#endif
BF_ENC(r,l,s,p[16]);
BF_ENC(l,r,s,p[15]);
BF_ENC(r,l,s,p[14]);
BF_ENC(l,r,s,p[13]);
BF_ENC(r,l,s,p[12]);
BF_ENC(l,r,s,p[11]);
BF_ENC(r,l,s,p[10]);
BF_ENC(l,r,s,p[ 9]);
BF_ENC(r,l,s,p[ 8]);
BF_ENC(l,r,s,p[ 7]);
BF_ENC(r,l,s,p[ 6]);
BF_ENC(l,r,s,p[ 5]);
BF_ENC(r,l,s,p[ 4]);
BF_ENC(l,r,s,p[ 3]);
BF_ENC(r,l,s,p[ 2]);
BF_ENC(l,r,s,p[ 1]);
r^=p[0];
data[1]=l&0xffffffffL;
data[0]=r&0xffffffffL;
}
void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length, BF_KEY *ks, unsigned char *iv, int encrypt)
{
register BF_LONG tin0,tin1;
register BF_LONG tout0,tout1,xor0,xor1;
register long l=length;
BF_LONG tin[2];
if (encrypt)
{
n2l(iv,tout0);
n2l(iv,tout1);
iv-=8;
for (l-=8; l>=0; l-=8)
{
n2l(in,tin0);
n2l(in,tin1);
tin0^=tout0;
tin1^=tout1;
tin[0]=tin0;
tin[1]=tin1;
BF_encrypt(tin,ks);
tout0=tin[0];
tout1=tin[1];
l2n(tout0,out);
l2n(tout1,out);
}
if (l != -8)
{
n2ln(in,tin0,tin1,l+8);
tin0^=tout0;
tin1^=tout1;
tin[0]=tin0;
tin[1]=tin1;
BF_encrypt(tin,ks);
tout0=tin[0];
tout1=tin[1];
l2n(tout0,out);
l2n(tout1,out);
}
l2n(tout0,iv);
l2n(tout1,iv);
}
else
{
n2l(iv,xor0);
n2l(iv,xor1);
iv-=8;
for (l-=8; l>=0; l-=8)
{
n2l(in,tin0);
n2l(in,tin1);
tin[0]=tin0;
tin[1]=tin1;
BF_decrypt(tin,ks);
tout0=tin[0]^xor0;
tout1=tin[1]^xor1;
l2n(tout0,out);
l2n(tout1,out);
xor0=tin0;
xor1=tin1;
}
if (l != -8)
{
n2l(in,tin0);
n2l(in,tin1);
tin[0]=tin0;
tin[1]=tin1;
BF_decrypt(tin,ks);
tout0=tin[0]^xor0;
tout1=tin[1]^xor1;
l2nn(tout0,tout1,out,l+8);
xor0=tin0;
xor1=tin1;
}
l2n(xor0,iv);
l2n(xor1,iv);
}
tin0=tin1=tout0=tout1=xor0=xor1=0;
tin[0]=tin[1]=0;
}
#endif

246
src/utils/crypto/bf_locl.h Normal file
View File

@@ -0,0 +1,246 @@
/* Deprecated/legacy */
/* crypto/bf/bf_locl.org */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*
* Always modify bf_locl.org since bf_locl.h is automatically generated from
* it during SSLeay configuration.
*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*/
/* Special defines which change the way the code is built depending on the
CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
even newer MIPS CPU's, but at the moment one size fits all for
optimization options. Older Sparc's work better with only UNROLL, but
there's no way to tell at compile time what it is you're running on */
#if defined( sun ) /* Newer Sparc's */
# define BF_PTR
#elif defined( __ultrix ) /* Older MIPS */
# define BF_PTR
#elif defined( __osf1__ ) /* Alpha */
/* None */
#elif defined ( _AIX ) /* RS6000 */
/* Unknown */
#elif defined( __hpux ) /* HP-PA */
/* None */
#elif defined( __aux ) /* 68K */
/* Unknown */
#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
/* Unknown */
#elif defined( __sgi ) /* Newer MIPS */
# define BF_PTR
#elif defined( i386 ) /* x86 boxes, should be gcc */
# define BF_PTR2
#elif defined( _MSC_VER ) /* x86 boxes, Visual C */
# define BF_PTR2
#endif /* Systems-specific speed defines */
#undef c2l
#define c2l(c,l) (l =((uint32_t)(*((c)++))) , \
l|=((uint32_t)(*((c)++)))<< 8L, \
l|=((uint32_t)(*((c)++)))<<16L, \
l|=((uint32_t)(*((c)++)))<<24L)
/* NOTE - c is not incremented as per c2l */
#undef c2ln
#define c2ln(c,l1,l2,n) { \
c+=n; \
l1=l2=0; \
switch (n) { \
case 8: l2 =((uint32_t)(*(--(c))))<<24L; \
case 7: l2|=((uint32_t)(*(--(c))))<<16L; \
case 6: l2|=((uint32_t)(*(--(c))))<< 8L; \
case 5: l2|=((uint32_t)(*(--(c)))); \
case 4: l1 =((uint32_t)(*(--(c))))<<24L; \
case 3: l1|=((uint32_t)(*(--(c))))<<16L; \
case 2: l1|=((uint32_t)(*(--(c))))<< 8L; \
case 1: l1|=((uint32_t)(*(--(c)))); \
} \
}
#undef l2c
#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
*((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
*((c)++)=(unsigned char)(((l)>>16L)&0xff), \
*((c)++)=(unsigned char)(((l)>>24L)&0xff))
/* NOTE - c is not incremented as per l2c */
#undef l2cn
#define l2cn(l1,l2,c,n) { \
c+=n; \
switch (n) { \
case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
} \
}
/* NOTE - c is not incremented as per n2l */
#define n2ln(c,l1,l2,n) { \
c+=n; \
l1=l2=0; \
switch (n) { \
case 8: l2 =((uint32_t)(*(--(c)))) ; \
case 7: l2|=((uint32_t)(*(--(c))))<< 8; \
case 6: l2|=((uint32_t)(*(--(c))))<<16; \
case 5: l2|=((uint32_t)(*(--(c))))<<24; \
case 4: l1 =((uint32_t)(*(--(c)))) ; \
case 3: l1|=((uint32_t)(*(--(c))))<< 8; \
case 2: l1|=((uint32_t)(*(--(c))))<<16; \
case 1: l1|=((uint32_t)(*(--(c))))<<24; \
} \
}
/* NOTE - c is not incremented as per l2n */
#define l2nn(l1,l2,c,n) { \
c+=n; \
switch (n) { \
case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \
case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \
case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
} \
}
#undef n2l
#define n2l(c,l) (l =((uint32_t)(*((c)++)))<<24L, \
l|=((uint32_t)(*((c)++)))<<16L, \
l|=((uint32_t)(*((c)++)))<< 8L, \
l|=((uint32_t)(*((c)++))))
#undef l2n
#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
*((c)++)=(unsigned char)(((l)>>16L)&0xff), \
*((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
*((c)++)=(unsigned char)(((l) )&0xff))
/* This is actually a big endian algorithm, the most significate byte
* is used to lookup array 0 */
/* use BF_PTR2 for intel boxes,
* BF_PTR for sparc and MIPS/SGI
* use nothing for Alpha and HP.
*/
#if !defined(BF_PTR) && !defined(BF_PTR2)
#define BF_PTR2
#endif
#define BF_M 0x3fc
#define BF_0 22L
#define BF_1 14L
#define BF_2 6L
#define BF_3 2L /* left shift */
#if defined(BF_PTR2)
/* This is basically a special pentium verson */
#define BF_ENC(LL,R,S,P) \
{ \
BF_LONG t,u,v; \
u=R>>BF_0; \
v=R>>BF_1; \
u&=BF_M; \
v&=BF_M; \
t= *(BF_LONG *)((unsigned char *)&(S[ 0])+u); \
u=R>>BF_2; \
t+= *(BF_LONG *)((unsigned char *)&(S[256])+v); \
v=R<<BF_3; \
u&=BF_M; \
v&=BF_M; \
t^= *(BF_LONG *)((unsigned char *)&(S[512])+u); \
LL^=P; \
t+= *(BF_LONG *)((unsigned char *)&(S[768])+v); \
LL^=t; \
}
#elif defined(BF_PTR)
/* This is normally very good */
#define BF_ENC(LL,R,S,P) \
LL^=P; \
LL^= (((*(BF_LONG *)((unsigned char *)&(S[ 0])+((R>>BF_0)&BF_M))+ \
*(BF_LONG *)((unsigned char *)&(S[256])+((R>>BF_1)&BF_M)))^ \
*(BF_LONG *)((unsigned char *)&(S[512])+((R>>BF_2)&BF_M)))+ \
*(BF_LONG *)((unsigned char *)&(S[768])+((R<<BF_3)&BF_M)));
#else
/* This will always work, even on 64 bit machines and strangly enough,
* on the Alpha it is faster than the pointer versions (both 32 and 64
* versions of BF_LONG) */
#define BF_ENC(LL,R,S,P) \
LL^=P; \
LL^=((( S[ (int)(R>>24L) ] + \
S[0x0100+((int)(R>>16L)&0xff)])^ \
S[0x0200+((int)(R>> 8L)&0xff)])+ \
S[0x0300+((int)(R )&0xff)])&0xffffffffL;
#endif

327
src/utils/crypto/bf_pi.h Normal file
View File

@@ -0,0 +1,327 @@
/* Deprecated/legacy */
/* crypto/bf/bf_pi.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
static BF_KEY bf_init= {
{
0x243f6a88L, 0x85a308d3L, 0x13198a2eL, 0x03707344L,
0xa4093822L, 0x299f31d0L, 0x082efa98L, 0xec4e6c89L,
0x452821e6L, 0x38d01377L, 0xbe5466cfL, 0x34e90c6cL,
0xc0ac29b7L, 0xc97c50ddL, 0x3f84d5b5L, 0xb5470917L,
0x9216d5d9L, 0x8979fb1b
},{
0xd1310ba6L, 0x98dfb5acL, 0x2ffd72dbL, 0xd01adfb7L,
0xb8e1afedL, 0x6a267e96L, 0xba7c9045L, 0xf12c7f99L,
0x24a19947L, 0xb3916cf7L, 0x0801f2e2L, 0x858efc16L,
0x636920d8L, 0x71574e69L, 0xa458fea3L, 0xf4933d7eL,
0x0d95748fL, 0x728eb658L, 0x718bcd58L, 0x82154aeeL,
0x7b54a41dL, 0xc25a59b5L, 0x9c30d539L, 0x2af26013L,
0xc5d1b023L, 0x286085f0L, 0xca417918L, 0xb8db38efL,
0x8e79dcb0L, 0x603a180eL, 0x6c9e0e8bL, 0xb01e8a3eL,
0xd71577c1L, 0xbd314b27L, 0x78af2fdaL, 0x55605c60L,
0xe65525f3L, 0xaa55ab94L, 0x57489862L, 0x63e81440L,
0x55ca396aL, 0x2aab10b6L, 0xb4cc5c34L, 0x1141e8ceL,
0xa15486afL, 0x7c72e993L, 0xb3ee1411L, 0x636fbc2aL,
0x2ba9c55dL, 0x741831f6L, 0xce5c3e16L, 0x9b87931eL,
0xafd6ba33L, 0x6c24cf5cL, 0x7a325381L, 0x28958677L,
0x3b8f4898L, 0x6b4bb9afL, 0xc4bfe81bL, 0x66282193L,
0x61d809ccL, 0xfb21a991L, 0x487cac60L, 0x5dec8032L,
0xef845d5dL, 0xe98575b1L, 0xdc262302L, 0xeb651b88L,
0x23893e81L, 0xd396acc5L, 0x0f6d6ff3L, 0x83f44239L,
0x2e0b4482L, 0xa4842004L, 0x69c8f04aL, 0x9e1f9b5eL,
0x21c66842L, 0xf6e96c9aL, 0x670c9c61L, 0xabd388f0L,
0x6a51a0d2L, 0xd8542f68L, 0x960fa728L, 0xab5133a3L,
0x6eef0b6cL, 0x137a3be4L, 0xba3bf050L, 0x7efb2a98L,
0xa1f1651dL, 0x39af0176L, 0x66ca593eL, 0x82430e88L,
0x8cee8619L, 0x456f9fb4L, 0x7d84a5c3L, 0x3b8b5ebeL,
0xe06f75d8L, 0x85c12073L, 0x401a449fL, 0x56c16aa6L,
0x4ed3aa62L, 0x363f7706L, 0x1bfedf72L, 0x429b023dL,
0x37d0d724L, 0xd00a1248L, 0xdb0fead3L, 0x49f1c09bL,
0x075372c9L, 0x80991b7bL, 0x25d479d8L, 0xf6e8def7L,
0xe3fe501aL, 0xb6794c3bL, 0x976ce0bdL, 0x04c006baL,
0xc1a94fb6L, 0x409f60c4L, 0x5e5c9ec2L, 0x196a2463L,
0x68fb6fafL, 0x3e6c53b5L, 0x1339b2ebL, 0x3b52ec6fL,
0x6dfc511fL, 0x9b30952cL, 0xcc814544L, 0xaf5ebd09L,
0xbee3d004L, 0xde334afdL, 0x660f2807L, 0x192e4bb3L,
0xc0cba857L, 0x45c8740fL, 0xd20b5f39L, 0xb9d3fbdbL,
0x5579c0bdL, 0x1a60320aL, 0xd6a100c6L, 0x402c7279L,
0x679f25feL, 0xfb1fa3ccL, 0x8ea5e9f8L, 0xdb3222f8L,
0x3c7516dfL, 0xfd616b15L, 0x2f501ec8L, 0xad0552abL,
0x323db5faL, 0xfd238760L, 0x53317b48L, 0x3e00df82L,
0x9e5c57bbL, 0xca6f8ca0L, 0x1a87562eL, 0xdf1769dbL,
0xd542a8f6L, 0x287effc3L, 0xac6732c6L, 0x8c4f5573L,
0x695b27b0L, 0xbbca58c8L, 0xe1ffa35dL, 0xb8f011a0L,
0x10fa3d98L, 0xfd2183b8L, 0x4afcb56cL, 0x2dd1d35bL,
0x9a53e479L, 0xb6f84565L, 0xd28e49bcL, 0x4bfb9790L,
0xe1ddf2daL, 0xa4cb7e33L, 0x62fb1341L, 0xcee4c6e8L,
0xef20cadaL, 0x36774c01L, 0xd07e9efeL, 0x2bf11fb4L,
0x95dbda4dL, 0xae909198L, 0xeaad8e71L, 0x6b93d5a0L,
0xd08ed1d0L, 0xafc725e0L, 0x8e3c5b2fL, 0x8e7594b7L,
0x8ff6e2fbL, 0xf2122b64L, 0x8888b812L, 0x900df01cL,
0x4fad5ea0L, 0x688fc31cL, 0xd1cff191L, 0xb3a8c1adL,
0x2f2f2218L, 0xbe0e1777L, 0xea752dfeL, 0x8b021fa1L,
0xe5a0cc0fL, 0xb56f74e8L, 0x18acf3d6L, 0xce89e299L,
0xb4a84fe0L, 0xfd13e0b7L, 0x7cc43b81L, 0xd2ada8d9L,
0x165fa266L, 0x80957705L, 0x93cc7314L, 0x211a1477L,
0xe6ad2065L, 0x77b5fa86L, 0xc75442f5L, 0xfb9d35cfL,
0xebcdaf0cL, 0x7b3e89a0L, 0xd6411bd3L, 0xae1e7e49L,
0x00250e2dL, 0x2071b35eL, 0x226800bbL, 0x57b8e0afL,
0x2464369bL, 0xf009b91eL, 0x5563911dL, 0x59dfa6aaL,
0x78c14389L, 0xd95a537fL, 0x207d5ba2L, 0x02e5b9c5L,
0x83260376L, 0x6295cfa9L, 0x11c81968L, 0x4e734a41L,
0xb3472dcaL, 0x7b14a94aL, 0x1b510052L, 0x9a532915L,
0xd60f573fL, 0xbc9bc6e4L, 0x2b60a476L, 0x81e67400L,
0x08ba6fb5L, 0x571be91fL, 0xf296ec6bL, 0x2a0dd915L,
0xb6636521L, 0xe7b9f9b6L, 0xff34052eL, 0xc5855664L,
0x53b02d5dL, 0xa99f8fa1L, 0x08ba4799L, 0x6e85076aL,
0x4b7a70e9L, 0xb5b32944L, 0xdb75092eL, 0xc4192623L,
0xad6ea6b0L, 0x49a7df7dL, 0x9cee60b8L, 0x8fedb266L,
0xecaa8c71L, 0x699a17ffL, 0x5664526cL, 0xc2b19ee1L,
0x193602a5L, 0x75094c29L, 0xa0591340L, 0xe4183a3eL,
0x3f54989aL, 0x5b429d65L, 0x6b8fe4d6L, 0x99f73fd6L,
0xa1d29c07L, 0xefe830f5L, 0x4d2d38e6L, 0xf0255dc1L,
0x4cdd2086L, 0x8470eb26L, 0x6382e9c6L, 0x021ecc5eL,
0x09686b3fL, 0x3ebaefc9L, 0x3c971814L, 0x6b6a70a1L,
0x687f3584L, 0x52a0e286L, 0xb79c5305L, 0xaa500737L,
0x3e07841cL, 0x7fdeae5cL, 0x8e7d44ecL, 0x5716f2b8L,
0xb03ada37L, 0xf0500c0dL, 0xf01c1f04L, 0x0200b3ffL,
0xae0cf51aL, 0x3cb574b2L, 0x25837a58L, 0xdc0921bdL,
0xd19113f9L, 0x7ca92ff6L, 0x94324773L, 0x22f54701L,
0x3ae5e581L, 0x37c2dadcL, 0xc8b57634L, 0x9af3dda7L,
0xa9446146L, 0x0fd0030eL, 0xecc8c73eL, 0xa4751e41L,
0xe238cd99L, 0x3bea0e2fL, 0x3280bba1L, 0x183eb331L,
0x4e548b38L, 0x4f6db908L, 0x6f420d03L, 0xf60a04bfL,
0x2cb81290L, 0x24977c79L, 0x5679b072L, 0xbcaf89afL,
0xde9a771fL, 0xd9930810L, 0xb38bae12L, 0xdccf3f2eL,
0x5512721fL, 0x2e6b7124L, 0x501adde6L, 0x9f84cd87L,
0x7a584718L, 0x7408da17L, 0xbc9f9abcL, 0xe94b7d8cL,
0xec7aec3aL, 0xdb851dfaL, 0x63094366L, 0xc464c3d2L,
0xef1c1847L, 0x3215d908L, 0xdd433b37L, 0x24c2ba16L,
0x12a14d43L, 0x2a65c451L, 0x50940002L, 0x133ae4ddL,
0x71dff89eL, 0x10314e55L, 0x81ac77d6L, 0x5f11199bL,
0x043556f1L, 0xd7a3c76bL, 0x3c11183bL, 0x5924a509L,
0xf28fe6edL, 0x97f1fbfaL, 0x9ebabf2cL, 0x1e153c6eL,
0x86e34570L, 0xeae96fb1L, 0x860e5e0aL, 0x5a3e2ab3L,
0x771fe71cL, 0x4e3d06faL, 0x2965dcb9L, 0x99e71d0fL,
0x803e89d6L, 0x5266c825L, 0x2e4cc978L, 0x9c10b36aL,
0xc6150ebaL, 0x94e2ea78L, 0xa5fc3c53L, 0x1e0a2df4L,
0xf2f74ea7L, 0x361d2b3dL, 0x1939260fL, 0x19c27960L,
0x5223a708L, 0xf71312b6L, 0xebadfe6eL, 0xeac31f66L,
0xe3bc4595L, 0xa67bc883L, 0xb17f37d1L, 0x018cff28L,
0xc332ddefL, 0xbe6c5aa5L, 0x65582185L, 0x68ab9802L,
0xeecea50fL, 0xdb2f953bL, 0x2aef7dadL, 0x5b6e2f84L,
0x1521b628L, 0x29076170L, 0xecdd4775L, 0x619f1510L,
0x13cca830L, 0xeb61bd96L, 0x0334fe1eL, 0xaa0363cfL,
0xb5735c90L, 0x4c70a239L, 0xd59e9e0bL, 0xcbaade14L,
0xeecc86bcL, 0x60622ca7L, 0x9cab5cabL, 0xb2f3846eL,
0x648b1eafL, 0x19bdf0caL, 0xa02369b9L, 0x655abb50L,
0x40685a32L, 0x3c2ab4b3L, 0x319ee9d5L, 0xc021b8f7L,
0x9b540b19L, 0x875fa099L, 0x95f7997eL, 0x623d7da8L,
0xf837889aL, 0x97e32d77L, 0x11ed935fL, 0x16681281L,
0x0e358829L, 0xc7e61fd6L, 0x96dedfa1L, 0x7858ba99L,
0x57f584a5L, 0x1b227263L, 0x9b83c3ffL, 0x1ac24696L,
0xcdb30aebL, 0x532e3054L, 0x8fd948e4L, 0x6dbc3128L,
0x58ebf2efL, 0x34c6ffeaL, 0xfe28ed61L, 0xee7c3c73L,
0x5d4a14d9L, 0xe864b7e3L, 0x42105d14L, 0x203e13e0L,
0x45eee2b6L, 0xa3aaabeaL, 0xdb6c4f15L, 0xfacb4fd0L,
0xc742f442L, 0xef6abbb5L, 0x654f3b1dL, 0x41cd2105L,
0xd81e799eL, 0x86854dc7L, 0xe44b476aL, 0x3d816250L,
0xcf62a1f2L, 0x5b8d2646L, 0xfc8883a0L, 0xc1c7b6a3L,
0x7f1524c3L, 0x69cb7492L, 0x47848a0bL, 0x5692b285L,
0x095bbf00L, 0xad19489dL, 0x1462b174L, 0x23820e00L,
0x58428d2aL, 0x0c55f5eaL, 0x1dadf43eL, 0x233f7061L,
0x3372f092L, 0x8d937e41L, 0xd65fecf1L, 0x6c223bdbL,
0x7cde3759L, 0xcbee7460L, 0x4085f2a7L, 0xce77326eL,
0xa6078084L, 0x19f8509eL, 0xe8efd855L, 0x61d99735L,
0xa969a7aaL, 0xc50c06c2L, 0x5a04abfcL, 0x800bcadcL,
0x9e447a2eL, 0xc3453484L, 0xfdd56705L, 0x0e1e9ec9L,
0xdb73dbd3L, 0x105588cdL, 0x675fda79L, 0xe3674340L,
0xc5c43465L, 0x713e38d8L, 0x3d28f89eL, 0xf16dff20L,
0x153e21e7L, 0x8fb03d4aL, 0xe6e39f2bL, 0xdb83adf7L,
0xe93d5a68L, 0x948140f7L, 0xf64c261cL, 0x94692934L,
0x411520f7L, 0x7602d4f7L, 0xbcf46b2eL, 0xd4a20068L,
0xd4082471L, 0x3320f46aL, 0x43b7d4b7L, 0x500061afL,
0x1e39f62eL, 0x97244546L, 0x14214f74L, 0xbf8b8840L,
0x4d95fc1dL, 0x96b591afL, 0x70f4ddd3L, 0x66a02f45L,
0xbfbc09ecL, 0x03bd9785L, 0x7fac6dd0L, 0x31cb8504L,
0x96eb27b3L, 0x55fd3941L, 0xda2547e6L, 0xabca0a9aL,
0x28507825L, 0x530429f4L, 0x0a2c86daL, 0xe9b66dfbL,
0x68dc1462L, 0xd7486900L, 0x680ec0a4L, 0x27a18deeL,
0x4f3ffea2L, 0xe887ad8cL, 0xb58ce006L, 0x7af4d6b6L,
0xaace1e7cL, 0xd3375fecL, 0xce78a399L, 0x406b2a42L,
0x20fe9e35L, 0xd9f385b9L, 0xee39d7abL, 0x3b124e8bL,
0x1dc9faf7L, 0x4b6d1856L, 0x26a36631L, 0xeae397b2L,
0x3a6efa74L, 0xdd5b4332L, 0x6841e7f7L, 0xca7820fbL,
0xfb0af54eL, 0xd8feb397L, 0x454056acL, 0xba489527L,
0x55533a3aL, 0x20838d87L, 0xfe6ba9b7L, 0xd096954bL,
0x55a867bcL, 0xa1159a58L, 0xcca92963L, 0x99e1db33L,
0xa62a4a56L, 0x3f3125f9L, 0x5ef47e1cL, 0x9029317cL,
0xfdf8e802L, 0x04272f70L, 0x80bb155cL, 0x05282ce3L,
0x95c11548L, 0xe4c66d22L, 0x48c1133fL, 0xc70f86dcL,
0x07f9c9eeL, 0x41041f0fL, 0x404779a4L, 0x5d886e17L,
0x325f51ebL, 0xd59bc0d1L, 0xf2bcc18fL, 0x41113564L,
0x257b7834L, 0x602a9c60L, 0xdff8e8a3L, 0x1f636c1bL,
0x0e12b4c2L, 0x02e1329eL, 0xaf664fd1L, 0xcad18115L,
0x6b2395e0L, 0x333e92e1L, 0x3b240b62L, 0xeebeb922L,
0x85b2a20eL, 0xe6ba0d99L, 0xde720c8cL, 0x2da2f728L,
0xd0127845L, 0x95b794fdL, 0x647d0862L, 0xe7ccf5f0L,
0x5449a36fL, 0x877d48faL, 0xc39dfd27L, 0xf33e8d1eL,
0x0a476341L, 0x992eff74L, 0x3a6f6eabL, 0xf4f8fd37L,
0xa812dc60L, 0xa1ebddf8L, 0x991be14cL, 0xdb6e6b0dL,
0xc67b5510L, 0x6d672c37L, 0x2765d43bL, 0xdcd0e804L,
0xf1290dc7L, 0xcc00ffa3L, 0xb5390f92L, 0x690fed0bL,
0x667b9ffbL, 0xcedb7d9cL, 0xa091cf0bL, 0xd9155ea3L,
0xbb132f88L, 0x515bad24L, 0x7b9479bfL, 0x763bd6ebL,
0x37392eb3L, 0xcc115979L, 0x8026e297L, 0xf42e312dL,
0x6842ada7L, 0xc66a2b3bL, 0x12754cccL, 0x782ef11cL,
0x6a124237L, 0xb79251e7L, 0x06a1bbe6L, 0x4bfb6350L,
0x1a6b1018L, 0x11caedfaL, 0x3d25bdd8L, 0xe2e1c3c9L,
0x44421659L, 0x0a121386L, 0xd90cec6eL, 0xd5abea2aL,
0x64af674eL, 0xda86a85fL, 0xbebfe988L, 0x64e4c3feL,
0x9dbc8057L, 0xf0f7c086L, 0x60787bf8L, 0x6003604dL,
0xd1fd8346L, 0xf6381fb0L, 0x7745ae04L, 0xd736fcccL,
0x83426b33L, 0xf01eab71L, 0xb0804187L, 0x3c005e5fL,
0x77a057beL, 0xbde8ae24L, 0x55464299L, 0xbf582e61L,
0x4e58f48fL, 0xf2ddfda2L, 0xf474ef38L, 0x8789bdc2L,
0x5366f9c3L, 0xc8b38e74L, 0xb475f255L, 0x46fcd9b9L,
0x7aeb2661L, 0x8b1ddf84L, 0x846a0e79L, 0x915f95e2L,
0x466e598eL, 0x20b45770L, 0x8cd55591L, 0xc902de4cL,
0xb90bace1L, 0xbb8205d0L, 0x11a86248L, 0x7574a99eL,
0xb77f19b6L, 0xe0a9dc09L, 0x662d09a1L, 0xc4324633L,
0xe85a1f02L, 0x09f0be8cL, 0x4a99a025L, 0x1d6efe10L,
0x1ab93d1dL, 0x0ba5a4dfL, 0xa186f20fL, 0x2868f169L,
0xdcb7da83L, 0x573906feL, 0xa1e2ce9bL, 0x4fcd7f52L,
0x50115e01L, 0xa70683faL, 0xa002b5c4L, 0x0de6d027L,
0x9af88c27L, 0x773f8641L, 0xc3604c06L, 0x61a806b5L,
0xf0177a28L, 0xc0f586e0L, 0x006058aaL, 0x30dc7d62L,
0x11e69ed7L, 0x2338ea63L, 0x53c2dd94L, 0xc2c21634L,
0xbbcbee56L, 0x90bcb6deL, 0xebfc7da1L, 0xce591d76L,
0x6f05e409L, 0x4b7c0188L, 0x39720a3dL, 0x7c927c24L,
0x86e3725fL, 0x724d9db9L, 0x1ac15bb4L, 0xd39eb8fcL,
0xed545578L, 0x08fca5b5L, 0xd83d7cd3L, 0x4dad0fc4L,
0x1e50ef5eL, 0xb161e6f8L, 0xa28514d9L, 0x6c51133cL,
0x6fd5c7e7L, 0x56e14ec4L, 0x362abfceL, 0xddc6c837L,
0xd79a3234L, 0x92638212L, 0x670efa8eL, 0x406000e0L,
0x3a39ce37L, 0xd3faf5cfL, 0xabc27737L, 0x5ac52d1bL,
0x5cb0679eL, 0x4fa33742L, 0xd3822740L, 0x99bc9bbeL,
0xd5118e9dL, 0xbf0f7315L, 0xd62d1c7eL, 0xc700c47bL,
0xb78c1b6bL, 0x21a19045L, 0xb26eb1beL, 0x6a366eb4L,
0x5748ab2fL, 0xbc946e79L, 0xc6a376d2L, 0x6549c2c8L,
0x530ff8eeL, 0x468dde7dL, 0xd5730a1dL, 0x4cd04dc6L,
0x2939bbdbL, 0xa9ba4650L, 0xac9526e8L, 0xbe5ee304L,
0xa1fad5f0L, 0x6a2d519aL, 0x63ef8ce2L, 0x9a86ee22L,
0xc089c2b8L, 0x43242ef6L, 0xa51e03aaL, 0x9cf2d0a4L,
0x83c061baL, 0x9be96a4dL, 0x8fe51550L, 0xba645bd6L,
0x2826a2f9L, 0xa73a3ae1L, 0x4ba99586L, 0xef5562e9L,
0xc72fefd3L, 0xf752f7daL, 0x3f046f69L, 0x77fa0a59L,
0x80e4a915L, 0x87b08601L, 0x9b09e6adL, 0x3b3ee593L,
0xe990fd5aL, 0x9e34d797L, 0x2cf0b7d9L, 0x022b8b51L,
0x96d5ac3aL, 0x017da67dL, 0xd1cf3ed6L, 0x7c7d2d28L,
0x1f9f25cfL, 0xadf2b89bL, 0x5ad6b472L, 0x5a88f54cL,
0xe029ac71L, 0xe019a5e6L, 0x47b0acfdL, 0xed93fa9bL,
0xe8d3c48dL, 0x283b57ccL, 0xf8d56629L, 0x79132e28L,
0x785f0191L, 0xed756055L, 0xf7960e44L, 0xe3d35e8cL,
0x15056dd4L, 0x88f46dbaL, 0x03a16125L, 0x0564f0bdL,
0xc3eb9e15L, 0x3c9057a2L, 0x97271aecL, 0xa93a072aL,
0x1b3f6d9bL, 0x1e6321f5L, 0xf59c66fbL, 0x26dcf319L,
0x7533d928L, 0xb155fdf5L, 0x03563482L, 0x8aba3cbbL,
0x28517711L, 0xc20ad9f8L, 0xabcc5167L, 0xccad925fL,
0x4de81751L, 0x3830dc8eL, 0x379d5862L, 0x9320f991L,
0xea7a90c2L, 0xfb3e7bceL, 0x5121ce64L, 0x774fbe32L,
0xa8b6e37eL, 0xc3293d46L, 0x48de5369L, 0x6413e680L,
0xa2ae0810L, 0xdd6db224L, 0x69852dfdL, 0x09072166L,
0xb39a460aL, 0x6445c0ddL, 0x586cdecfL, 0x1c20c8aeL,
0x5bbef7ddL, 0x1b588d40L, 0xccd2017fL, 0x6bb4e3bbL,
0xdda26a7eL, 0x3a59ff45L, 0x3e350a44L, 0xbcb4cdd5L,
0x72eacea8L, 0xfa6484bbL, 0x8d6612aeL, 0xbf3c6f47L,
0xd29be463L, 0x542f5d9eL, 0xaec2771bL, 0xf64e6370L,
0x740e0d8dL, 0xe75b1357L, 0xf8721671L, 0xaf537d5dL,
0x4040cb08L, 0x4eb4e2ccL, 0x34d2466aL, 0x0115af84L,
0xe1b00428L, 0x95983a1dL, 0x06b89fb4L, 0xce6ea048L,
0x6f3f3b82L, 0x3520ab82L, 0x011a1d4bL, 0x277227f8L,
0x611560b1L, 0xe7933fdcL, 0xbb3a792bL, 0x344525bdL,
0xa08839e1L, 0x51ce794bL, 0x2f32c9b7L, 0xa01fbac9L,
0xe01cc87eL, 0xbcc7d1f6L, 0xcf0111c3L, 0xa1e8aac7L,
0x1a908749L, 0xd44fbd9aL, 0xd0dadecbL, 0xd50ada38L,
0x0339c32aL, 0xc6913667L, 0x8df9317cL, 0xe0b12b4fL,
0xf79e59b7L, 0x43f5bb3aL, 0xf2d519ffL, 0x27d9459cL,
0xbf97222cL, 0x15e6fc2aL, 0x0f91fc71L, 0x9b941525L,
0xfae59361L, 0xceb69cebL, 0xc2a86459L, 0x12baa8d1L,
0xb6c1075eL, 0xe3056a0cL, 0x10d25065L, 0xcb03a442L,
0xe0ec6e0eL, 0x1698db3bL, 0x4c98a0beL, 0x3278e964L,
0x9f1f9532L, 0xe0d392dfL, 0xd3a0342bL, 0x8971f21eL,
0x1b0a7441L, 0x4ba3348cL, 0xc5be7120L, 0xc37632d8L,
0xdf359f8dL, 0x9b992f2eL, 0xe60b6f47L, 0x0fe3f11dL,
0xe54cda54L, 0x1edad891L, 0xce6279cfL, 0xcd3e7e6fL,
0x1618b166L, 0xfd2c1d05L, 0x848fd2c5L, 0xf6fb2299L,
0xf523f357L, 0xa6327623L, 0x93a83531L, 0x56cccd02L,
0xacf08162L, 0x5a75ebb5L, 0x6e163697L, 0x88d273ccL,
0xde966292L, 0x81b949d0L, 0x4c50901bL, 0x71c65614L,
0xe6c6c7bdL, 0x327a140aL, 0x45e1d006L, 0xc3f27b9aL,
0xc9aa53fdL, 0x62a80f00L, 0xbb25bfe2L, 0x35bdd2f6L,
0x71126905L, 0xb2040222L, 0xb6cbcf7cL, 0xcd769c2bL,
0x53113ec0L, 0x1640e3d3L, 0x38abbd60L, 0x2547adf0L,
0xba38209cL, 0xf746ce76L, 0x77afa1c5L, 0x20756060L,
0x85cbfe4eL, 0x8ae88dd8L, 0x7aaaf9b0L, 0x4cf9aa7eL,
0x1948c25cL, 0x02fb8a8cL, 0x01c36ae4L, 0xd6ebe1f9L,
0x90d4f869L, 0xa65cdea0L, 0x3f09252dL, 0xc208e69fL,
0xb74e6132L, 0xce77e25bL, 0x578fdfe3L, 0x3ac372e6L,
}
};

118
src/utils/crypto/bf_skey.c Normal file
View File

@@ -0,0 +1,118 @@
/* Deprecated/legacy */
/* crypto/bf/bf_skey.c */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <string.h>
#include "blowfish.h"
#include "bf_locl.h"
#include "bf_pi.h"
void BF_set_key(BF_KEY *key, int len, unsigned char *data)
{
int i;
BF_LONG *p,ri,in[2];
unsigned char *d,*end;
memcpy((char *)key,(char *)&bf_init,sizeof(BF_KEY));
p=key->P;
if (len > ((BF_ROUNDS+2)*4)) len=(BF_ROUNDS+2)*4;
d=data;
end= &(data[len]);
for (i=0; i<(BF_ROUNDS+2); i++)
{
ri= *(d++);
if (d >= end) d=data;
ri<<=8;
ri|= *(d++);
if (d >= end) d=data;
ri<<=8;
ri|= *(d++);
if (d >= end) d=data;
ri<<=8;
ri|= *(d++);
if (d >= end) d=data;
p[i]^=ri;
}
in[0]=0L;
in[1]=0L;
for (i=0; i<(BF_ROUNDS+2); i+=2)
{
BF_encrypt(in,key);
p[i ]=in[0];
p[i+1]=in[1];
}
p=key->S;
for (i=0; i<4*256; i+=2)
{
BF_encrypt(in,key);
p[i ]=in[0];
p[i+1]=in[1];
}
}

120
src/utils/crypto/blowfish.h Normal file
View File

@@ -0,0 +1,120 @@
/* Deprecated/legacy */
/* crypto/bf/blowfish.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#ifndef HEADER_BLOWFISH_H
#define HEADER_BLOWFISH_H
#include <inttypes.h>
#ifdef __cplusplus
extern "C" {
#endif
#define BF_ENCRYPT 1
#define BF_DECRYPT 0
/* If you make this 'unsigned int' the pointer variants will work on
* the Alpha, otherwise they will not. Strangly using the '8 byte'
* BF_LONG and the default 'non-pointer' inner loop is the best configuration
* for the Alpha */
#define BF_LONG uint32_t
#define BF_ROUNDS 16
#define BF_BLOCK 8
typedef struct bf_key_st
{
BF_LONG P[BF_ROUNDS+2];
BF_LONG S[4*256];
} BF_KEY;
#ifndef NOPROTO
void BF_set_key(BF_KEY *key, int len, unsigned char *data);
void BF_ecb_encrypt(unsigned char *in,unsigned char *out,BF_KEY *key, int enc);
void BF_ecb_le_encrypt(unsigned char *in, unsigned char *out, BF_KEY *ks, int encrypt);
void BF_encrypt(BF_LONG *data,BF_KEY *key);
void BF_decrypt(BF_LONG *data,BF_KEY *key);
void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
BF_KEY *ks, unsigned char *iv, int enc);
void BF_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
BF_KEY *schedule, unsigned char *ivec, int *num, int enc);
void BF_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
BF_KEY *schedule, unsigned char *ivec, int *num);
char *BF_options(void);
#else
void BF_set_key();
void BF_ecb_encrypt();
void BF_encrypt();
void BF_decrypt();
void BF_cbc_encrypt();
void BF_cfb64_encrypt();
void BF_ofb64_encrypt();
char *BF_options();
#endif
#ifdef __cplusplus
}
#endif
#endif

80
src/utils/crypto/c_ecb.c Normal file
View File

@@ -0,0 +1,80 @@
/* Deprecated/legacy */
/* crypto/cast/cast_ecb.c */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include "cast.h"
#include "cast_lcl.h"
char *CAST_version="CAST part of SSLeay 0.8.2b 08-Jan-1998";
void CAST_ecb_encrypt(unsigned char *in, unsigned char *out, CAST_KEY *ks, int encrypt)
{
CAST_LONG l,d[2];
n2l(in,l); d[0]=l;
n2l(in,l); d[1]=l;
if (encrypt)
CAST_encrypt(d,ks);
else
CAST_decrypt(d,ks);
l=d[0]; l2n(l,out);
l=d[1]; l2n(l,out);
l=d[0]=d[1]=0;
}

201
src/utils/crypto/c_enc.c Normal file
View File

@@ -0,0 +1,201 @@
/* Deprecated/legacy */
/* crypto/cast/c_enc.c */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include "cast.h"
#include "cast_lcl.h"
void CAST_encrypt(CAST_LONG *data, CAST_KEY *key)
{
register CAST_LONG l,r,*k,t;
k= &(key->data[0]);
l=data[0];
r=data[1];
E_CAST( 0,k,l,r,+,^,-);
E_CAST( 1,k,r,l,^,-,+);
E_CAST( 2,k,l,r,-,+,^);
E_CAST( 3,k,r,l,+,^,-);
E_CAST( 4,k,l,r,^,-,+);
E_CAST( 5,k,r,l,-,+,^);
E_CAST( 6,k,l,r,+,^,-);
E_CAST( 7,k,r,l,^,-,+);
E_CAST( 8,k,l,r,-,+,^);
E_CAST( 9,k,r,l,+,^,-);
E_CAST(10,k,l,r,^,-,+);
E_CAST(11,k,r,l,-,+,^);
E_CAST(12,k,l,r,+,^,-);
E_CAST(13,k,r,l,^,-,+);
E_CAST(14,k,l,r,-,+,^);
E_CAST(15,k,r,l,+,^,-);
data[1]=l&0xffffffffL;
data[0]=r&0xffffffffL;
}
void CAST_decrypt(CAST_LONG *data, CAST_KEY *key)
{
register CAST_LONG l,r,*k,t;
k= &(key->data[0]);
l=data[0];
r=data[1];
E_CAST(15,k,l,r,+,^,-);
E_CAST(14,k,r,l,-,+,^);
E_CAST(13,k,l,r,^,-,+);
E_CAST(12,k,r,l,+,^,-);
E_CAST(11,k,l,r,-,+,^);
E_CAST(10,k,r,l,^,-,+);
E_CAST( 9,k,l,r,+,^,-);
E_CAST( 8,k,r,l,-,+,^);
E_CAST( 7,k,l,r,^,-,+);
E_CAST( 6,k,r,l,+,^,-);
E_CAST( 5,k,l,r,-,+,^);
E_CAST( 4,k,r,l,^,-,+);
E_CAST( 3,k,l,r,+,^,-);
E_CAST( 2,k,r,l,-,+,^);
E_CAST( 1,k,l,r,^,-,+);
E_CAST( 0,k,r,l,+,^,-);
data[1]=l&0xffffffffL;
data[0]=r&0xffffffffL;
}
void CAST_cbc_encrypt(unsigned char *in, unsigned char *out, long length, CAST_KEY *ks, unsigned char *iv, int encrypt)
{
register CAST_LONG tin0,tin1;
register CAST_LONG tout0,tout1,xor0,xor1;
register long l=length;
CAST_LONG tin[2];
if (encrypt)
{
n2l(iv,tout0);
n2l(iv,tout1);
iv-=8;
for (l-=8; l>=0; l-=8)
{
n2l(in,tin0);
n2l(in,tin1);
tin0^=tout0;
tin1^=tout1;
tin[0]=tin0;
tin[1]=tin1;
CAST_encrypt(tin,ks);
tout0=tin[0];
tout1=tin[1];
l2n(tout0,out);
l2n(tout1,out);
}
if (l != -8)
{
n2ln(in,tin0,tin1,l+8);
tin0^=tout0;
tin1^=tout1;
tin[0]=tin0;
tin[1]=tin1;
CAST_encrypt(tin,ks);
tout0=tin[0];
tout1=tin[1];
l2n(tout0,out);
l2n(tout1,out);
}
l2n(tout0,iv);
l2n(tout1,iv);
}
else
{
n2l(iv,xor0);
n2l(iv,xor1);
iv-=8;
for (l-=8; l>=0; l-=8)
{
n2l(in,tin0);
n2l(in,tin1);
tin[0]=tin0;
tin[1]=tin1;
CAST_decrypt(tin,ks);
tout0=tin[0]^xor0;
tout1=tin[1]^xor1;
l2n(tout0,out);
l2n(tout1,out);
xor0=tin0;
xor1=tin1;
}
if (l != -8)
{
n2l(in,tin0);
n2l(in,tin1);
tin[0]=tin0;
tin[1]=tin1;
CAST_decrypt(tin,ks);
tout0=tin[0]^xor0;
tout1=tin[1]^xor1;
l2nn(tout0,tout1,out,l+8);
xor0=tin0;
xor1=tin1;
}
l2n(xor0,iv);
l2n(xor1,iv);
}
tin0=tin1=tout0=tout1=xor0=xor1=0;
tin[0]=tin[1]=0;
}

164
src/utils/crypto/c_skey.c Normal file
View File

@@ -0,0 +1,164 @@
/* Deprecated/legacy */
/* crypto/cast/c_skey.c */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include "cast.h"
#include "cast_lcl.h"
#include "cast_s.h"
#define CAST_exp(l,A,a,n) \
A[n/4]=l; \
a[n+3]=(l )&0xff; \
a[n+2]=(l>> 8)&0xff; \
a[n+1]=(l>>16)&0xff; \
a[n+0]=(l>>24);
#define S4 CAST_S_table4
#define S5 CAST_S_table5
#define S6 CAST_S_table6
#define S7 CAST_S_table7
void CAST_set_key(CAST_KEY *key, int len, unsigned char *data)
{
CAST_LONG x[16];
CAST_LONG z[16];
CAST_LONG k[32];
CAST_LONG X[4],Z[4];
CAST_LONG l,*K;
int i;
for (i=0; i<16; i++) x[i]=0;
if (len > 16) len=16;
for (i=0; i<len; i++)
x[i]=data[i];
K= &k[0];
X[0]=(x[ 0]<<24)|(x[ 1]<<16)|(x[ 2]<<8)|x[ 3];
X[1]=(x[ 4]<<24)|(x[ 5]<<16)|(x[ 6]<<8)|x[ 7];
X[2]=(x[ 8]<<24)|(x[ 9]<<16)|(x[10]<<8)|x[11];
X[3]=(x[12]<<24)|(x[13]<<16)|(x[14]<<8)|x[15];
for (;;)
{
l=X[0]^S4[x[13]]^S5[x[15]]^S6[x[12]]^S7[x[14]]^S6[x[ 8]];
CAST_exp(l,Z,z, 0);
l=X[2]^S4[z[ 0]]^S5[z[ 2]]^S6[z[ 1]]^S7[z[ 3]]^S7[x[10]];
CAST_exp(l,Z,z, 4);
l=X[3]^S4[z[ 7]]^S5[z[ 6]]^S6[z[ 5]]^S7[z[ 4]]^S4[x[ 9]];
CAST_exp(l,Z,z, 8);
l=X[1]^S4[z[10]]^S5[z[ 9]]^S6[z[11]]^S7[z[ 8]]^S5[x[11]];
CAST_exp(l,Z,z,12);
K[ 0]= S4[z[ 8]]^S5[z[ 9]]^S6[z[ 7]]^S7[z[ 6]]^S4[z[ 2]];
K[ 1]= S4[z[10]]^S5[z[11]]^S6[z[ 5]]^S7[z[ 4]]^S5[z[ 6]];
K[ 2]= S4[z[12]]^S5[z[13]]^S6[z[ 3]]^S7[z[ 2]]^S6[z[ 9]];
K[ 3]= S4[z[14]]^S5[z[15]]^S6[z[ 1]]^S7[z[ 0]]^S7[z[12]];
l=Z[2]^S4[z[ 5]]^S5[z[ 7]]^S6[z[ 4]]^S7[z[ 6]]^S6[z[ 0]];
CAST_exp(l,X,x, 0);
l=Z[0]^S4[x[ 0]]^S5[x[ 2]]^S6[x[ 1]]^S7[x[ 3]]^S7[z[ 2]];
CAST_exp(l,X,x, 4);
l=Z[1]^S4[x[ 7]]^S5[x[ 6]]^S6[x[ 5]]^S7[x[ 4]]^S4[z[ 1]];
CAST_exp(l,X,x, 8);
l=Z[3]^S4[x[10]]^S5[x[ 9]]^S6[x[11]]^S7[x[ 8]]^S5[z[ 3]];
CAST_exp(l,X,x,12);
K[ 4]= S4[x[ 3]]^S5[x[ 2]]^S6[x[12]]^S7[x[13]]^S4[x[ 8]];
K[ 5]= S4[x[ 1]]^S5[x[ 0]]^S6[x[14]]^S7[x[15]]^S5[x[13]];
K[ 6]= S4[x[ 7]]^S5[x[ 6]]^S6[x[ 8]]^S7[x[ 9]]^S6[x[ 3]];
K[ 7]= S4[x[ 5]]^S5[x[ 4]]^S6[x[10]]^S7[x[11]]^S7[x[ 7]];
l=X[0]^S4[x[13]]^S5[x[15]]^S6[x[12]]^S7[x[14]]^S6[x[ 8]];
CAST_exp(l,Z,z, 0);
l=X[2]^S4[z[ 0]]^S5[z[ 2]]^S6[z[ 1]]^S7[z[ 3]]^S7[x[10]];
CAST_exp(l,Z,z, 4);
l=X[3]^S4[z[ 7]]^S5[z[ 6]]^S6[z[ 5]]^S7[z[ 4]]^S4[x[ 9]];
CAST_exp(l,Z,z, 8);
l=X[1]^S4[z[10]]^S5[z[ 9]]^S6[z[11]]^S7[z[ 8]]^S5[x[11]];
CAST_exp(l,Z,z,12);
K[ 8]= S4[z[ 3]]^S5[z[ 2]]^S6[z[12]]^S7[z[13]]^S4[z[ 9]];
K[ 9]= S4[z[ 1]]^S5[z[ 0]]^S6[z[14]]^S7[z[15]]^S5[z[12]];
K[10]= S4[z[ 7]]^S5[z[ 6]]^S6[z[ 8]]^S7[z[ 9]]^S6[z[ 2]];
K[11]= S4[z[ 5]]^S5[z[ 4]]^S6[z[10]]^S7[z[11]]^S7[z[ 6]];
l=Z[2]^S4[z[ 5]]^S5[z[ 7]]^S6[z[ 4]]^S7[z[ 6]]^S6[z[ 0]];
CAST_exp(l,X,x, 0);
l=Z[0]^S4[x[ 0]]^S5[x[ 2]]^S6[x[ 1]]^S7[x[ 3]]^S7[z[ 2]];
CAST_exp(l,X,x, 4);
l=Z[1]^S4[x[ 7]]^S5[x[ 6]]^S6[x[ 5]]^S7[x[ 4]]^S4[z[ 1]];
CAST_exp(l,X,x, 8);
l=Z[3]^S4[x[10]]^S5[x[ 9]]^S6[x[11]]^S7[x[ 8]]^S5[z[ 3]];
CAST_exp(l,X,x,12);
K[12]= S4[x[ 8]]^S5[x[ 9]]^S6[x[ 7]]^S7[x[ 6]]^S4[x[ 3]];
K[13]= S4[x[10]]^S5[x[11]]^S6[x[ 5]]^S7[x[ 4]]^S5[x[ 7]];
K[14]= S4[x[12]]^S5[x[13]]^S6[x[ 3]]^S7[x[ 2]]^S6[x[ 8]];
K[15]= S4[x[14]]^S5[x[15]]^S6[x[ 1]]^S7[x[ 0]]^S7[x[13]];
if (K != k) break;
K+=16;
}
for (i=0; i<16; i++)
{
key->data[i*2]=k[i];
key->data[i*2+1]=((k[i+16])+16)&0x1f;
}
}

113
src/utils/crypto/cast.h Normal file
View File

@@ -0,0 +1,113 @@
/* Deprecated/legacy */
/* crypto/cast/cast.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#ifndef HEADER_CAST_H
#define HEADER_CAST_H
#include <inttypes.h>
#ifdef __cplusplus
extern "C" {
#endif
#define CAST_ENCRYPT 1
#define CAST_DECRYPT 0
#define CAST_LONG uint32_t
#define CAST_BLOCK 8
#define CAST_KEY_LENGTH 16
typedef struct cast_key_st
{
CAST_LONG data[32];
} CAST_KEY;
#ifndef NOPROTO
void CAST_set_key(CAST_KEY *key, int len, unsigned char *data);
void CAST_ecb_encrypt(unsigned char *in,unsigned char *out,CAST_KEY *key,
int enc);
void CAST_encrypt(CAST_LONG *data,CAST_KEY *key);
void CAST_decrypt(CAST_LONG *data,CAST_KEY *key);
void CAST_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
CAST_KEY *ks, unsigned char *iv, int enc);
void CAST_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
CAST_KEY *schedule, unsigned char *ivec, int *num, int enc);
void CAST_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
CAST_KEY *schedule, unsigned char *ivec, int *num);
#else
void CAST_set_key();
void CAST_ecb_encrypt();
void CAST_encrypt();
void CAST_decrypt();
void CAST_cbc_encrypt();
void CAST_cfb64_encrypt();
void CAST_ofb64_encrypt();
#endif
#ifdef __cplusplus
}
#endif
#endif

225
src/utils/crypto/cast_lcl.h Normal file
View File

@@ -0,0 +1,225 @@
/* Deprecated/legacy */
/* crypto/rc2/rc2_locl.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#ifdef WIN32
#include <stdlib.h>
#endif
#undef c2l
#define c2l(c,l) (l =((uint32_t)(*((c)++))) , \
l|=((uint32_t)(*((c)++)))<< 8L, \
l|=((uint32_t)(*((c)++)))<<16L, \
l|=((uint32_t)(*((c)++)))<<24L)
/* NOTE - c is not incremented as per c2l */
#undef c2ln
#define c2ln(c,l1,l2,n) { \
c+=n; \
l1=l2=0; \
switch (n) { \
case 8: l2 =((uint32_t)(*(--(c))))<<24L; \
case 7: l2|=((uint32_t)(*(--(c))))<<16L; \
case 6: l2|=((uint32_t)(*(--(c))))<< 8L; \
case 5: l2|=((uint32_t)(*(--(c)))); \
case 4: l1 =((uint32_t)(*(--(c))))<<24L; \
case 3: l1|=((uint32_t)(*(--(c))))<<16L; \
case 2: l1|=((uint32_t)(*(--(c))))<< 8L; \
case 1: l1|=((uint32_t)(*(--(c)))); \
} \
}
#undef l2c
#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
*((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
*((c)++)=(unsigned char)(((l)>>16L)&0xff), \
*((c)++)=(unsigned char)(((l)>>24L)&0xff))
/* NOTE - c is not incremented as per l2c */
#undef l2cn
#define l2cn(l1,l2,c,n) { \
c+=n; \
switch (n) { \
case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
} \
}
/* NOTE - c is not incremented as per n2l */
#define n2ln(c,l1,l2,n) { \
c+=n; \
l1=l2=0; \
switch (n) { \
case 8: l2 =((uint32_t)(*(--(c)))) ; \
case 7: l2|=((uint32_t)(*(--(c))))<< 8; \
case 6: l2|=((uint32_t)(*(--(c))))<<16; \
case 5: l2|=((uint32_t)(*(--(c))))<<24; \
case 4: l1 =((uint32_t)(*(--(c)))) ; \
case 3: l1|=((uint32_t)(*(--(c))))<< 8; \
case 2: l1|=((uint32_t)(*(--(c))))<<16; \
case 1: l1|=((uint32_t)(*(--(c))))<<24; \
} \
}
/* NOTE - c is not incremented as per l2n */
#define l2nn(l1,l2,c,n) { \
c+=n; \
switch (n) { \
case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \
case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \
case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
} \
}
#undef n2l
#define n2l(c,l) (l =((uint32_t)(*((c)++)))<<24L, \
l|=((uint32_t)(*((c)++)))<<16L, \
l|=((uint32_t)(*((c)++)))<< 8L, \
l|=((uint32_t)(*((c)++))))
#undef l2n
#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
*((c)++)=(unsigned char)(((l)>>16L)&0xff), \
*((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
*((c)++)=(unsigned char)(((l) )&0xff))
//#if defined(WIN32)
//#define ROTL(a,n) (_lrotl(a,n))
//#else
#define ROTL(a,n) (((a)<<(n))|((a)>>(32-(n))))
//#endif
#define C_M 0x3fc
#define C_0 22L
#define C_1 14L
#define C_2 6L
#define C_3 2L /* left shift */
/* The rotate has an extra 16 added to it to help the x86 asm */
#if defined(CAST_PTR)
#define E_CAST(n,key,L,R,OP1,OP2,OP3) \
{ \
int i; \
t=key[n*2] OP1 R; \
i=key[n*2+1]; \
t=ROTL(t,i); \
L^= ((( *(CAST_LONG *)((unsigned char *) \
CAST_S_table0+((t>>C_2)&C_M)) OP2 \
*(CAST_LONG *)((unsigned char *) \
CAST_S_table1+((t<<C_3)&C_M))) OP3 \
*(CAST_LONG *)((unsigned char *) \
CAST_S_table2+((t>>C_0)&C_M))) OP1 \
*(CAST_LONG *)((unsigned char *) \
CAST_S_table3+((t>>C_1)&C_M))); \
}
#elif defined(CAST_PTR2)
#define E_CAST(n,key,L,R,OP1,OP2,OP3) \
{ \
int i; \
CAST_LONG u,v,w; \
w=key[n*2] OP1 R; \
i=key[n*2+1]; \
w=ROTL(w,i); \
u=w>>C_2; \
v=w<<C_3; \
u&=C_M; \
v&=C_M; \
t= *(CAST_LONG *)((unsigned char *)CAST_S_table0+u); \
u=w>>C_0; \
t=t OP2 *(CAST_LONG *)((unsigned char *)CAST_S_table1+v); \
v=w>>C_1; \
u&=C_M; \
v&=C_M; \
t=t OP3 *(CAST_LONG *)((unsigned char *)CAST_S_table2+u); \
t=t OP1 *(CAST_LONG *)((unsigned char *)CAST_S_table3+v); \
L^=t; \
}
#else
#define E_CAST(n,key,L,R,OP1,OP2,OP3) \
{ \
CAST_LONG a,b,c,d; \
t=key[n*2] OP1 R; \
t=ROTL(t,(key[n*2+1])); \
a=CAST_S_table0[(t>> 8)&0xff]; \
b=CAST_S_table1[(t )&0xff]; \
c=CAST_S_table2[(t>>24)&0xff]; \
d=CAST_S_table3[(t>>16)&0xff]; \
L^=(((a OP2 b) OP3 c) OP1 d); \
}
#endif
extern CAST_LONG CAST_S_table0[256];
extern CAST_LONG CAST_S_table1[256];
extern CAST_LONG CAST_S_table2[256];
extern CAST_LONG CAST_S_table3[256];
extern CAST_LONG CAST_S_table4[256];
extern CAST_LONG CAST_S_table5[256];
extern CAST_LONG CAST_S_table6[256];
extern CAST_LONG CAST_S_table7[256];

530
src/utils/crypto/cast_s.h Normal file
View File

@@ -0,0 +1,530 @@
/* Deprecated/legacy */
CAST_LONG CAST_S_table0[256]={
0x30fb40d4,0x9fa0ff0b,0x6beccd2f,0x3f258c7a,
0x1e213f2f,0x9c004dd3,0x6003e540,0xcf9fc949,
0xbfd4af27,0x88bbbdb5,0xe2034090,0x98d09675,
0x6e63a0e0,0x15c361d2,0xc2e7661d,0x22d4ff8e,
0x28683b6f,0xc07fd059,0xff2379c8,0x775f50e2,
0x43c340d3,0xdf2f8656,0x887ca41a,0xa2d2bd2d,
0xa1c9e0d6,0x346c4819,0x61b76d87,0x22540f2f,
0x2abe32e1,0xaa54166b,0x22568e3a,0xa2d341d0,
0x66db40c8,0xa784392f,0x004dff2f,0x2db9d2de,
0x97943fac,0x4a97c1d8,0x527644b7,0xb5f437a7,
0xb82cbaef,0xd751d159,0x6ff7f0ed,0x5a097a1f,
0x827b68d0,0x90ecf52e,0x22b0c054,0xbc8e5935,
0x4b6d2f7f,0x50bb64a2,0xd2664910,0xbee5812d,
0xb7332290,0xe93b159f,0xb48ee411,0x4bff345d,
0xfd45c240,0xad31973f,0xc4f6d02e,0x55fc8165,
0xd5b1caad,0xa1ac2dae,0xa2d4b76d,0xc19b0c50,
0x882240f2,0x0c6e4f38,0xa4e4bfd7,0x4f5ba272,
0x564c1d2f,0xc59c5319,0xb949e354,0xb04669fe,
0xb1b6ab8a,0xc71358dd,0x6385c545,0x110f935d,
0x57538ad5,0x6a390493,0xe63d37e0,0x2a54f6b3,
0x3a787d5f,0x6276a0b5,0x19a6fcdf,0x7a42206a,
0x29f9d4d5,0xf61b1891,0xbb72275e,0xaa508167,
0x38901091,0xc6b505eb,0x84c7cb8c,0x2ad75a0f,
0x874a1427,0xa2d1936b,0x2ad286af,0xaa56d291,
0xd7894360,0x425c750d,0x93b39e26,0x187184c9,
0x6c00b32d,0x73e2bb14,0xa0bebc3c,0x54623779,
0x64459eab,0x3f328b82,0x7718cf82,0x59a2cea6,
0x04ee002e,0x89fe78e6,0x3fab0950,0x325ff6c2,
0x81383f05,0x6963c5c8,0x76cb5ad6,0xd49974c9,
0xca180dcf,0x380782d5,0xc7fa5cf6,0x8ac31511,
0x35e79e13,0x47da91d0,0xf40f9086,0xa7e2419e,
0x31366241,0x051ef495,0xaa573b04,0x4a805d8d,
0x548300d0,0x00322a3c,0xbf64cddf,0xba57a68e,
0x75c6372b,0x50afd341,0xa7c13275,0x915a0bf5,
0x6b54bfab,0x2b0b1426,0xab4cc9d7,0x449ccd82,
0xf7fbf265,0xab85c5f3,0x1b55db94,0xaad4e324,
0xcfa4bd3f,0x2deaa3e2,0x9e204d02,0xc8bd25ac,
0xeadf55b3,0xd5bd9e98,0xe31231b2,0x2ad5ad6c,
0x954329de,0xadbe4528,0xd8710f69,0xaa51c90f,
0xaa786bf6,0x22513f1e,0xaa51a79b,0x2ad344cc,
0x7b5a41f0,0xd37cfbad,0x1b069505,0x41ece491,
0xb4c332e6,0x032268d4,0xc9600acc,0xce387e6d,
0xbf6bb16c,0x6a70fb78,0x0d03d9c9,0xd4df39de,
0xe01063da,0x4736f464,0x5ad328d8,0xb347cc96,
0x75bb0fc3,0x98511bfb,0x4ffbcc35,0xb58bcf6a,
0xe11f0abc,0xbfc5fe4a,0xa70aec10,0xac39570a,
0x3f04442f,0x6188b153,0xe0397a2e,0x5727cb79,
0x9ceb418f,0x1cacd68d,0x2ad37c96,0x0175cb9d,
0xc69dff09,0xc75b65f0,0xd9db40d8,0xec0e7779,
0x4744ead4,0xb11c3274,0xdd24cb9e,0x7e1c54bd,
0xf01144f9,0xd2240eb1,0x9675b3fd,0xa3ac3755,
0xd47c27af,0x51c85f4d,0x56907596,0xa5bb15e6,
0x580304f0,0xca042cf1,0x011a37ea,0x8dbfaadb,
0x35ba3e4a,0x3526ffa0,0xc37b4d09,0xbc306ed9,
0x98a52666,0x5648f725,0xff5e569d,0x0ced63d0,
0x7c63b2cf,0x700b45e1,0xd5ea50f1,0x85a92872,
0xaf1fbda7,0xd4234870,0xa7870bf3,0x2d3b4d79,
0x42e04198,0x0cd0ede7,0x26470db8,0xf881814c,
0x474d6ad7,0x7c0c5e5c,0xd1231959,0x381b7298,
0xf5d2f4db,0xab838653,0x6e2f1e23,0x83719c9e,
0xbd91e046,0x9a56456e,0xdc39200c,0x20c8c571,
0x962bda1c,0xe1e696ff,0xb141ab08,0x7cca89b9,
0x1a69e783,0x02cc4843,0xa2f7c579,0x429ef47d,
0x427b169c,0x5ac9f049,0xdd8f0f00,0x5c8165bf,
};
CAST_LONG CAST_S_table1[256]={
0x1f201094,0xef0ba75b,0x69e3cf7e,0x393f4380,
0xfe61cf7a,0xeec5207a,0x55889c94,0x72fc0651,
0xada7ef79,0x4e1d7235,0xd55a63ce,0xde0436ba,
0x99c430ef,0x5f0c0794,0x18dcdb7d,0xa1d6eff3,
0xa0b52f7b,0x59e83605,0xee15b094,0xe9ffd909,
0xdc440086,0xef944459,0xba83ccb3,0xe0c3cdfb,
0xd1da4181,0x3b092ab1,0xf997f1c1,0xa5e6cf7b,
0x01420ddb,0xe4e7ef5b,0x25a1ff41,0xe180f806,
0x1fc41080,0x179bee7a,0xd37ac6a9,0xfe5830a4,
0x98de8b7f,0x77e83f4e,0x79929269,0x24fa9f7b,
0xe113c85b,0xacc40083,0xd7503525,0xf7ea615f,
0x62143154,0x0d554b63,0x5d681121,0xc866c359,
0x3d63cf73,0xcee234c0,0xd4d87e87,0x5c672b21,
0x071f6181,0x39f7627f,0x361e3084,0xe4eb573b,
0x602f64a4,0xd63acd9c,0x1bbc4635,0x9e81032d,
0x2701f50c,0x99847ab4,0xa0e3df79,0xba6cf38c,
0x10843094,0x2537a95e,0xf46f6ffe,0xa1ff3b1f,
0x208cfb6a,0x8f458c74,0xd9e0a227,0x4ec73a34,
0xfc884f69,0x3e4de8df,0xef0e0088,0x3559648d,
0x8a45388c,0x1d804366,0x721d9bfd,0xa58684bb,
0xe8256333,0x844e8212,0x128d8098,0xfed33fb4,
0xce280ae1,0x27e19ba5,0xd5a6c252,0xe49754bd,
0xc5d655dd,0xeb667064,0x77840b4d,0xa1b6a801,
0x84db26a9,0xe0b56714,0x21f043b7,0xe5d05860,
0x54f03084,0x066ff472,0xa31aa153,0xdadc4755,
0xb5625dbf,0x68561be6,0x83ca6b94,0x2d6ed23b,
0xeccf01db,0xa6d3d0ba,0xb6803d5c,0xaf77a709,
0x33b4a34c,0x397bc8d6,0x5ee22b95,0x5f0e5304,
0x81ed6f61,0x20e74364,0xb45e1378,0xde18639b,
0x881ca122,0xb96726d1,0x8049a7e8,0x22b7da7b,
0x5e552d25,0x5272d237,0x79d2951c,0xc60d894c,
0x488cb402,0x1ba4fe5b,0xa4b09f6b,0x1ca815cf,
0xa20c3005,0x8871df63,0xb9de2fcb,0x0cc6c9e9,
0x0beeff53,0xe3214517,0xb4542835,0x9f63293c,
0xee41e729,0x6e1d2d7c,0x50045286,0x1e6685f3,
0xf33401c6,0x30a22c95,0x31a70850,0x60930f13,
0x73f98417,0xa1269859,0xec645c44,0x52c877a9,
0xcdff33a6,0xa02b1741,0x7cbad9a2,0x2180036f,
0x50d99c08,0xcb3f4861,0xc26bd765,0x64a3f6ab,
0x80342676,0x25a75e7b,0xe4e6d1fc,0x20c710e6,
0xcdf0b680,0x17844d3b,0x31eef84d,0x7e0824e4,
0x2ccb49eb,0x846a3bae,0x8ff77888,0xee5d60f6,
0x7af75673,0x2fdd5cdb,0xa11631c1,0x30f66f43,
0xb3faec54,0x157fd7fa,0xef8579cc,0xd152de58,
0xdb2ffd5e,0x8f32ce19,0x306af97a,0x02f03ef8,
0x99319ad5,0xc242fa0f,0xa7e3ebb0,0xc68e4906,
0xb8da230c,0x80823028,0xdcdef3c8,0xd35fb171,
0x088a1bc8,0xbec0c560,0x61a3c9e8,0xbca8f54d,
0xc72feffa,0x22822e99,0x82c570b4,0xd8d94e89,
0x8b1c34bc,0x301e16e6,0x273be979,0xb0ffeaa6,
0x61d9b8c6,0x00b24869,0xb7ffce3f,0x08dc283b,
0x43daf65a,0xf7e19798,0x7619b72f,0x8f1c9ba4,
0xdc8637a0,0x16a7d3b1,0x9fc393b7,0xa7136eeb,
0xc6bcc63e,0x1a513742,0xef6828bc,0x520365d6,
0x2d6a77ab,0x3527ed4b,0x821fd216,0x095c6e2e,
0xdb92f2fb,0x5eea29cb,0x145892f5,0x91584f7f,
0x5483697b,0x2667a8cc,0x85196048,0x8c4bacea,
0x833860d4,0x0d23e0f9,0x6c387e8a,0x0ae6d249,
0xb284600c,0xd835731d,0xdcb1c647,0xac4c56ea,
0x3ebd81b3,0x230eabb0,0x6438bc87,0xf0b5b1fa,
0x8f5ea2b3,0xfc184642,0x0a036b7a,0x4fb089bd,
0x649da589,0xa345415e,0x5c038323,0x3e5d3bb9,
0x43d79572,0x7e6dd07c,0x06dfdf1e,0x6c6cc4ef,
0x7160a539,0x73bfbe70,0x83877605,0x4523ecf1,
};
CAST_LONG CAST_S_table2[256]={
0x8defc240,0x25fa5d9f,0xeb903dbf,0xe810c907,
0x47607fff,0x369fe44b,0x8c1fc644,0xaececa90,
0xbeb1f9bf,0xeefbcaea,0xe8cf1950,0x51df07ae,
0x920e8806,0xf0ad0548,0xe13c8d83,0x927010d5,
0x11107d9f,0x07647db9,0xb2e3e4d4,0x3d4f285e,
0xb9afa820,0xfade82e0,0xa067268b,0x8272792e,
0x553fb2c0,0x489ae22b,0xd4ef9794,0x125e3fbc,
0x21fffcee,0x825b1bfd,0x9255c5ed,0x1257a240,
0x4e1a8302,0xbae07fff,0x528246e7,0x8e57140e,
0x3373f7bf,0x8c9f8188,0xa6fc4ee8,0xc982b5a5,
0xa8c01db7,0x579fc264,0x67094f31,0xf2bd3f5f,
0x40fff7c1,0x1fb78dfc,0x8e6bd2c1,0x437be59b,
0x99b03dbf,0xb5dbc64b,0x638dc0e6,0x55819d99,
0xa197c81c,0x4a012d6e,0xc5884a28,0xccc36f71,
0xb843c213,0x6c0743f1,0x8309893c,0x0feddd5f,
0x2f7fe850,0xd7c07f7e,0x02507fbf,0x5afb9a04,
0xa747d2d0,0x1651192e,0xaf70bf3e,0x58c31380,
0x5f98302e,0x727cc3c4,0x0a0fb402,0x0f7fef82,
0x8c96fdad,0x5d2c2aae,0x8ee99a49,0x50da88b8,
0x8427f4a0,0x1eac5790,0x796fb449,0x8252dc15,
0xefbd7d9b,0xa672597d,0xada840d8,0x45f54504,
0xfa5d7403,0xe83ec305,0x4f91751a,0x925669c2,
0x23efe941,0xa903f12e,0x60270df2,0x0276e4b6,
0x94fd6574,0x927985b2,0x8276dbcb,0x02778176,
0xf8af918d,0x4e48f79e,0x8f616ddf,0xe29d840e,
0x842f7d83,0x340ce5c8,0x96bbb682,0x93b4b148,
0xef303cab,0x984faf28,0x779faf9b,0x92dc560d,
0x224d1e20,0x8437aa88,0x7d29dc96,0x2756d3dc,
0x8b907cee,0xb51fd240,0xe7c07ce3,0xe566b4a1,
0xc3e9615e,0x3cf8209d,0x6094d1e3,0xcd9ca341,
0x5c76460e,0x00ea983b,0xd4d67881,0xfd47572c,
0xf76cedd9,0xbda8229c,0x127dadaa,0x438a074e,
0x1f97c090,0x081bdb8a,0x93a07ebe,0xb938ca15,
0x97b03cff,0x3dc2c0f8,0x8d1ab2ec,0x64380e51,
0x68cc7bfb,0xd90f2788,0x12490181,0x5de5ffd4,
0xdd7ef86a,0x76a2e214,0xb9a40368,0x925d958f,
0x4b39fffa,0xba39aee9,0xa4ffd30b,0xfaf7933b,
0x6d498623,0x193cbcfa,0x27627545,0x825cf47a,
0x61bd8ba0,0xd11e42d1,0xcead04f4,0x127ea392,
0x10428db7,0x8272a972,0x9270c4a8,0x127de50b,
0x285ba1c8,0x3c62f44f,0x35c0eaa5,0xe805d231,
0x428929fb,0xb4fcdf82,0x4fb66a53,0x0e7dc15b,
0x1f081fab,0x108618ae,0xfcfd086d,0xf9ff2889,
0x694bcc11,0x236a5cae,0x12deca4d,0x2c3f8cc5,
0xd2d02dfe,0xf8ef5896,0xe4cf52da,0x95155b67,
0x494a488c,0xb9b6a80c,0x5c8f82bc,0x89d36b45,
0x3a609437,0xec00c9a9,0x44715253,0x0a874b49,
0xd773bc40,0x7c34671c,0x02717ef6,0x4feb5536,
0xa2d02fff,0xd2bf60c4,0xd43f03c0,0x50b4ef6d,
0x07478cd1,0x006e1888,0xa2e53f55,0xb9e6d4bc,
0xa2048016,0x97573833,0xd7207d67,0xde0f8f3d,
0x72f87b33,0xabcc4f33,0x7688c55d,0x7b00a6b0,
0x947b0001,0x570075d2,0xf9bb88f8,0x8942019e,
0x4264a5ff,0x856302e0,0x72dbd92b,0xee971b69,
0x6ea22fde,0x5f08ae2b,0xaf7a616d,0xe5c98767,
0xcf1febd2,0x61efc8c2,0xf1ac2571,0xcc8239c2,
0x67214cb8,0xb1e583d1,0xb7dc3e62,0x7f10bdce,
0xf90a5c38,0x0ff0443d,0x606e6dc6,0x60543a49,
0x5727c148,0x2be98a1d,0x8ab41738,0x20e1be24,
0xaf96da0f,0x68458425,0x99833be5,0x600d457d,
0x282f9350,0x8334b362,0xd91d1120,0x2b6d8da0,
0x642b1e31,0x9c305a00,0x52bce688,0x1b03588a,
0xf7baefd5,0x4142ed9c,0xa4315c11,0x83323ec5,
0xdfef4636,0xa133c501,0xe9d3531c,0xee353783,
};
CAST_LONG CAST_S_table3[256]={
0x9db30420,0x1fb6e9de,0xa7be7bef,0xd273a298,
0x4a4f7bdb,0x64ad8c57,0x85510443,0xfa020ed1,
0x7e287aff,0xe60fb663,0x095f35a1,0x79ebf120,
0xfd059d43,0x6497b7b1,0xf3641f63,0x241e4adf,
0x28147f5f,0x4fa2b8cd,0xc9430040,0x0cc32220,
0xfdd30b30,0xc0a5374f,0x1d2d00d9,0x24147b15,
0xee4d111a,0x0fca5167,0x71ff904c,0x2d195ffe,
0x1a05645f,0x0c13fefe,0x081b08ca,0x05170121,
0x80530100,0xe83e5efe,0xac9af4f8,0x7fe72701,
0xd2b8ee5f,0x06df4261,0xbb9e9b8a,0x7293ea25,
0xce84ffdf,0xf5718801,0x3dd64b04,0xa26f263b,
0x7ed48400,0x547eebe6,0x446d4ca0,0x6cf3d6f5,
0x2649abdf,0xaea0c7f5,0x36338cc1,0x503f7e93,
0xd3772061,0x11b638e1,0x72500e03,0xf80eb2bb,
0xabe0502e,0xec8d77de,0x57971e81,0xe14f6746,
0xc9335400,0x6920318f,0x081dbb99,0xffc304a5,
0x4d351805,0x7f3d5ce3,0xa6c866c6,0x5d5bcca9,
0xdaec6fea,0x9f926f91,0x9f46222f,0x3991467d,
0xa5bf6d8e,0x1143c44f,0x43958302,0xd0214eeb,
0x022083b8,0x3fb6180c,0x18f8931e,0x281658e6,
0x26486e3e,0x8bd78a70,0x7477e4c1,0xb506e07c,
0xf32d0a25,0x79098b02,0xe4eabb81,0x28123b23,
0x69dead38,0x1574ca16,0xdf871b62,0x211c40b7,
0xa51a9ef9,0x0014377b,0x041e8ac8,0x09114003,
0xbd59e4d2,0xe3d156d5,0x4fe876d5,0x2f91a340,
0x557be8de,0x00eae4a7,0x0ce5c2ec,0x4db4bba6,
0xe756bdff,0xdd3369ac,0xec17b035,0x06572327,
0x99afc8b0,0x56c8c391,0x6b65811c,0x5e146119,
0x6e85cb75,0xbe07c002,0xc2325577,0x893ff4ec,
0x5bbfc92d,0xd0ec3b25,0xb7801ab7,0x8d6d3b24,
0x20c763ef,0xc366a5fc,0x9c382880,0x0ace3205,
0xaac9548a,0xeca1d7c7,0x041afa32,0x1d16625a,
0x6701902c,0x9b757a54,0x31d477f7,0x9126b031,
0x36cc6fdb,0xc70b8b46,0xd9e66a48,0x56e55a79,
0x026a4ceb,0x52437eff,0x2f8f76b4,0x0df980a5,
0x8674cde3,0xedda04eb,0x17a9be04,0x2c18f4df,
0xb7747f9d,0xab2af7b4,0xefc34d20,0x2e096b7c,
0x1741a254,0xe5b6a035,0x213d42f6,0x2c1c7c26,
0x61c2f50f,0x6552daf9,0xd2c231f8,0x25130f69,
0xd8167fa2,0x0418f2c8,0x001a96a6,0x0d1526ab,
0x63315c21,0x5e0a72ec,0x49bafefd,0x187908d9,
0x8d0dbd86,0x311170a7,0x3e9b640c,0xcc3e10d7,
0xd5cad3b6,0x0caec388,0xf73001e1,0x6c728aff,
0x71eae2a1,0x1f9af36e,0xcfcbd12f,0xc1de8417,
0xac07be6b,0xcb44a1d8,0x8b9b0f56,0x013988c3,
0xb1c52fca,0xb4be31cd,0xd8782806,0x12a3a4e2,
0x6f7de532,0x58fd7eb6,0xd01ee900,0x24adffc2,
0xf4990fc5,0x9711aac5,0x001d7b95,0x82e5e7d2,
0x109873f6,0x00613096,0xc32d9521,0xada121ff,
0x29908415,0x7fbb977f,0xaf9eb3db,0x29c9ed2a,
0x5ce2a465,0xa730f32c,0xd0aa3fe8,0x8a5cc091,
0xd49e2ce7,0x0ce454a9,0xd60acd86,0x015f1919,
0x77079103,0xdea03af6,0x78a8565e,0xdee356df,
0x21f05cbe,0x8b75e387,0xb3c50651,0xb8a5c3ef,
0xd8eeb6d2,0xe523be77,0xc2154529,0x2f69efdf,
0xafe67afb,0xf470c4b2,0xf3e0eb5b,0xd6cc9876,
0x39e4460c,0x1fda8538,0x1987832f,0xca007367,
0xa99144f8,0x296b299e,0x492fc295,0x9266beab,
0xb5676e69,0x9bd3ddda,0xdf7e052f,0xdb25701c,
0x1b5e51ee,0xf65324e6,0x6afce36c,0x0316cc04,
0x8644213e,0xb7dc59d0,0x7965291f,0xccd6fd43,
0x41823979,0x932bcdf6,0xb657c34d,0x4edfd282,
0x7ae5290c,0x3cb9536b,0x851e20fe,0x9833557e,
0x13ecf0b0,0xd3ffb372,0x3f85c5c1,0x0aef7ed2,
};
CAST_LONG CAST_S_table4[256]={
0x7ec90c04,0x2c6e74b9,0x9b0e66df,0xa6337911,
0xb86a7fff,0x1dd358f5,0x44dd9d44,0x1731167f,
0x08fbf1fa,0xe7f511cc,0xd2051b00,0x735aba00,
0x2ab722d8,0x386381cb,0xacf6243a,0x69befd7a,
0xe6a2e77f,0xf0c720cd,0xc4494816,0xccf5c180,
0x38851640,0x15b0a848,0xe68b18cb,0x4caadeff,
0x5f480a01,0x0412b2aa,0x259814fc,0x41d0efe2,
0x4e40b48d,0x248eb6fb,0x8dba1cfe,0x41a99b02,
0x1a550a04,0xba8f65cb,0x7251f4e7,0x95a51725,
0xc106ecd7,0x97a5980a,0xc539b9aa,0x4d79fe6a,
0xf2f3f763,0x68af8040,0xed0c9e56,0x11b4958b,
0xe1eb5a88,0x8709e6b0,0xd7e07156,0x4e29fea7,
0x6366e52d,0x02d1c000,0xc4ac8e05,0x9377f571,
0x0c05372a,0x578535f2,0x2261be02,0xd642a0c9,
0xdf13a280,0x74b55bd2,0x682199c0,0xd421e5ec,
0x53fb3ce8,0xc8adedb3,0x28a87fc9,0x3d959981,
0x5c1ff900,0xfe38d399,0x0c4eff0b,0x062407ea,
0xaa2f4fb1,0x4fb96976,0x90c79505,0xb0a8a774,
0xef55a1ff,0xe59ca2c2,0xa6b62d27,0xe66a4263,
0xdf65001f,0x0ec50966,0xdfdd55bc,0x29de0655,
0x911e739a,0x17af8975,0x32c7911c,0x89f89468,
0x0d01e980,0x524755f4,0x03b63cc9,0x0cc844b2,
0xbcf3f0aa,0x87ac36e9,0xe53a7426,0x01b3d82b,
0x1a9e7449,0x64ee2d7e,0xcddbb1da,0x01c94910,
0xb868bf80,0x0d26f3fd,0x9342ede7,0x04a5c284,
0x636737b6,0x50f5b616,0xf24766e3,0x8eca36c1,
0x136e05db,0xfef18391,0xfb887a37,0xd6e7f7d4,
0xc7fb7dc9,0x3063fcdf,0xb6f589de,0xec2941da,
0x26e46695,0xb7566419,0xf654efc5,0xd08d58b7,
0x48925401,0xc1bacb7f,0xe5ff550f,0xb6083049,
0x5bb5d0e8,0x87d72e5a,0xab6a6ee1,0x223a66ce,
0xc62bf3cd,0x9e0885f9,0x68cb3e47,0x086c010f,
0xa21de820,0xd18b69de,0xf3f65777,0xfa02c3f6,
0x407edac3,0xcbb3d550,0x1793084d,0xb0d70eba,
0x0ab378d5,0xd951fb0c,0xded7da56,0x4124bbe4,
0x94ca0b56,0x0f5755d1,0xe0e1e56e,0x6184b5be,
0x580a249f,0x94f74bc0,0xe327888e,0x9f7b5561,
0xc3dc0280,0x05687715,0x646c6bd7,0x44904db3,
0x66b4f0a3,0xc0f1648a,0x697ed5af,0x49e92ff6,
0x309e374f,0x2cb6356a,0x85808573,0x4991f840,
0x76f0ae02,0x083be84d,0x28421c9a,0x44489406,
0x736e4cb8,0xc1092910,0x8bc95fc6,0x7d869cf4,
0x134f616f,0x2e77118d,0xb31b2be1,0xaa90b472,
0x3ca5d717,0x7d161bba,0x9cad9010,0xaf462ba2,
0x9fe459d2,0x45d34559,0xd9f2da13,0xdbc65487,
0xf3e4f94e,0x176d486f,0x097c13ea,0x631da5c7,
0x445f7382,0x175683f4,0xcdc66a97,0x70be0288,
0xb3cdcf72,0x6e5dd2f3,0x20936079,0x459b80a5,
0xbe60e2db,0xa9c23101,0xeba5315c,0x224e42f2,
0x1c5c1572,0xf6721b2c,0x1ad2fff3,0x8c25404e,
0x324ed72f,0x4067b7fd,0x0523138e,0x5ca3bc78,
0xdc0fd66e,0x75922283,0x784d6b17,0x58ebb16e,
0x44094f85,0x3f481d87,0xfcfeae7b,0x77b5ff76,
0x8c2302bf,0xaaf47556,0x5f46b02a,0x2b092801,
0x3d38f5f7,0x0ca81f36,0x52af4a8a,0x66d5e7c0,
0xdf3b0874,0x95055110,0x1b5ad7a8,0xf61ed5ad,
0x6cf6e479,0x20758184,0xd0cefa65,0x88f7be58,
0x4a046826,0x0ff6f8f3,0xa09c7f70,0x5346aba0,
0x5ce96c28,0xe176eda3,0x6bac307f,0x376829d2,
0x85360fa9,0x17e3fe2a,0x24b79767,0xf5a96b20,
0xd6cd2595,0x68ff1ebf,0x7555442c,0xf19f06be,
0xf9e0659a,0xeeb9491d,0x34010718,0xbb30cab8,
0xe822fe15,0x88570983,0x750e6249,0xda627e55,
0x5e76ffa8,0xb1534546,0x6d47de08,0xefe9e7d4,
};
CAST_LONG CAST_S_table5[256]={
0xf6fa8f9d,0x2cac6ce1,0x4ca34867,0xe2337f7c,
0x95db08e7,0x016843b4,0xeced5cbc,0x325553ac,
0xbf9f0960,0xdfa1e2ed,0x83f0579d,0x63ed86b9,
0x1ab6a6b8,0xde5ebe39,0xf38ff732,0x8989b138,
0x33f14961,0xc01937bd,0xf506c6da,0xe4625e7e,
0xa308ea99,0x4e23e33c,0x79cbd7cc,0x48a14367,
0xa3149619,0xfec94bd5,0xa114174a,0xeaa01866,
0xa084db2d,0x09a8486f,0xa888614a,0x2900af98,
0x01665991,0xe1992863,0xc8f30c60,0x2e78ef3c,
0xd0d51932,0xcf0fec14,0xf7ca07d2,0xd0a82072,
0xfd41197e,0x9305a6b0,0xe86be3da,0x74bed3cd,
0x372da53c,0x4c7f4448,0xdab5d440,0x6dba0ec3,
0x083919a7,0x9fbaeed9,0x49dbcfb0,0x4e670c53,
0x5c3d9c01,0x64bdb941,0x2c0e636a,0xba7dd9cd,
0xea6f7388,0xe70bc762,0x35f29adb,0x5c4cdd8d,
0xf0d48d8c,0xb88153e2,0x08a19866,0x1ae2eac8,
0x284caf89,0xaa928223,0x9334be53,0x3b3a21bf,
0x16434be3,0x9aea3906,0xefe8c36e,0xf890cdd9,
0x80226dae,0xc340a4a3,0xdf7e9c09,0xa694a807,
0x5b7c5ecc,0x221db3a6,0x9a69a02f,0x68818a54,
0xceb2296f,0x53c0843a,0xfe893655,0x25bfe68a,
0xb4628abc,0xcf222ebf,0x25ac6f48,0xa9a99387,
0x53bddb65,0xe76ffbe7,0xe967fd78,0x0ba93563,
0x8e342bc1,0xe8a11be9,0x4980740d,0xc8087dfc,
0x8de4bf99,0xa11101a0,0x7fd37975,0xda5a26c0,
0xe81f994f,0x9528cd89,0xfd339fed,0xb87834bf,
0x5f04456d,0x22258698,0xc9c4c83b,0x2dc156be,
0x4f628daa,0x57f55ec5,0xe2220abe,0xd2916ebf,
0x4ec75b95,0x24f2c3c0,0x42d15d99,0xcd0d7fa0,
0x7b6e27ff,0xa8dc8af0,0x7345c106,0xf41e232f,
0x35162386,0xe6ea8926,0x3333b094,0x157ec6f2,
0x372b74af,0x692573e4,0xe9a9d848,0xf3160289,
0x3a62ef1d,0xa787e238,0xf3a5f676,0x74364853,
0x20951063,0x4576698d,0xb6fad407,0x592af950,
0x36f73523,0x4cfb6e87,0x7da4cec0,0x6c152daa,
0xcb0396a8,0xc50dfe5d,0xfcd707ab,0x0921c42f,
0x89dff0bb,0x5fe2be78,0x448f4f33,0x754613c9,
0x2b05d08d,0x48b9d585,0xdc049441,0xc8098f9b,
0x7dede786,0xc39a3373,0x42410005,0x6a091751,
0x0ef3c8a6,0x890072d6,0x28207682,0xa9a9f7be,
0xbf32679d,0xd45b5b75,0xb353fd00,0xcbb0e358,
0x830f220a,0x1f8fb214,0xd372cf08,0xcc3c4a13,
0x8cf63166,0x061c87be,0x88c98f88,0x6062e397,
0x47cf8e7a,0xb6c85283,0x3cc2acfb,0x3fc06976,
0x4e8f0252,0x64d8314d,0xda3870e3,0x1e665459,
0xc10908f0,0x513021a5,0x6c5b68b7,0x822f8aa0,
0x3007cd3e,0x74719eef,0xdc872681,0x073340d4,
0x7e432fd9,0x0c5ec241,0x8809286c,0xf592d891,
0x08a930f6,0x957ef305,0xb7fbffbd,0xc266e96f,
0x6fe4ac98,0xb173ecc0,0xbc60b42a,0x953498da,
0xfba1ae12,0x2d4bd736,0x0f25faab,0xa4f3fceb,
0xe2969123,0x257f0c3d,0x9348af49,0x361400bc,
0xe8816f4a,0x3814f200,0xa3f94043,0x9c7a54c2,
0xbc704f57,0xda41e7f9,0xc25ad33a,0x54f4a084,
0xb17f5505,0x59357cbe,0xedbd15c8,0x7f97c5ab,
0xba5ac7b5,0xb6f6deaf,0x3a479c3a,0x5302da25,
0x653d7e6a,0x54268d49,0x51a477ea,0x5017d55b,
0xd7d25d88,0x44136c76,0x0404a8c8,0xb8e5a121,
0xb81a928a,0x60ed5869,0x97c55b96,0xeaec991b,
0x29935913,0x01fdb7f1,0x088e8dfa,0x9ab6f6f5,
0x3b4cbf9f,0x4a5de3ab,0xe6051d35,0xa0e1d855,
0xd36b4cf1,0xf544edeb,0xb0e93524,0xbebb8fbd,
0xa2d762cf,0x49c92f54,0x38b5f331,0x7128a454,
0x48392905,0xa65b1db8,0x851c97bd,0xd675cf2f,
};
CAST_LONG CAST_S_table6[256]={
0x85e04019,0x332bf567,0x662dbfff,0xcfc65693,
0x2a8d7f6f,0xab9bc912,0xde6008a1,0x2028da1f,
0x0227bce7,0x4d642916,0x18fac300,0x50f18b82,
0x2cb2cb11,0xb232e75c,0x4b3695f2,0xb28707de,
0xa05fbcf6,0xcd4181e9,0xe150210c,0xe24ef1bd,
0xb168c381,0xfde4e789,0x5c79b0d8,0x1e8bfd43,
0x4d495001,0x38be4341,0x913cee1d,0x92a79c3f,
0x089766be,0xbaeeadf4,0x1286becf,0xb6eacb19,
0x2660c200,0x7565bde4,0x64241f7a,0x8248dca9,
0xc3b3ad66,0x28136086,0x0bd8dfa8,0x356d1cf2,
0x107789be,0xb3b2e9ce,0x0502aa8f,0x0bc0351e,
0x166bf52a,0xeb12ff82,0xe3486911,0xd34d7516,
0x4e7b3aff,0x5f43671b,0x9cf6e037,0x4981ac83,
0x334266ce,0x8c9341b7,0xd0d854c0,0xcb3a6c88,
0x47bc2829,0x4725ba37,0xa66ad22b,0x7ad61f1e,
0x0c5cbafa,0x4437f107,0xb6e79962,0x42d2d816,
0x0a961288,0xe1a5c06e,0x13749e67,0x72fc081a,
0xb1d139f7,0xf9583745,0xcf19df58,0xbec3f756,
0xc06eba30,0x07211b24,0x45c28829,0xc95e317f,
0xbc8ec511,0x38bc46e9,0xc6e6fa14,0xbae8584a,
0xad4ebc46,0x468f508b,0x7829435f,0xf124183b,
0x821dba9f,0xaff60ff4,0xea2c4e6d,0x16e39264,
0x92544a8b,0x009b4fc3,0xaba68ced,0x9ac96f78,
0x06a5b79a,0xb2856e6e,0x1aec3ca9,0xbe838688,
0x0e0804e9,0x55f1be56,0xe7e5363b,0xb3a1f25d,
0xf7debb85,0x61fe033c,0x16746233,0x3c034c28,
0xda6d0c74,0x79aac56c,0x3ce4e1ad,0x51f0c802,
0x98f8f35a,0x1626a49f,0xeed82b29,0x1d382fe3,
0x0c4fb99a,0xbb325778,0x3ec6d97b,0x6e77a6a9,
0xcb658b5c,0xd45230c7,0x2bd1408b,0x60c03eb7,
0xb9068d78,0xa33754f4,0xf430c87d,0xc8a71302,
0xb96d8c32,0xebd4e7be,0xbe8b9d2d,0x7979fb06,
0xe7225308,0x8b75cf77,0x11ef8da4,0xe083c858,
0x8d6b786f,0x5a6317a6,0xfa5cf7a0,0x5dda0033,
0xf28ebfb0,0xf5b9c310,0xa0eac280,0x08b9767a,
0xa3d9d2b0,0x79d34217,0x021a718d,0x9ac6336a,
0x2711fd60,0x438050e3,0x069908a8,0x3d7fedc4,
0x826d2bef,0x4eeb8476,0x488dcf25,0x36c9d566,
0x28e74e41,0xc2610aca,0x3d49a9cf,0xbae3b9df,
0xb65f8de6,0x92aeaf64,0x3ac7d5e6,0x9ea80509,
0xf22b017d,0xa4173f70,0xdd1e16c3,0x15e0d7f9,
0x50b1b887,0x2b9f4fd5,0x625aba82,0x6a017962,
0x2ec01b9c,0x15488aa9,0xd716e740,0x40055a2c,
0x93d29a22,0xe32dbf9a,0x058745b9,0x3453dc1e,
0xd699296e,0x496cff6f,0x1c9f4986,0xdfe2ed07,
0xb87242d1,0x19de7eae,0x053e561a,0x15ad6f8c,
0x66626c1c,0x7154c24c,0xea082b2a,0x93eb2939,
0x17dcb0f0,0x58d4f2ae,0x9ea294fb,0x52cf564c,
0x9883fe66,0x2ec40581,0x763953c3,0x01d6692e,
0xd3a0c108,0xa1e7160e,0xe4f2dfa6,0x693ed285,
0x74904698,0x4c2b0edd,0x4f757656,0x5d393378,
0xa132234f,0x3d321c5d,0xc3f5e194,0x4b269301,
0xc79f022f,0x3c997e7e,0x5e4f9504,0x3ffafbbd,
0x76f7ad0e,0x296693f4,0x3d1fce6f,0xc61e45be,
0xd3b5ab34,0xf72bf9b7,0x1b0434c0,0x4e72b567,
0x5592a33d,0xb5229301,0xcfd2a87f,0x60aeb767,
0x1814386b,0x30bcc33d,0x38a0c07d,0xfd1606f2,
0xc363519b,0x589dd390,0x5479f8e6,0x1cb8d647,
0x97fd61a9,0xea7759f4,0x2d57539d,0x569a58cf,
0xe84e63ad,0x462e1b78,0x6580f87e,0xf3817914,
0x91da55f4,0x40a230f3,0xd1988f35,0xb6e318d2,
0x3ffa50bc,0x3d40f021,0xc3c0bdae,0x4958c24c,
0x518f36b2,0x84b1d370,0x0fedce83,0x878ddada,
0xf2a279c7,0x94e01be8,0x90716f4b,0x954b8aa3,
};
CAST_LONG CAST_S_table7[256]={
0xe216300d,0xbbddfffc,0xa7ebdabd,0x35648095,
0x7789f8b7,0xe6c1121b,0x0e241600,0x052ce8b5,
0x11a9cfb0,0xe5952f11,0xece7990a,0x9386d174,
0x2a42931c,0x76e38111,0xb12def3a,0x37ddddfc,
0xde9adeb1,0x0a0cc32c,0xbe197029,0x84a00940,
0xbb243a0f,0xb4d137cf,0xb44e79f0,0x049eedfd,
0x0b15a15d,0x480d3168,0x8bbbde5a,0x669ded42,
0xc7ece831,0x3f8f95e7,0x72df191b,0x7580330d,
0x94074251,0x5c7dcdfa,0xabbe6d63,0xaa402164,
0xb301d40a,0x02e7d1ca,0x53571dae,0x7a3182a2,
0x12a8ddec,0xfdaa335d,0x176f43e8,0x71fb46d4,
0x38129022,0xce949ad4,0xb84769ad,0x965bd862,
0x82f3d055,0x66fb9767,0x15b80b4e,0x1d5b47a0,
0x4cfde06f,0xc28ec4b8,0x57e8726e,0x647a78fc,
0x99865d44,0x608bd593,0x6c200e03,0x39dc5ff6,
0x5d0b00a3,0xae63aff2,0x7e8bd632,0x70108c0c,
0xbbd35049,0x2998df04,0x980cf42a,0x9b6df491,
0x9e7edd53,0x06918548,0x58cb7e07,0x3b74ef2e,
0x522fffb1,0xd24708cc,0x1c7e27cd,0xa4eb215b,
0x3cf1d2e2,0x19b47a38,0x424f7618,0x35856039,
0x9d17dee7,0x27eb35e6,0xc9aff67b,0x36baf5b8,
0x09c467cd,0xc18910b1,0xe11dbf7b,0x06cd1af8,
0x7170c608,0x2d5e3354,0xd4de495a,0x64c6d006,
0xbcc0c62c,0x3dd00db3,0x708f8f34,0x77d51b42,
0x264f620f,0x24b8d2bf,0x15c1b79e,0x46a52564,
0xf8d7e54e,0x3e378160,0x7895cda5,0x859c15a5,
0xe6459788,0xc37bc75f,0xdb07ba0c,0x0676a3ab,
0x7f229b1e,0x31842e7b,0x24259fd7,0xf8bef472,
0x835ffcb8,0x6df4c1f2,0x96f5b195,0xfd0af0fc,
0xb0fe134c,0xe2506d3d,0x4f9b12ea,0xf215f225,
0xa223736f,0x9fb4c428,0x25d04979,0x34c713f8,
0xc4618187,0xea7a6e98,0x7cd16efc,0x1436876c,
0xf1544107,0xbedeee14,0x56e9af27,0xa04aa441,
0x3cf7c899,0x92ecbae6,0xdd67016d,0x151682eb,
0xa842eedf,0xfdba60b4,0xf1907b75,0x20e3030f,
0x24d8c29e,0xe139673b,0xefa63fb8,0x71873054,
0xb6f2cf3b,0x9f326442,0xcb15a4cc,0xb01a4504,
0xf1e47d8d,0x844a1be5,0xbae7dfdc,0x42cbda70,
0xcd7dae0a,0x57e85b7a,0xd53f5af6,0x20cf4d8c,
0xcea4d428,0x79d130a4,0x3486ebfb,0x33d3cddc,
0x77853b53,0x37effcb5,0xc5068778,0xe580b3e6,
0x4e68b8f4,0xc5c8b37e,0x0d809ea2,0x398feb7c,
0x132a4f94,0x43b7950e,0x2fee7d1c,0x223613bd,
0xdd06caa2,0x37df932b,0xc4248289,0xacf3ebc3,
0x5715f6b7,0xef3478dd,0xf267616f,0xc148cbe4,
0x9052815e,0x5e410fab,0xb48a2465,0x2eda7fa4,
0xe87b40e4,0xe98ea084,0x5889e9e1,0xefd390fc,
0xdd07d35b,0xdb485694,0x38d7e5b2,0x57720101,
0x730edebc,0x5b643113,0x94917e4f,0x503c2fba,
0x646f1282,0x7523d24a,0xe0779695,0xf9c17a8f,
0x7a5b2121,0xd187b896,0x29263a4d,0xba510cdf,
0x81f47c9f,0xad1163ed,0xea7b5965,0x1a00726e,
0x11403092,0x00da6d77,0x4a0cdd61,0xad1f4603,
0x605bdfb0,0x9eedc364,0x22ebe6a8,0xcee7d28a,
0xa0e736a0,0x5564a6b9,0x10853209,0xc7eb8f37,
0x2de705ca,0x8951570f,0xdf09822b,0xbd691a6c,
0xaa12e4f2,0x87451c0f,0xe0f6a27a,0x3ada4819,
0x4cf1764f,0x0d771c2b,0x67cdb156,0x350d8384,
0x5938fa0f,0x42399ef3,0x36997b07,0x0e84093d,
0x4aa93e61,0x8360d87b,0x1fa98b0c,0x1149382c,
0xe97625a5,0x0614d1b7,0x0e25244b,0x0c768347,
0x589e8d82,0x0d2059d1,0xa466bb1e,0xf8da0a82,
0x04f19130,0xba6e4ec0,0x99265164,0x1ee7230d,
0x50b2ad80,0xeaee6801,0x8db2a283,0xea8bf59e,
};

4
src/utils/crypto/des.c Normal file
View File

@@ -0,0 +1,4 @@
/* Deprecated/legacy */
#include "des.h"
#include "spr.h"

292
src/utils/crypto/des.h Normal file
View File

@@ -0,0 +1,292 @@
/* Deprecated/legacy */
/* crypto/des/des.org */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*
* Always modify des.org since des.h is automatically generated from
* it during SSLeay configuration.
*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*/
#ifndef HEADER_DES_H
#define HEADER_DES_H
#ifdef __cplusplus
extern "C" {
#endif
#include <inttypes.h>
#include <stdio.h>
/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
* %20 speed up (longs are 8 bytes, int's are 4). */
#ifndef DES_LONG
#define DES_LONG uint32_t
#endif
typedef unsigned char des_cblock[8];
typedef struct des_ks_struct
{
union {
des_cblock _;
/* make sure things are correct size on machines with
* 8 byte longs */
DES_LONG pad[2];
} ks;
} des_key_schedule[16];
#define DES_KEY_SZ (sizeof(des_cblock))
#define DES_SCHEDULE_SZ (sizeof(des_key_schedule))
#define DES_ENCRYPT 1
#define DES_DECRYPT 0
#define DES_CBC_MODE 0
#define DES_PCBC_MODE 1
#define des_ecb2_encrypt(i,o,k1,k2,e) \
des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
#define C_Block des_cblock
#define Key_schedule des_key_schedule
#ifdef KERBEROS
#define ENCRYPT DES_ENCRYPT
#define DECRYPT DES_DECRYPT
#endif
#define KEY_SZ DES_KEY_SZ
#define string_to_key des_string_to_key
#define read_pw_string des_read_pw_string
#define random_key des_random_key
#define pcbc_encrypt des_pcbc_encrypt
#define set_key des_set_key
#define key_sched des_key_sched
#define ecb_encrypt des_ecb_encrypt
#define cbc_encrypt des_cbc_encrypt
#define ncbc_encrypt des_ncbc_encrypt
#define xcbc_encrypt des_xcbc_encrypt
#define cbc_cksum des_cbc_cksum
#define quad_cksum des_quad_cksum
/* For compatibility with the MIT lib - eay 20/05/92 */
typedef des_key_schedule bit_64;
#define des_fixup_key_parity des_set_odd_parity
#define des_check_key_parity check_parity
extern int des_check_key; /* defaults to false */
extern int des_rw_mode; /* defaults to DES_PCBC_MODE */
/* The next line is used to disable full ANSI prototypes, if your
* compiler has problems with the prototypes, make sure this line always
* evaluates to true :-) */
#if defined(MSDOS) || defined(__STDC__)
#undef NOPROTO
#endif
#ifndef NOPROTO
char *des_options(void);
void des_ecb3_encrypt(des_cblock *input,des_cblock *output,
des_key_schedule ks1,des_key_schedule ks2,
des_key_schedule ks3, int enc);
DES_LONG des_cbc_cksum(des_cblock *input,des_cblock *output,
long length,des_key_schedule schedule,des_cblock *ivec);
void des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,
des_key_schedule schedule,des_cblock *ivec,int enc);
void des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length,
des_key_schedule schedule,des_cblock *ivec,int enc);
void des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length,
des_key_schedule schedule,des_cblock *ivec,
des_cblock *inw,des_cblock *outw,int enc);
void des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
long length,des_key_schedule schedule,des_cblock *ivec,int enc);
void des_ecb_encrypt(des_cblock *input,des_cblock *output,
des_key_schedule ks,int enc);
void des_encrypt(DES_LONG *data,des_key_schedule ks, int enc);
void des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc);
void des_encrypt3(DES_LONG *data, des_key_schedule ks1,
des_key_schedule ks2, des_key_schedule ks3);
void des_decrypt3(DES_LONG *data, des_key_schedule ks1,
des_key_schedule ks2, des_key_schedule ks3);
void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output,
long length, des_key_schedule ks1, des_key_schedule ks2,
des_key_schedule ks3, des_cblock *ivec, int enc);
void des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
long length, des_key_schedule ks1, des_key_schedule ks2,
des_key_schedule ks3, des_cblock *ivec, int *num, int enc);
void des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
long length, des_key_schedule ks1, des_key_schedule ks2,
des_key_schedule ks3, des_cblock *ivec, int *num);
void des_xwhite_in2out(des_cblock (*des_key), des_cblock (*in_white),
des_cblock (*out_white));
int des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
des_cblock *iv);
int des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
des_cblock *iv);
char *des_fcrypt(const char *buf,const char *salt, char *ret);
char *des_crypt(const char *buf,const char *salt);
void des_ofb_encrypt(unsigned char *in,unsigned char *out,
int numbits,long length,des_key_schedule schedule,des_cblock *ivec);
void des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,
des_key_schedule schedule,des_cblock *ivec,int enc);
DES_LONG des_quad_cksum(des_cblock *input,des_cblock *output,
long length,int out_count,des_cblock *seed);
void des_random_seed(des_cblock key);
void des_random_key(des_cblock ret);
int des_read_password(des_cblock *key,char *prompt,int verify);
int des_read_2passwords(des_cblock *key1,des_cblock *key2,
char *prompt,int verify);
int des_read_pw_string(char *buf,int length,char *prompt,int verify);
void des_set_odd_parity(des_cblock *key);
int des_is_weak_key(des_cblock *key);
int des_set_key(des_cblock *key,des_key_schedule schedule);
int des_key_sched(des_cblock *key,des_key_schedule schedule);
void des_string_to_key(char *str,des_cblock *key);
void des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);
void des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
des_key_schedule schedule, des_cblock *ivec, int *num, int enc);
void des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
des_key_schedule schedule, des_cblock *ivec, int *num);
int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify);
/* Extra functions from Mark Murray <mark@grondar.za> */
void des_cblock_print_file(des_cblock *cb, FILE *fp);
/* The following functions are not in the normal unix build or the
* SSLeay build. When using the SSLeay build, use RAND_seed()
* and RAND_bytes() instead. */
int des_new_random_key(des_cblock *key);
void des_init_random_number_generator(des_cblock *key);
void des_set_random_generator_seed(des_cblock *key);
void des_set_sequence_number(des_cblock new_sequence_number);
void des_generate_random_block(des_cblock *block);
#else
char *des_options();
void des_ecb3_encrypt();
DES_LONG des_cbc_cksum();
void des_cbc_encrypt();
void des_ncbc_encrypt();
void des_xcbc_encrypt();
void des_cfb_encrypt();
void des_ede3_cfb64_encrypt();
void des_ede3_ofb64_encrypt();
void des_ecb_encrypt();
void des_encrypt();
void des_encrypt2();
void des_encrypt3();
void des_decrypt3();
void des_ede3_cbc_encrypt();
int des_enc_read();
int des_enc_write();
char *des_fcrypt();
#ifdef PERL5
char *des_crypt();
#else
char *crypt();
#endif
void des_ofb_encrypt();
void des_pcbc_encrypt();
DES_LONG des_quad_cksum();
void des_random_seed();
void des_random_key();
int des_read_password();
int des_read_2passwords();
int des_read_pw_string();
void des_set_odd_parity();
int des_is_weak_key();
int des_set_key();
int des_key_sched();
void des_string_to_key();
void des_string_to_2keys();
void des_cfb64_encrypt();
void des_ofb64_encrypt();
int des_read_pw();
void des_xwhite_in2out();
/* Extra functions from Mark Murray <mark@grondar.za> */
void des_cblock_print_file();
/* The following functions are not in the normal unix build or the
* SSLeay build. When using the SSLeay build, use RAND_seed()
* and RAND_bytes() instead. */
#ifdef FreeBSD
int des_new_random_key();
void des_init_random_number_generator();
void des_set_random_generator_seed();
void des_set_sequence_number();
void des_generate_random_block();
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif

479
src/utils/crypto/des_enc.c Normal file
View File

@@ -0,0 +1,479 @@
/* Deprecated/legacy */
/* crypto/des/des_enc.c */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* Adapted for TrueCrypt by the TrueCrypt Foundation */
#include "des_locl.h"
#include "../common/endian.h"
void des_encrypt(DES_LONG *data, des_key_schedule ks, int enc)
{
register DES_LONG l,r,t,u;
#ifdef DES_PTR
register unsigned char *des_SP=(unsigned char *)des_SPtrans;
#endif
#ifndef DES_UNROLL
register int i;
#endif
register DES_LONG *s;
r=LE32(data[0]);
l=LE32(data[1]);
IP(r,l);
/* Things have been modified so that the initial rotate is
* done outside the loop. This required the
* des_SPtrans values in sp.h to be rotated 1 bit to the right.
* One perl script later and things have a 5% speed up on a sparc2.
* Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
* for pointing this out. */
/* clear the top bits on machines with 8byte longs */
/* shift left by 2 */
r=ROTATE(r,29)&0xffffffffL;
l=ROTATE(l,29)&0xffffffffL;
s=(DES_LONG *)ks;
/* I don't know if it is worth the effort of loop unrolling the
* inner loop */
if (enc)
{
#ifdef DES_UNROLL
D_ENCRYPT(l,r, 0); /* 1 */
D_ENCRYPT(r,l, 2); /* 2 */
D_ENCRYPT(l,r, 4); /* 3 */
D_ENCRYPT(r,l, 6); /* 4 */
D_ENCRYPT(l,r, 8); /* 5 */
D_ENCRYPT(r,l,10); /* 6 */
D_ENCRYPT(l,r,12); /* 7 */
D_ENCRYPT(r,l,14); /* 8 */
D_ENCRYPT(l,r,16); /* 9 */
D_ENCRYPT(r,l,18); /* 10 */
D_ENCRYPT(l,r,20); /* 11 */
D_ENCRYPT(r,l,22); /* 12 */
D_ENCRYPT(l,r,24); /* 13 */
D_ENCRYPT(r,l,26); /* 14 */
D_ENCRYPT(l,r,28); /* 15 */
D_ENCRYPT(r,l,30); /* 16 */
#else
for (i=0; i<32; i+=8)
{
D_ENCRYPT(l,r,i+0); /* 1 */
D_ENCRYPT(r,l,i+2); /* 2 */
D_ENCRYPT(l,r,i+4); /* 3 */
D_ENCRYPT(r,l,i+6); /* 4 */
}
#endif
}
else
{
#ifdef DES_UNROLL
D_ENCRYPT(l,r,30); /* 16 */
D_ENCRYPT(r,l,28); /* 15 */
D_ENCRYPT(l,r,26); /* 14 */
D_ENCRYPT(r,l,24); /* 13 */
D_ENCRYPT(l,r,22); /* 12 */
D_ENCRYPT(r,l,20); /* 11 */
D_ENCRYPT(l,r,18); /* 10 */
D_ENCRYPT(r,l,16); /* 9 */
D_ENCRYPT(l,r,14); /* 8 */
D_ENCRYPT(r,l,12); /* 7 */
D_ENCRYPT(l,r,10); /* 6 */
D_ENCRYPT(r,l, 8); /* 5 */
D_ENCRYPT(l,r, 6); /* 4 */
D_ENCRYPT(r,l, 4); /* 3 */
D_ENCRYPT(l,r, 2); /* 2 */
D_ENCRYPT(r,l, 0); /* 1 */
#else
for (i=30; i>0; i-=8)
{
D_ENCRYPT(l,r,i-0); /* 16 */
D_ENCRYPT(r,l,i-2); /* 15 */
D_ENCRYPT(l,r,i-4); /* 14 */
D_ENCRYPT(r,l,i-6); /* 13 */
}
#endif
}
/* rotate and clear the top bits on machines with 8byte longs */
l=ROTATE(l,3)&0xffffffffL;
r=ROTATE(r,3)&0xffffffffL;
FP(r,l);
data[0]=LE32(l);
data[1]=LE32(r);
l=r=t=u=0;
}
void des_encrypt2(DES_LONG *data, des_key_schedule ks, int enc)
{
register DES_LONG l,r,t,u;
#ifdef DES_PTR
register unsigned char *des_SP=(unsigned char *)des_SPtrans;
#endif
#ifndef DES_UNROLL
register int i;
#endif
register DES_LONG *s;
r=data[0];
l=data[1];
/* Things have been modified so that the initial rotate is
* done outside the loop. This required the
* des_SPtrans values in sp.h to be rotated 1 bit to the right.
* One perl script later and things have a 5% speed up on a sparc2.
* Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
* for pointing this out. */
/* clear the top bits on machines with 8byte longs */
r=ROTATE(r,29)&0xffffffffL;
l=ROTATE(l,29)&0xffffffffL;
s=(DES_LONG *)ks;
/* I don't know if it is worth the effort of loop unrolling the
* inner loop */
if (enc)
{
#ifdef DES_UNROLL
D_ENCRYPT(l,r, 0); /* 1 */
D_ENCRYPT(r,l, 2); /* 2 */
D_ENCRYPT(l,r, 4); /* 3 */
D_ENCRYPT(r,l, 6); /* 4 */
D_ENCRYPT(l,r, 8); /* 5 */
D_ENCRYPT(r,l,10); /* 6 */
D_ENCRYPT(l,r,12); /* 7 */
D_ENCRYPT(r,l,14); /* 8 */
D_ENCRYPT(l,r,16); /* 9 */
D_ENCRYPT(r,l,18); /* 10 */
D_ENCRYPT(l,r,20); /* 11 */
D_ENCRYPT(r,l,22); /* 12 */
D_ENCRYPT(l,r,24); /* 13 */
D_ENCRYPT(r,l,26); /* 14 */
D_ENCRYPT(l,r,28); /* 15 */
D_ENCRYPT(r,l,30); /* 16 */
#else
for (i=0; i<32; i+=8)
{
D_ENCRYPT(l,r,i+0); /* 1 */
D_ENCRYPT(r,l,i+2); /* 2 */
D_ENCRYPT(l,r,i+4); /* 3 */
D_ENCRYPT(r,l,i+6); /* 4 */
}
#endif
}
else
{
#ifdef DES_UNROLL
D_ENCRYPT(l,r,30); /* 16 */
D_ENCRYPT(r,l,28); /* 15 */
D_ENCRYPT(l,r,26); /* 14 */
D_ENCRYPT(r,l,24); /* 13 */
D_ENCRYPT(l,r,22); /* 12 */
D_ENCRYPT(r,l,20); /* 11 */
D_ENCRYPT(l,r,18); /* 10 */
D_ENCRYPT(r,l,16); /* 9 */
D_ENCRYPT(l,r,14); /* 8 */
D_ENCRYPT(r,l,12); /* 7 */
D_ENCRYPT(l,r,10); /* 6 */
D_ENCRYPT(r,l, 8); /* 5 */
D_ENCRYPT(l,r, 6); /* 4 */
D_ENCRYPT(r,l, 4); /* 3 */
D_ENCRYPT(l,r, 2); /* 2 */
D_ENCRYPT(r,l, 0); /* 1 */
#else
for (i=30; i>0; i-=8)
{
D_ENCRYPT(l,r,i-0); /* 16 */
D_ENCRYPT(r,l,i-2); /* 15 */
D_ENCRYPT(l,r,i-4); /* 14 */
D_ENCRYPT(r,l,i-6); /* 13 */
}
#endif
}
/* rotate and clear the top bits on machines with 8byte longs */
data[0]=ROTATE(l,3)&0xffffffffL;
data[1]=ROTATE(r,3)&0xffffffffL;
l=r=t=u=0;
}
void des_encrypt3(DES_LONG *data, des_key_schedule ks1, des_key_schedule ks2, des_key_schedule ks3)
{
register DES_LONG l,r;
l=data[0];
r=data[1];
IP(l,r);
data[0]=l;
data[1]=r;
des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
l=data[0];
r=data[1];
FP(r,l);
data[0]=l;
data[1]=r;
}
void des_decrypt3(DES_LONG *data, des_key_schedule ks1, des_key_schedule ks2, des_key_schedule ks3)
{
register DES_LONG l,r;
l=data[0];
r=data[1];
IP(l,r);
data[0]=l;
data[1]=r;
des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
l=data[0];
r=data[1];
FP(r,l);
data[0]=l;
data[1]=r;
}
#ifndef DES_DEFAULT_OPTIONS
void des_ncbc_encrypt(des_cblock (*input), des_cblock (*output), long length, des_key_schedule schedule, des_cblock (*ivec), int enc)
{
register DES_LONG tin0,tin1;
register DES_LONG tout0,tout1,xor0,xor1;
register unsigned char *in,*out;
register long l=length;
DES_LONG tin[2];
unsigned char *iv;
in=(unsigned char *)input;
out=(unsigned char *)output;
iv=(unsigned char *)ivec;
if (enc)
{
c2l(iv,tout0);
c2l(iv,tout1);
for (l-=8; l>=0; l-=8)
{
c2l(in,tin0);
c2l(in,tin1);
tin0^=tout0; tin[0]=tin0;
tin1^=tout1; tin[1]=tin1;
des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
tout0=tin[0]; l2c(tout0,out);
tout1=tin[1]; l2c(tout1,out);
}
if (l != -8)
{
c2ln(in,tin0,tin1,l+8);
tin0^=tout0; tin[0]=tin0;
tin1^=tout1; tin[1]=tin1;
des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
tout0=tin[0]; l2c(tout0,out);
tout1=tin[1]; l2c(tout1,out);
}
iv=(unsigned char *)ivec;
l2c(tout0,iv);
l2c(tout1,iv);
}
else
{
c2l(iv,xor0);
c2l(iv,xor1);
for (l-=8; l>=0; l-=8)
{
c2l(in,tin0); tin[0]=tin0;
c2l(in,tin1); tin[1]=tin1;
des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
tout0=tin[0]^xor0;
tout1=tin[1]^xor1;
l2c(tout0,out);
l2c(tout1,out);
xor0=tin0;
xor1=tin1;
}
if (l != -8)
{
c2l(in,tin0); tin[0]=tin0;
c2l(in,tin1); tin[1]=tin1;
des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
tout0=tin[0]^xor0;
tout1=tin[1]^xor1;
l2cn(tout0,tout1,out,l+8);
xor0=tin0;
xor1=tin1;
}
iv=(unsigned char *)ivec;
l2c(xor0,iv);
l2c(xor1,iv);
}
tin0=tin1=tout0=tout1=xor0=xor1=0;
tin[0]=tin[1]=0;
}
void des_ede3_cbc_encrypt(des_cblock (*input), des_cblock (*output), long length, des_key_schedule ks1, des_key_schedule ks2, des_key_schedule ks3, des_cblock (*ivec), int enc)
{
register DES_LONG tin0,tin1;
register DES_LONG tout0,tout1,xor0,xor1;
register unsigned char *in,*out;
register long l=length;
DES_LONG tin[2];
unsigned char *iv;
in=(unsigned char *)input;
out=(unsigned char *)output;
iv=(unsigned char *)ivec;
if (enc)
{
c2l(iv,tout0);
c2l(iv,tout1);
for (l-=8; l>=0; l-=8)
{
c2l(in,tin0);
c2l(in,tin1);
tin0^=tout0;
tin1^=tout1;
tin[0]=tin0;
tin[1]=tin1;
des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
tout0=tin[0];
tout1=tin[1];
l2c(tout0,out);
l2c(tout1,out);
}
if (l != -8)
{
c2ln(in,tin0,tin1,l+8);
tin0^=tout0;
tin1^=tout1;
tin[0]=tin0;
tin[1]=tin1;
des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
tout0=tin[0];
tout1=tin[1];
l2c(tout0,out);
l2c(tout1,out);
}
iv=(unsigned char *)ivec;
l2c(tout0,iv);
l2c(tout1,iv);
}
else
{
register DES_LONG t0,t1;
c2l(iv,xor0);
c2l(iv,xor1);
for (l-=8; l>=0; l-=8)
{
c2l(in,tin0);
c2l(in,tin1);
t0=tin0;
t1=tin1;
tin[0]=tin0;
tin[1]=tin1;
des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
tout0=tin[0];
tout1=tin[1];
tout0^=xor0;
tout1^=xor1;
l2c(tout0,out);
l2c(tout1,out);
xor0=t0;
xor1=t1;
}
if (l != -8)
{
c2l(in,tin0);
c2l(in,tin1);
t0=tin0;
t1=tin1;
tin[0]=tin0;
tin[1]=tin1;
des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
tout0=tin[0];
tout1=tin[1];
tout0^=xor0;
tout1^=xor1;
l2cn(tout0,tout1,out,l+8);
xor0=t0;
xor1=t1;
}
iv=(unsigned char *)ivec;
l2c(xor0,iv);
l2c(xor1,iv);
}
tin0=tin1=tout0=tout1=xor0=xor1=0;
tin[0]=tin[1]=0;
}
#endif /* DES_DEFAULT_OPTIONS */

518
src/utils/crypto/des_locl.h Normal file
View File

@@ -0,0 +1,518 @@
/* Deprecated/legacy */
/* crypto/des/des_locl.org */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*
* Always modify des_locl.org since des_locl.h is automatically generated from
* it during SSLeay configuration.
*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*/
#ifndef HEADER_DES_LOCL_H
#define HEADER_DES_LOCL_H
#if defined(WIN32) || defined(WIN16)
#ifndef MSDOS
#define MSDOS
#endif
#endif
#include <stdio.h>
#include <stdlib.h>
#ifndef MSDOS
#include <unistd.h>
#endif
#include "des.h"
#ifndef DES_DEFAULT_OPTIONS
/* the following is tweaked from a config script, that is why it is a
* protected undef/define */
#ifndef DES_PTR
#define DES_PTR
#endif
/* This helps C compiler generate the correct code for multiple functional
* units. It reduces register dependancies at the expense of 2 more
* registers */
#ifndef DES_RISC1
#define DES_RISC1
#endif
#ifndef DES_RISC2
#undef DES_RISC2
#endif
#if defined(DES_RISC1) && defined(DES_RISC2)
YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
#endif
/* Unroll the inner loop, this sometimes helps, sometimes hinders.
* Very mucy CPU dependant */
#ifndef DES_UNROLL
#define DES_UNROLL
#endif
/* These default values were supplied by
* Peter Gutman <pgut001@cs.auckland.ac.nz>
* They are only used if nothing else has been defined */
#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
/* Special defines which change the way the code is built depending on the
CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
even newer MIPS CPU's, but at the moment one size fits all for
optimization options. Older Sparc's work better with only UNROLL, but
there's no way to tell at compile time what it is you're running on */
#if defined( sun ) /* Newer Sparc's */
#define DES_PTR
#define DES_RISC1
#define DES_UNROLL
#elif defined( __ultrix ) /* Older MIPS */
#define DES_PTR
#define DES_RISC2
#define DES_UNROLL
#elif defined( __osf1__ ) /* Alpha */
#define DES_PTR
#define DES_RISC2
#elif defined ( _AIX ) /* RS6000 */
/* Unknown */
#elif defined( __hpux ) /* HP-PA */
/* Unknown */
#elif defined( __aux ) /* 68K */
/* Unknown */
#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
#define DES_UNROLL
#elif defined( __sgi ) /* Newer MIPS */
#define DES_PTR
#define DES_RISC2
#define DES_UNROLL
#elif defined( i386 ) /* x86 boxes, should be gcc */
#define DES_PTR
#define DES_RISC1
#define DES_UNROLL
#endif /* Systems-specific speed defines */
#endif
#endif /* DES_DEFAULT_OPTIONS */
#ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <io.h>
#ifndef RAND
#define RAND
#endif
#undef NOPROTO
#endif
#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
#include <string.h>
#endif
#ifndef RAND
#define RAND
#endif
#ifdef linux
#undef RAND
#endif
#ifdef MSDOS
#define getpid() 2
#define RAND
#undef NOPROTO
#endif
#if defined(NOCONST)
#define const
#endif
#ifdef __STDC__
#undef NOPROTO
#endif
#ifdef RAND
#define srandom(s) srand(s)
#define random rand
#endif
#define ITERATIONS 16
#define HALF_ITERATIONS 8
/* used in des_read and des_write */
#define MAXWRITE (1024*16)
#define BSIZE (MAXWRITE+4)
#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \
l|=((DES_LONG)(*((c)++)))<< 8L, \
l|=((DES_LONG)(*((c)++)))<<16L, \
l|=((DES_LONG)(*((c)++)))<<24L)
/* NOTE - c is not incremented as per c2l */
#define c2ln(c,l1,l2,n) { \
c+=n; \
l1=l2=0; \
switch (n) { \
case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
case 5: l2|=((DES_LONG)(*(--(c)))); \
case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
case 1: l1|=((DES_LONG)(*(--(c)))); \
} \
}
#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
*((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
*((c)++)=(unsigned char)(((l)>>16L)&0xff), \
*((c)++)=(unsigned char)(((l)>>24L)&0xff))
/* replacements for htonl and ntohl since I have no idea what to do
* when faced with machines with 8 byte longs. */
#define HDRSIZE 4
#define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \
l|=((DES_LONG)(*((c)++)))<<16L, \
l|=((DES_LONG)(*((c)++)))<< 8L, \
l|=((DES_LONG)(*((c)++))))
#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
*((c)++)=(unsigned char)(((l)>>16L)&0xff), \
*((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
*((c)++)=(unsigned char)(((l) )&0xff))
/* NOTE - c is not incremented as per l2c */
#define l2cn(l1,l2,c,n) { \
c+=n; \
switch (n) { \
case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
} \
}
//#if defined(WIN32)
//#define ROTATE(a,n) (_lrotr(a,n))
//#else
#define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n))))
//#endif
/* Don't worry about the LOAD_DATA() stuff, that is used by
* fcrypt() to add it's little bit to the front */
#ifdef DES_FCRYPT
#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
{ DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
t=R^(R>>16L); \
u=t&E0; t&=E1; \
tmp=(u<<16); u^=R^s[S ]; u^=tmp; \
tmp=(t<<16); t^=R^s[S+1]; t^=tmp
#else
#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
u=R^s[S ]; \
t=R^s[S+1]
#endif
/* The changes to this macro may help or hinder, depending on the
* compiler and the achitecture. gcc2 always seems to do well :-).
* Inspired by Dana How <how@isl.stanford.edu>
* DO NOT use the alternative version on machines with 8 byte longs.
* It does not seem to work on the Alpha, even when DES_LONG is 4
* bytes, probably an issue of accessing non-word aligned objects :-( */
#ifdef DES_PTR
/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there
* is no reason to not xor all the sub items together. This potentially
* saves a register since things can be xored directly into L */
#if defined(DES_RISC1) || defined(DES_RISC2)
#ifdef DES_RISC1
#define D_ENCRYPT(LL,R,S) { \
unsigned int u1,u2,u3; \
LOAD_DATA(R,S,u,t,E0,E1,u1); \
u2=(int)u>>8L; \
u1=(int)u&0xfc; \
u2&=0xfc; \
t=ROTATE(t,4); \
u>>=16L; \
LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
u3=(int)(u>>8L); \
u1=(int)u&0xfc; \
u3&=0xfc; \
LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \
LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \
u2=(int)t>>8L; \
u1=(int)t&0xfc; \
u2&=0xfc; \
t>>=16L; \
LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
u3=(int)t>>8L; \
u1=(int)t&0xfc; \
u3&=0xfc; \
LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \
LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); }
#endif
#ifdef DES_RISC2
#define D_ENCRYPT(LL,R,S) { \
unsigned int u1,u2,s1,s2; \
LOAD_DATA(R,S,u,t,E0,E1,u1); \
u2=(int)u>>8L; \
u1=(int)u&0xfc; \
u2&=0xfc; \
t=ROTATE(t,4); \
LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
s1=(int)(u>>16L); \
s2=(int)(u>>24L); \
s1&=0xfc; \
s2&=0xfc; \
LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \
LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \
u2=(int)t>>8L; \
u1=(int)t&0xfc; \
u2&=0xfc; \
LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
s1=(int)(t>>16L); \
s2=(int)(t>>24L); \
s1&=0xfc; \
s2&=0xfc; \
LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \
LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); }
#endif
#else
#define D_ENCRYPT(LL,R,S) { \
LOAD_DATA_tmp(R,S,u,t,E0,E1); \
t=ROTATE(t,4); \
LL^= \
*(DES_LONG *)((unsigned char *)des_SP +((u )&0xfc))^ \
*(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \
*(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \
*(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \
*(DES_LONG *)((unsigned char *)des_SP+0x100+((t )&0xfc))^ \
*(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \
*(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \
*(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); }
#endif
#else /* original version */
#if defined(DES_RISC1) || defined(DES_RISC2)
#ifdef DES_RISC1
#define D_ENCRYPT(LL,R,S) {\
unsigned int u1,u2,u3; \
LOAD_DATA(R,S,u,t,E0,E1,u1); \
u>>=2L; \
t=ROTATE(t,6); \
u2=(int)u>>8L; \
u1=(int)u&0x3f; \
u2&=0x3f; \
u>>=16L; \
LL^=des_SPtrans[0][u1]; \
LL^=des_SPtrans[2][u2]; \
u3=(int)u>>8L; \
u1=(int)u&0x3f; \
u3&=0x3f; \
LL^=des_SPtrans[4][u1]; \
LL^=des_SPtrans[6][u3]; \
u2=(int)t>>8L; \
u1=(int)t&0x3f; \
u2&=0x3f; \
t>>=16L; \
LL^=des_SPtrans[1][u1]; \
LL^=des_SPtrans[3][u2]; \
u3=(int)t>>8L; \
u1=(int)t&0x3f; \
u3&=0x3f; \
LL^=des_SPtrans[5][u1]; \
LL^=des_SPtrans[7][u3]; }
#endif
#ifdef DES_RISC2
#define D_ENCRYPT(LL,R,S) {\
unsigned int u1,u2,s1,s2; \
LOAD_DATA(R,S,u,t,E0,E1,u1); \
u>>=2L; \
t=ROTATE(t,6); \
u2=(int)u>>8L; \
u1=(int)u&0x3f; \
u2&=0x3f; \
LL^=des_SPtrans[0][u1]; \
LL^=des_SPtrans[2][u2]; \
s1=(int)u>>16L; \
s2=(int)u>>24L; \
s1&=0x3f; \
s2&=0x3f; \
LL^=des_SPtrans[4][s1]; \
LL^=des_SPtrans[6][s2]; \
u2=(int)t>>8L; \
u1=(int)t&0x3f; \
u2&=0x3f; \
LL^=des_SPtrans[1][u1]; \
LL^=des_SPtrans[3][u2]; \
s1=(int)t>>16; \
s2=(int)t>>24L; \
s1&=0x3f; \
s2&=0x3f; \
LL^=des_SPtrans[5][s1]; \
LL^=des_SPtrans[7][s2]; }
#endif
#else
#define D_ENCRYPT(LL,R,S) {\
LOAD_DATA_tmp(R,S,u,t,E0,E1); \
t=ROTATE(t,4); \
LL^=\
des_SPtrans[0][(u>> 2L)&0x3f]^ \
des_SPtrans[2][(u>>10L)&0x3f]^ \
des_SPtrans[4][(u>>18L)&0x3f]^ \
des_SPtrans[6][(u>>26L)&0x3f]^ \
des_SPtrans[1][(t>> 2L)&0x3f]^ \
des_SPtrans[3][(t>>10L)&0x3f]^ \
des_SPtrans[5][(t>>18L)&0x3f]^ \
des_SPtrans[7][(t>>26L)&0x3f]; }
#endif
#endif
/* IP and FP
* The problem is more of a geometric problem that random bit fiddling.
0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
The output has been subject to swaps of the form
0 1 -> 3 1 but the odd and even bits have been put into
2 3 2 0
different words. The main trick is to remember that
t=((l>>size)^r)&(mask);
r^=t;
l^=(t<<size);
can be used to swap and move bits between words.
So l = 0 1 2 3 r = 16 17 18 19
4 5 6 7 20 21 22 23
8 9 10 11 24 25 26 27
12 13 14 15 28 29 30 31
becomes (for size == 2 and mask == 0x3333)
t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
6^20 7^21 -- -- 4 5 20 21 6 7 22 23
10^24 11^25 -- -- 8 9 24 25 10 11 24 25
14^28 15^29 -- -- 12 13 28 29 14 15 28 29
Thanks for hints from Richard Outerbridge - he told me IP&FP
could be done in 15 xor, 10 shifts and 5 ands.
When I finally started to think of the problem in 2D
I first got ~42 operations without xors. When I remembered
how to use xors :-) I got it to its final state.
*/
#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
(b)^=(t),\
(a)^=((t)<<(n)))
#define IP(l,r) \
{ \
register DES_LONG tt; \
PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
PERM_OP(l,r,tt,16,0x0000ffffL); \
PERM_OP(r,l,tt, 2,0x33333333L); \
PERM_OP(l,r,tt, 8,0x00ff00ffL); \
PERM_OP(r,l,tt, 1,0x55555555L); \
}
#define FP(l,r) \
{ \
register DES_LONG tt; \
PERM_OP(l,r,tt, 1,0x55555555L); \
PERM_OP(r,l,tt, 8,0x00ff00ffL); \
PERM_OP(l,r,tt, 2,0x33333333L); \
PERM_OP(r,l,tt,16,0x0000ffffL); \
PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
}
extern const DES_LONG des_SPtrans[8][64];
#ifndef NOPROTO
void fcrypt_body(DES_LONG *out,des_key_schedule ks,
DES_LONG Eswap0, DES_LONG Eswap1);
#else
void fcrypt_body();
#endif
#endif

View File

@@ -0,0 +1,84 @@
/* Deprecated/legacy */
/* crypto/des/ecb3_enc.c */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include "des_locl.h"
void des_ecb3_encrypt(des_cblock (*input), des_cblock (*output), des_key_schedule ks1, des_key_schedule ks2, des_key_schedule ks3, int enc)
{
register DES_LONG l0,l1;
register unsigned char *in,*out;
DES_LONG ll[2];
in=(unsigned char *)input;
out=(unsigned char *)output;
c2l(in,l0);
c2l(in,l1);
ll[0]=l0;
ll[1]=l1;
if (enc)
des_encrypt3(ll,ks1,ks2,ks3);
else
des_decrypt3(ll,ks1,ks2,ks3);
l0=ll[0];
l1=ll[1];
l2c(l0,out);
l2c(l1,out);
}

77
src/utils/crypto/podd.h Normal file
View File

@@ -0,0 +1,77 @@
/* Deprecated/legacy */
/* crypto/des/podd.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
static const unsigned char odd_parity[256]={
1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};

510
src/utils/crypto/rmd160.c Normal file
View File

@@ -0,0 +1,510 @@
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Preneel, Bosselaers, Dobbertin, "The Cryptographic Hash Function RIPEMD-160",
* RSA Laboratories, CryptoBytes, Volume 3, Number 2, Autumn 1997,
* ftp://ftp.rsasecurity.com/pub/cryptobytes/crypto3n2.pdf
*/
/* Adapted by TrueCrypt Foundation */
#include "rmd160.h"
#include "../common/endian.h"
#include <memory.h>
#define PUT_64BIT_LE(cp, value) do { \
(cp)[7] = (unsigned char)((value) >> 56); \
(cp)[6] = (unsigned char)((value) >> 48); \
(cp)[5] = (unsigned char)((value) >> 40); \
(cp)[4] = (unsigned char)((value) >> 32); \
(cp)[3] = (unsigned char)((value) >> 24); \
(cp)[2] = (unsigned char)((value) >> 16); \
(cp)[1] = (unsigned char)((value) >> 8); \
(cp)[0] = (unsigned char)(value); } while (0)
#define PUT_32BIT_LE(cp, value) do { \
(cp)[3] = (unsigned char)((value) >> 24); \
(cp)[2] = (unsigned char)((value) >> 16); \
(cp)[1] = (unsigned char)((value) >> 8); \
(cp)[0] = (unsigned char)(value); } while (0)
#define H0 0x67452301U
#define H1 0xEFCDAB89U
#define H2 0x98BADCFEU
#define H3 0x10325476U
#define H4 0xC3D2E1F0U
#define K0 0x00000000U
#define K1 0x5A827999U
#define K2 0x6ED9EBA1U
#define K3 0x8F1BBCDCU
#define K4 0xA953FD4EU
#define KK0 0x50A28BE6U
#define KK1 0x5C4DD124U
#define KK2 0x6D703EF3U
#define KK3 0x7A6D76E9U
#define KK4 0x00000000U
/* rotate x left n bits. */
#if defined (_MSC_VER) && !defined (_DEBUG)
#include <stdlib.h>
# pragma intrinsic (_lrotl)
# define ROL(n, x) (_lrotl (x, n))
#else
# define ROL(n, x) (((x) << (n)) | ((x) >> (32-(n))))
#endif
#define F0(x, y, z) ((x) ^ (y) ^ (z))
#define F1(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define F2(x, y, z) (((x) | (~y)) ^ (z))
#define F3(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define F4(x, y, z) ((x) ^ ((y) | (~z)))
#define R(a, b, c, d, e, Fj, Kj, sj, rj) \
do { \
a = ROL(sj, a + Fj(b,c,d) + X(rj) + Kj) + e; \
c = ROL(10, c); \
} while(0)
#define X(i) x[i]
#ifndef TC_MINIMIZE_CODE_SIZE
static u_char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#else
static u_char PADDING[64];
#endif
void
RMD160Init(RMD160_CTX *ctx)
{
ctx->count = 0;
ctx->state[0] = H0;
ctx->state[1] = H1;
ctx->state[2] = H2;
ctx->state[3] = H3;
ctx->state[4] = H4;
PADDING[0] = 0x80;
}
void
RMD160Update(RMD160_CTX *ctx, const u_char *input, u_int32_t len)
{
u_int32_t have, off, need;
u_char buf[64] = { 0 };
have = (uint32_t)((ctx->count/8) % 64);
need = 64 - have;
ctx->count += 8 * len;
off = 0;
if (len >= need) {
if (have) {
memcpy(ctx->buffer + have, input, (size_t) need);
RMD160Transform(ctx->state, ctx->buffer);
off = need;
have = 0;
}
/* now the buffer is empty */
while (off + 64 <= len) {
if ((len - off) < 64) {
memset(buf, 0x00, 64);
memcpy(buf, input + off, len - off);
RMD160Transform(ctx->state, buf);
} else
RMD160Transform(ctx->state, input + off);
off += 64;
}
}
if (off < len)
memcpy(ctx->buffer + have, input+off, (size_t) (len-off));
}
void RMD160Final(u_char digest[20], RMD160_CTX *ctx)
{
int i;
u_char size[8];
u_int32_t padlen;
#ifndef TC_NO_COMPILER_INT64
PUT_64BIT_LE(size, ctx->count);
#else
*(uint32_t *) (size + 4) = 0;
PUT_32BIT_LE(size, ctx->count);
#endif
/*
* pad to 64 byte blocks, at least one byte from PADDING plus 8 bytes
* for the size
*/
padlen = (uint32_t)(64 - ((ctx->count/8) % 64));
if (padlen < 1 + 8)
padlen += 64;
RMD160Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */
RMD160Update(ctx, size, 8);
if (digest != 0)
for (i = 0; i < 5; i++)
PUT_32BIT_LE(digest + i*4, ctx->state[i]);
memset(ctx, 0, sizeof (*ctx));
}
#ifndef TC_MINIMIZE_CODE_SIZE
void
RMD160Transform(u_int32_t state[5], const u_char block[64])
{
u_int32_t a, b, c, d, e, aa, bb, cc, dd, ee, t, x[16];
#if BYTE_ORDER == LITTLE_ENDIAN
memcpy(x, block, 64);
#else
int i;
for (i = 0; i < 16; i++)
x[i] = (u_int32_t)(
(u_int32_t)(block[i*4 + 0]) |
(u_int32_t)(block[i*4 + 1]) << 8 |
(u_int32_t)(block[i*4 + 2]) << 16 |
(u_int32_t)(block[i*4 + 3]) << 24);
#endif
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
/* Round 1 */
R(a, b, c, d, e, F0, K0, 11, 0);
R(e, a, b, c, d, F0, K0, 14, 1);
R(d, e, a, b, c, F0, K0, 15, 2);
R(c, d, e, a, b, F0, K0, 12, 3);
R(b, c, d, e, a, F0, K0, 5, 4);
R(a, b, c, d, e, F0, K0, 8, 5);
R(e, a, b, c, d, F0, K0, 7, 6);
R(d, e, a, b, c, F0, K0, 9, 7);
R(c, d, e, a, b, F0, K0, 11, 8);
R(b, c, d, e, a, F0, K0, 13, 9);
R(a, b, c, d, e, F0, K0, 14, 10);
R(e, a, b, c, d, F0, K0, 15, 11);
R(d, e, a, b, c, F0, K0, 6, 12);
R(c, d, e, a, b, F0, K0, 7, 13);
R(b, c, d, e, a, F0, K0, 9, 14);
R(a, b, c, d, e, F0, K0, 8, 15); /* #15 */
/* Round 2 */
R(e, a, b, c, d, F1, K1, 7, 7);
R(d, e, a, b, c, F1, K1, 6, 4);
R(c, d, e, a, b, F1, K1, 8, 13);
R(b, c, d, e, a, F1, K1, 13, 1);
R(a, b, c, d, e, F1, K1, 11, 10);
R(e, a, b, c, d, F1, K1, 9, 6);
R(d, e, a, b, c, F1, K1, 7, 15);
R(c, d, e, a, b, F1, K1, 15, 3);
R(b, c, d, e, a, F1, K1, 7, 12);
R(a, b, c, d, e, F1, K1, 12, 0);
R(e, a, b, c, d, F1, K1, 15, 9);
R(d, e, a, b, c, F1, K1, 9, 5);
R(c, d, e, a, b, F1, K1, 11, 2);
R(b, c, d, e, a, F1, K1, 7, 14);
R(a, b, c, d, e, F1, K1, 13, 11);
R(e, a, b, c, d, F1, K1, 12, 8); /* #31 */
/* Round 3 */
R(d, e, a, b, c, F2, K2, 11, 3);
R(c, d, e, a, b, F2, K2, 13, 10);
R(b, c, d, e, a, F2, K2, 6, 14);
R(a, b, c, d, e, F2, K2, 7, 4);
R(e, a, b, c, d, F2, K2, 14, 9);
R(d, e, a, b, c, F2, K2, 9, 15);
R(c, d, e, a, b, F2, K2, 13, 8);
R(b, c, d, e, a, F2, K2, 15, 1);
R(a, b, c, d, e, F2, K2, 14, 2);
R(e, a, b, c, d, F2, K2, 8, 7);
R(d, e, a, b, c, F2, K2, 13, 0);
R(c, d, e, a, b, F2, K2, 6, 6);
R(b, c, d, e, a, F2, K2, 5, 13);
R(a, b, c, d, e, F2, K2, 12, 11);
R(e, a, b, c, d, F2, K2, 7, 5);
R(d, e, a, b, c, F2, K2, 5, 12); /* #47 */
/* Round 4 */
R(c, d, e, a, b, F3, K3, 11, 1);
R(b, c, d, e, a, F3, K3, 12, 9);
R(a, b, c, d, e, F3, K3, 14, 11);
R(e, a, b, c, d, F3, K3, 15, 10);
R(d, e, a, b, c, F3, K3, 14, 0);
R(c, d, e, a, b, F3, K3, 15, 8);
R(b, c, d, e, a, F3, K3, 9, 12);
R(a, b, c, d, e, F3, K3, 8, 4);
R(e, a, b, c, d, F3, K3, 9, 13);
R(d, e, a, b, c, F3, K3, 14, 3);
R(c, d, e, a, b, F3, K3, 5, 7);
R(b, c, d, e, a, F3, K3, 6, 15);
R(a, b, c, d, e, F3, K3, 8, 14);
R(e, a, b, c, d, F3, K3, 6, 5);
R(d, e, a, b, c, F3, K3, 5, 6);
R(c, d, e, a, b, F3, K3, 12, 2); /* #63 */
/* Round 5 */
R(b, c, d, e, a, F4, K4, 9, 4);
R(a, b, c, d, e, F4, K4, 15, 0);
R(e, a, b, c, d, F4, K4, 5, 5);
R(d, e, a, b, c, F4, K4, 11, 9);
R(c, d, e, a, b, F4, K4, 6, 7);
R(b, c, d, e, a, F4, K4, 8, 12);
R(a, b, c, d, e, F4, K4, 13, 2);
R(e, a, b, c, d, F4, K4, 12, 10);
R(d, e, a, b, c, F4, K4, 5, 14);
R(c, d, e, a, b, F4, K4, 12, 1);
R(b, c, d, e, a, F4, K4, 13, 3);
R(a, b, c, d, e, F4, K4, 14, 8);
R(e, a, b, c, d, F4, K4, 11, 11);
R(d, e, a, b, c, F4, K4, 8, 6);
R(c, d, e, a, b, F4, K4, 5, 15);
R(b, c, d, e, a, F4, K4, 6, 13); /* #79 */
aa = a ; bb = b; cc = c; dd = d; ee = e;
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
/* Parallel round 1 */
R(a, b, c, d, e, F4, KK0, 8, 5);
R(e, a, b, c, d, F4, KK0, 9, 14);
R(d, e, a, b, c, F4, KK0, 9, 7);
R(c, d, e, a, b, F4, KK0, 11, 0);
R(b, c, d, e, a, F4, KK0, 13, 9);
R(a, b, c, d, e, F4, KK0, 15, 2);
R(e, a, b, c, d, F4, KK0, 15, 11);
R(d, e, a, b, c, F4, KK0, 5, 4);
R(c, d, e, a, b, F4, KK0, 7, 13);
R(b, c, d, e, a, F4, KK0, 7, 6);
R(a, b, c, d, e, F4, KK0, 8, 15);
R(e, a, b, c, d, F4, KK0, 11, 8);
R(d, e, a, b, c, F4, KK0, 14, 1);
R(c, d, e, a, b, F4, KK0, 14, 10);
R(b, c, d, e, a, F4, KK0, 12, 3);
R(a, b, c, d, e, F4, KK0, 6, 12); /* #15 */
/* Parallel round 2 */
R(e, a, b, c, d, F3, KK1, 9, 6);
R(d, e, a, b, c, F3, KK1, 13, 11);
R(c, d, e, a, b, F3, KK1, 15, 3);
R(b, c, d, e, a, F3, KK1, 7, 7);
R(a, b, c, d, e, F3, KK1, 12, 0);
R(e, a, b, c, d, F3, KK1, 8, 13);
R(d, e, a, b, c, F3, KK1, 9, 5);
R(c, d, e, a, b, F3, KK1, 11, 10);
R(b, c, d, e, a, F3, KK1, 7, 14);
R(a, b, c, d, e, F3, KK1, 7, 15);
R(e, a, b, c, d, F3, KK1, 12, 8);
R(d, e, a, b, c, F3, KK1, 7, 12);
R(c, d, e, a, b, F3, KK1, 6, 4);
R(b, c, d, e, a, F3, KK1, 15, 9);
R(a, b, c, d, e, F3, KK1, 13, 1);
R(e, a, b, c, d, F3, KK1, 11, 2); /* #31 */
/* Parallel round 3 */
R(d, e, a, b, c, F2, KK2, 9, 15);
R(c, d, e, a, b, F2, KK2, 7, 5);
R(b, c, d, e, a, F2, KK2, 15, 1);
R(a, b, c, d, e, F2, KK2, 11, 3);
R(e, a, b, c, d, F2, KK2, 8, 7);
R(d, e, a, b, c, F2, KK2, 6, 14);
R(c, d, e, a, b, F2, KK2, 6, 6);
R(b, c, d, e, a, F2, KK2, 14, 9);
R(a, b, c, d, e, F2, KK2, 12, 11);
R(e, a, b, c, d, F2, KK2, 13, 8);
R(d, e, a, b, c, F2, KK2, 5, 12);
R(c, d, e, a, b, F2, KK2, 14, 2);
R(b, c, d, e, a, F2, KK2, 13, 10);
R(a, b, c, d, e, F2, KK2, 13, 0);
R(e, a, b, c, d, F2, KK2, 7, 4);
R(d, e, a, b, c, F2, KK2, 5, 13); /* #47 */
/* Parallel round 4 */
R(c, d, e, a, b, F1, KK3, 15, 8);
R(b, c, d, e, a, F1, KK3, 5, 6);
R(a, b, c, d, e, F1, KK3, 8, 4);
R(e, a, b, c, d, F1, KK3, 11, 1);
R(d, e, a, b, c, F1, KK3, 14, 3);
R(c, d, e, a, b, F1, KK3, 14, 11);
R(b, c, d, e, a, F1, KK3, 6, 15);
R(a, b, c, d, e, F1, KK3, 14, 0);
R(e, a, b, c, d, F1, KK3, 6, 5);
R(d, e, a, b, c, F1, KK3, 9, 12);
R(c, d, e, a, b, F1, KK3, 12, 2);
R(b, c, d, e, a, F1, KK3, 9, 13);
R(a, b, c, d, e, F1, KK3, 12, 9);
R(e, a, b, c, d, F1, KK3, 5, 7);
R(d, e, a, b, c, F1, KK3, 15, 10);
R(c, d, e, a, b, F1, KK3, 8, 14); /* #63 */
/* Parallel round 5 */
R(b, c, d, e, a, F0, KK4, 8, 12);
R(a, b, c, d, e, F0, KK4, 5, 15);
R(e, a, b, c, d, F0, KK4, 12, 10);
R(d, e, a, b, c, F0, KK4, 9, 4);
R(c, d, e, a, b, F0, KK4, 12, 1);
R(b, c, d, e, a, F0, KK4, 5, 5);
R(a, b, c, d, e, F0, KK4, 14, 8);
R(e, a, b, c, d, F0, KK4, 6, 7);
R(d, e, a, b, c, F0, KK4, 8, 6);
R(c, d, e, a, b, F0, KK4, 13, 2);
R(b, c, d, e, a, F0, KK4, 6, 13);
R(a, b, c, d, e, F0, KK4, 5, 14);
R(e, a, b, c, d, F0, KK4, 15, 0);
R(d, e, a, b, c, F0, KK4, 13, 3);
R(c, d, e, a, b, F0, KK4, 11, 9);
R(b, c, d, e, a, F0, KK4, 11, 11); /* #79 */
t = state[1] + cc + d;
state[1] = state[2] + dd + e;
state[2] = state[3] + ee + a;
state[3] = state[4] + aa + b;
state[4] = state[0] + bb + c;
state[0] = t;
}
#else // TC_MINIMIZE_CODE_SIZE
/*
Copyright (c) 2008 TrueCrypt Foundation. All rights reserved.
Governed by the TrueCrypt License 2.4 the full text of which is contained
in the file License.txt included in TrueCrypt binary and source code
distribution packages.
*/
#pragma optimize ("tl", on)
typedef uint32_t uint32;
typedef unsigned __int8 byte;
static const byte OrderTab[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13,
5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
};
static const byte RolTab[] = {
11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6,
8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
};
static const uint32 KTab[] = {
0x00000000UL,
0x5A827999UL,
0x6ED9EBA1UL,
0x8F1BBCDCUL,
0xA953FD4EUL,
0x50A28BE6UL,
0x5C4DD124UL,
0x6D703EF3UL,
0x7A6D76E9UL,
0x00000000UL
};
void RMD160Transform (u_int32_t state[5], const u_char block[64])
{
uint32 a, b, c, d, e;
uint32 a2, b2, c2, d2, e2;
uint32 *data = (uint32 *) block;
byte pos;
uint32 tmp;
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
for (pos = 0; pos < 160; ++pos)
{
tmp = a + data[OrderTab[pos]] + KTab[pos >> 4];
switch (pos >> 4)
{
case 0: case 9: tmp += F0 (b, c, d); break;
case 1: case 8: tmp += F1 (b, c, d); break;
case 2: case 7: tmp += F2 (b, c, d); break;
case 3: case 6: tmp += F3 (b, c, d); break;
case 4: case 5: tmp += F4 (b, c, d); break;
}
tmp = ROL (RolTab[pos], tmp) + e;
a = e;
e = d;
d = ROL (10, c);
c = b;
b = tmp;
if (pos == 79)
{
a2 = a;
b2 = b;
c2 = c;
d2 = d;
e2 = e;
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
}
}
tmp = state[1] + c2 + d;
state[1] = state[2] + d2 + e;
state[2] = state[3] + e2 + a;
state[3] = state[4] + a2 + b;
state[4] = state[0] + b2 + c;
state[0] = tmp;
}
#endif // TC_MINIMIZE_CODE_SIZE

63
src/utils/crypto/rmd160.h Normal file
View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Adapted by TrueCrypt Foundation */
#ifndef _RMD160_H
#define _RMD160_H
#include <inttypes.h>
#if defined(__cplusplus)
extern "C"
{
#endif
#ifndef u_int32_t
#define u_int32_t uint32_t
#define u_int64_t uint64_t
#define u_char uint8_t
#endif
/* RMD160 context. */
typedef struct RMD160Context {
u_int32_t state[5]; /* state */
#ifndef TC_NO_COMPILER_INT64
u_int64_t count; /* number of bits, modulo 2^64 */
#else
u_int32_t count;
#endif
u_char buffer[64]; /* input buffer */
} RMD160_CTX;
void RMD160Init(RMD160_CTX *);
void RMD160Transform(u_int32_t [5], const u_char [64]);
void RMD160Update(RMD160_CTX *, const u_char *, u_int32_t);
void RMD160Final(u_char [20], RMD160_CTX *);
#if defined(__cplusplus)
}
#endif
#endif /* _RMD160_H */

940
src/utils/crypto/serpent.c Normal file
View File

@@ -0,0 +1,940 @@
// serpent.cpp - written and placed in the public domain by Wei Dai
/* Adapted for TrueCrypt by the TrueCrypt Foundation */
#include "serpent.h"
#include "../common/endian.h"
#include <memory.h>
#if defined(_WIN32) && !defined(_DEBUG)
#include <stdlib.h>
#define rotlFixed _rotl
#define rotrFixed _rotr
#else
#define rotlFixed(x,n) (((x) << (n)) | ((x) >> (32 - (n))))
#define rotrFixed(x,n) (((x) >> (n)) | ((x) << (32 - (n))))
#endif
// linear transformation
#define LT(i,a,b,c,d,e) {\
a = rotlFixed(a, 13); \
c = rotlFixed(c, 3); \
d = rotlFixed(d ^ c ^ (a << 3), 7); \
b = rotlFixed(b ^ a ^ c, 1); \
a = rotlFixed(a ^ b ^ d, 5); \
c = rotlFixed(c ^ d ^ (b << 7), 22);}
// inverse linear transformation
#define ILT(i,a,b,c,d,e) {\
c = rotrFixed(c, 22); \
a = rotrFixed(a, 5); \
c ^= d ^ (b << 7); \
a ^= b ^ d; \
b = rotrFixed(b, 1); \
d = rotrFixed(d, 7) ^ c ^ (a << 3); \
b ^= a ^ c; \
c = rotrFixed(c, 3); \
a = rotrFixed(a, 13);}
// order of output from S-box functions
#define beforeS0(f) f(0,a,b,c,d,e)
#define afterS0(f) f(1,b,e,c,a,d)
#define afterS1(f) f(2,c,b,a,e,d)
#define afterS2(f) f(3,a,e,b,d,c)
#define afterS3(f) f(4,e,b,d,c,a)
#define afterS4(f) f(5,b,a,e,c,d)
#define afterS5(f) f(6,a,c,b,e,d)
#define afterS6(f) f(7,a,c,d,b,e)
#define afterS7(f) f(8,d,e,b,a,c)
// order of output from inverse S-box functions
#define beforeI7(f) f(8,a,b,c,d,e)
#define afterI7(f) f(7,d,a,b,e,c)
#define afterI6(f) f(6,a,b,c,e,d)
#define afterI5(f) f(5,b,d,e,c,a)
#define afterI4(f) f(4,b,c,e,a,d)
#define afterI3(f) f(3,a,b,e,c,d)
#define afterI2(f) f(2,b,d,e,c,a)
#define afterI1(f) f(1,a,b,c,e,d)
#define afterI0(f) f(0,a,d,b,e,c)
// The instruction sequences for the S-box functions
// come from Dag Arne Osvik's paper "Speeding up Serpent".
#define S0(i, r0, r1, r2, r3, r4) \
{ \
r3 ^= r0; \
r4 = r1; \
r1 &= r3; \
r4 ^= r2; \
r1 ^= r0; \
r0 |= r3; \
r0 ^= r4; \
r4 ^= r3; \
r3 ^= r2; \
r2 |= r1; \
r2 ^= r4; \
r4 = ~r4; \
r4 |= r1; \
r1 ^= r3; \
r1 ^= r4; \
r3 |= r0; \
r1 ^= r3; \
r4 ^= r3; \
}
#define I0(i, r0, r1, r2, r3, r4) \
{ \
r2 = ~r2; \
r4 = r1; \
r1 |= r0; \
r4 = ~r4; \
r1 ^= r2; \
r2 |= r4; \
r1 ^= r3; \
r0 ^= r4; \
r2 ^= r0; \
r0 &= r3; \
r4 ^= r0; \
r0 |= r1; \
r0 ^= r2; \
r3 ^= r4; \
r2 ^= r1; \
r3 ^= r0; \
r3 ^= r1; \
r2 &= r3; \
r4 ^= r2; \
}
#define S1(i, r0, r1, r2, r3, r4) \
{ \
r0 = ~r0; \
r2 = ~r2; \
r4 = r0; \
r0 &= r1; \
r2 ^= r0; \
r0 |= r3; \
r3 ^= r2; \
r1 ^= r0; \
r0 ^= r4; \
r4 |= r1; \
r1 ^= r3; \
r2 |= r0; \
r2 &= r4; \
r0 ^= r1; \
r1 &= r2; \
r1 ^= r0; \
r0 &= r2; \
r0 ^= r4; \
}
#define I1(i, r0, r1, r2, r3, r4) \
{ \
r4 = r1; \
r1 ^= r3; \
r3 &= r1; \
r4 ^= r2; \
r3 ^= r0; \
r0 |= r1; \
r2 ^= r3; \
r0 ^= r4; \
r0 |= r2; \
r1 ^= r3; \
r0 ^= r1; \
r1 |= r3; \
r1 ^= r0; \
r4 = ~r4; \
r4 ^= r1; \
r1 |= r0; \
r1 ^= r0; \
r1 |= r4; \
r3 ^= r1; \
}
#define S2(i, r0, r1, r2, r3, r4) \
{ \
r4 = r0; \
r0 &= r2; \
r0 ^= r3; \
r2 ^= r1; \
r2 ^= r0; \
r3 |= r4; \
r3 ^= r1; \
r4 ^= r2; \
r1 = r3; \
r3 |= r4; \
r3 ^= r0; \
r0 &= r1; \
r4 ^= r0; \
r1 ^= r3; \
r1 ^= r4; \
r4 = ~r4; \
}
#define I2(i, r0, r1, r2, r3, r4) \
{ \
r2 ^= r3; \
r3 ^= r0; \
r4 = r3; \
r3 &= r2; \
r3 ^= r1; \
r1 |= r2; \
r1 ^= r4; \
r4 &= r3; \
r2 ^= r3; \
r4 &= r0; \
r4 ^= r2; \
r2 &= r1; \
r2 |= r0; \
r3 = ~r3; \
r2 ^= r3; \
r0 ^= r3; \
r0 &= r1; \
r3 ^= r4; \
r3 ^= r0; \
}
#define S3(i, r0, r1, r2, r3, r4) \
{ \
r4 = r0; \
r0 |= r3; \
r3 ^= r1; \
r1 &= r4; \
r4 ^= r2; \
r2 ^= r3; \
r3 &= r0; \
r4 |= r1; \
r3 ^= r4; \
r0 ^= r1; \
r4 &= r0; \
r1 ^= r3; \
r4 ^= r2; \
r1 |= r0; \
r1 ^= r2; \
r0 ^= r3; \
r2 = r1; \
r1 |= r3; \
r1 ^= r0; \
}
#define I3(i, r0, r1, r2, r3, r4) \
{ \
r4 = r2; \
r2 ^= r1; \
r1 &= r2; \
r1 ^= r0; \
r0 &= r4; \
r4 ^= r3; \
r3 |= r1; \
r3 ^= r2; \
r0 ^= r4; \
r2 ^= r0; \
r0 |= r3; \
r0 ^= r1; \
r4 ^= r2; \
r2 &= r3; \
r1 |= r3; \
r1 ^= r2; \
r4 ^= r0; \
r2 ^= r4; \
}
#define S4(i, r0, r1, r2, r3, r4) \
{ \
r1 ^= r3; \
r3 = ~r3; \
r2 ^= r3; \
r3 ^= r0; \
r4 = r1; \
r1 &= r3; \
r1 ^= r2; \
r4 ^= r3; \
r0 ^= r4; \
r2 &= r4; \
r2 ^= r0; \
r0 &= r1; \
r3 ^= r0; \
r4 |= r1; \
r4 ^= r0; \
r0 |= r3; \
r0 ^= r2; \
r2 &= r3; \
r0 = ~r0; \
r4 ^= r2; \
}
#define I4(i, r0, r1, r2, r3, r4) \
{ \
r4 = r2; \
r2 &= r3; \
r2 ^= r1; \
r1 |= r3; \
r1 &= r0; \
r4 ^= r2; \
r4 ^= r1; \
r1 &= r2; \
r0 = ~r0; \
r3 ^= r4; \
r1 ^= r3; \
r3 &= r0; \
r3 ^= r2; \
r0 ^= r1; \
r2 &= r0; \
r3 ^= r0; \
r2 ^= r4; \
r2 |= r3; \
r3 ^= r0; \
r2 ^= r1; \
}
#define S5(i, r0, r1, r2, r3, r4) \
{ \
r0 ^= r1; \
r1 ^= r3; \
r3 = ~r3; \
r4 = r1; \
r1 &= r0; \
r2 ^= r3; \
r1 ^= r2; \
r2 |= r4; \
r4 ^= r3; \
r3 &= r1; \
r3 ^= r0; \
r4 ^= r1; \
r4 ^= r2; \
r2 ^= r0; \
r0 &= r3; \
r2 = ~r2; \
r0 ^= r4; \
r4 |= r3; \
r2 ^= r4; \
}
#define I5(i, r0, r1, r2, r3, r4) \
{ \
r1 = ~r1; \
r4 = r3; \
r2 ^= r1; \
r3 |= r0; \
r3 ^= r2; \
r2 |= r1; \
r2 &= r0; \
r4 ^= r3; \
r2 ^= r4; \
r4 |= r0; \
r4 ^= r1; \
r1 &= r2; \
r1 ^= r3; \
r4 ^= r2; \
r3 &= r4; \
r4 ^= r1; \
r3 ^= r0; \
r3 ^= r4; \
r4 = ~r4; \
}
#define S6(i, r0, r1, r2, r3, r4) \
{ \
r2 = ~r2; \
r4 = r3; \
r3 &= r0; \
r0 ^= r4; \
r3 ^= r2; \
r2 |= r4; \
r1 ^= r3; \
r2 ^= r0; \
r0 |= r1; \
r2 ^= r1; \
r4 ^= r0; \
r0 |= r3; \
r0 ^= r2; \
r4 ^= r3; \
r4 ^= r0; \
r3 = ~r3; \
r2 &= r4; \
r2 ^= r3; \
}
#define I6(i, r0, r1, r2, r3, r4) \
{ \
r0 ^= r2; \
r4 = r2; \
r2 &= r0; \
r4 ^= r3; \
r2 = ~r2; \
r3 ^= r1; \
r2 ^= r3; \
r4 |= r0; \
r0 ^= r2; \
r3 ^= r4; \
r4 ^= r1; \
r1 &= r3; \
r1 ^= r0; \
r0 ^= r3; \
r0 |= r2; \
r3 ^= r1; \
r4 ^= r0; \
}
#define S7(i, r0, r1, r2, r3, r4) \
{ \
r4 = r2; \
r2 &= r1; \
r2 ^= r3; \
r3 &= r1; \
r4 ^= r2; \
r2 ^= r1; \
r1 ^= r0; \
r0 |= r4; \
r0 ^= r2; \
r3 ^= r1; \
r2 ^= r3; \
r3 &= r0; \
r3 ^= r4; \
r4 ^= r2; \
r2 &= r0; \
r4 = ~r4; \
r2 ^= r4; \
r4 &= r0; \
r1 ^= r3; \
r4 ^= r1; \
}
#define I7(i, r0, r1, r2, r3, r4) \
{ \
r4 = r2; \
r2 ^= r0; \
r0 &= r3; \
r2 = ~r2; \
r4 |= r3; \
r3 ^= r1; \
r1 |= r0; \
r0 ^= r2; \
r2 &= r4; \
r1 ^= r2; \
r2 ^= r0; \
r0 |= r2; \
r3 &= r4; \
r0 ^= r3; \
r4 ^= r1; \
r3 ^= r4; \
r4 |= r0; \
r3 ^= r2; \
r4 ^= r2; \
}
// key xor
#define KX(r, a, b, c, d, e) {\
a ^= k[4 * r + 0]; \
b ^= k[4 * r + 1]; \
c ^= k[4 * r + 2]; \
d ^= k[4 * r + 3];}
#ifdef TC_MINIMIZE_CODE_SIZE
static void S0f (uint32_t *r0, uint32_t *r1, uint32_t *r2, uint32_t *r3, uint32_t *r4)
{
*r3 ^= *r0;
*r4 = *r1;
*r1 &= *r3;
*r4 ^= *r2;
*r1 ^= *r0;
*r0 |= *r3;
*r0 ^= *r4;
*r4 ^= *r3;
*r3 ^= *r2;
*r2 |= *r1;
*r2 ^= *r4;
*r4 = ~*r4;
*r4 |= *r1;
*r1 ^= *r3;
*r1 ^= *r4;
*r3 |= *r0;
*r1 ^= *r3;
*r4 ^= *r3;
}
static void S1f (uint32_t *r0, uint32_t *r1, uint32_t *r2, uint32_t *r3, uint32_t *r4)
{
*r0 = ~*r0;
*r2 = ~*r2;
*r4 = *r0;
*r0 &= *r1;
*r2 ^= *r0;
*r0 |= *r3;
*r3 ^= *r2;
*r1 ^= *r0;
*r0 ^= *r4;
*r4 |= *r1;
*r1 ^= *r3;
*r2 |= *r0;
*r2 &= *r4;
*r0 ^= *r1;
*r1 &= *r2;
*r1 ^= *r0;
*r0 &= *r2;
*r0 ^= *r4;
}
static void S2f (uint32_t *r0, uint32_t *r1, uint32_t *r2, uint32_t *r3, uint32_t *r4)
{
*r4 = *r0;
*r0 &= *r2;
*r0 ^= *r3;
*r2 ^= *r1;
*r2 ^= *r0;
*r3 |= *r4;
*r3 ^= *r1;
*r4 ^= *r2;
*r1 = *r3;
*r3 |= *r4;
*r3 ^= *r0;
*r0 &= *r1;
*r4 ^= *r0;
*r1 ^= *r3;
*r1 ^= *r4;
*r4 = ~*r4;
}
static void S3f (uint32_t *r0, uint32_t *r1, uint32_t *r2, uint32_t *r3, uint32_t *r4)
{
*r4 = *r0;
*r0 |= *r3;
*r3 ^= *r1;
*r1 &= *r4;
*r4 ^= *r2;
*r2 ^= *r3;
*r3 &= *r0;
*r4 |= *r1;
*r3 ^= *r4;
*r0 ^= *r1;
*r4 &= *r0;
*r1 ^= *r3;
*r4 ^= *r2;
*r1 |= *r0;
*r1 ^= *r2;
*r0 ^= *r3;
*r2 = *r1;
*r1 |= *r3;
*r1 ^= *r0;
}
static void S4f (uint32_t *r0, uint32_t *r1, uint32_t *r2, uint32_t *r3, uint32_t *r4)
{
*r1 ^= *r3;
*r3 = ~*r3;
*r2 ^= *r3;
*r3 ^= *r0;
*r4 = *r1;
*r1 &= *r3;
*r1 ^= *r2;
*r4 ^= *r3;
*r0 ^= *r4;
*r2 &= *r4;
*r2 ^= *r0;
*r0 &= *r1;
*r3 ^= *r0;
*r4 |= *r1;
*r4 ^= *r0;
*r0 |= *r3;
*r0 ^= *r2;
*r2 &= *r3;
*r0 = ~*r0;
*r4 ^= *r2;
}
static void S5f (uint32_t *r0, uint32_t *r1, uint32_t *r2, uint32_t *r3, uint32_t *r4)
{
*r0 ^= *r1;
*r1 ^= *r3;
*r3 = ~*r3;
*r4 = *r1;
*r1 &= *r0;
*r2 ^= *r3;
*r1 ^= *r2;
*r2 |= *r4;
*r4 ^= *r3;
*r3 &= *r1;
*r3 ^= *r0;
*r4 ^= *r1;
*r4 ^= *r2;
*r2 ^= *r0;
*r0 &= *r3;
*r2 = ~*r2;
*r0 ^= *r4;
*r4 |= *r3;
*r2 ^= *r4;
}
static void S6f (uint32_t *r0, uint32_t *r1, uint32_t *r2, uint32_t *r3, uint32_t *r4)
{
*r2 = ~*r2;
*r4 = *r3;
*r3 &= *r0;
*r0 ^= *r4;
*r3 ^= *r2;
*r2 |= *r4;
*r1 ^= *r3;
*r2 ^= *r0;
*r0 |= *r1;
*r2 ^= *r1;
*r4 ^= *r0;
*r0 |= *r3;
*r0 ^= *r2;
*r4 ^= *r3;
*r4 ^= *r0;
*r3 = ~*r3;
*r2 &= *r4;
*r2 ^= *r3;
}
static void S7f (uint32_t *r0, uint32_t *r1, uint32_t *r2, uint32_t *r3, uint32_t *r4)
{
*r4 = *r2;
*r2 &= *r1;
*r2 ^= *r3;
*r3 &= *r1;
*r4 ^= *r2;
*r2 ^= *r1;
*r1 ^= *r0;
*r0 |= *r4;
*r0 ^= *r2;
*r3 ^= *r1;
*r2 ^= *r3;
*r3 &= *r0;
*r3 ^= *r4;
*r4 ^= *r2;
*r2 &= *r0;
*r4 = ~*r4;
*r2 ^= *r4;
*r4 &= *r0;
*r1 ^= *r3;
*r4 ^= *r1;
}
static void KXf (const uint32_t *k, unsigned int r, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d)
{
*a ^= k[r];
*b ^= k[r + 1];
*c ^= k[r + 2];
*d ^= k[r + 3];
}
#endif // TC_MINIMIZE_CODE_SIZE
#ifndef TC_MINIMIZE_CODE_SIZE
void serpent_set_key(const uint8_t userKey[], int keylen, uint8_t *ks)
{
uint32_t a,b,c,d,e;
uint32_t *k = (uint32_t *)ks;
uint32_t t;
int i;
for (i = 0; i < keylen / (int)sizeof(int32_t); i++)
k[i] = LE32(((uint32_t*)userKey)[i]);
if (keylen < 32)
k[keylen/4] |= (uint32_t)1 << ((keylen%4)*8);
k += 8;
t = k[-1];
for (i = 0; i < 132; ++i)
k[i] = t = rotlFixed(k[i-8] ^ k[i-5] ^ k[i-3] ^ t ^ 0x9e3779b9 ^ i, 11);
k -= 20;
#define LK(r, a, b, c, d, e) {\
a = k[(8-r)*4 + 0]; \
b = k[(8-r)*4 + 1]; \
c = k[(8-r)*4 + 2]; \
d = k[(8-r)*4 + 3];}
#define SK(r, a, b, c, d, e) {\
k[(8-r)*4 + 4] = a; \
k[(8-r)*4 + 5] = b; \
k[(8-r)*4 + 6] = c; \
k[(8-r)*4 + 7] = d;} \
for (i=0; i<4; i++)
{
afterS2(LK); afterS2(S3); afterS3(SK);
afterS1(LK); afterS1(S2); afterS2(SK);
afterS0(LK); afterS0(S1); afterS1(SK);
beforeS0(LK); beforeS0(S0); afterS0(SK);
k += 8*4;
afterS6(LK); afterS6(S7); afterS7(SK);
afterS5(LK); afterS5(S6); afterS6(SK);
afterS4(LK); afterS4(S5); afterS5(SK);
afterS3(LK); afterS3(S4); afterS4(SK);
}
afterS2(LK); afterS2(S3); afterS3(SK);
}
#else // TC_MINIMIZE_CODE_SIZE
static void LKf (uint32_t *k, unsigned int r, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d)
{
*a = k[r];
*b = k[r + 1];
*c = k[r + 2];
*d = k[r + 3];
}
static void SKf (uint32_t *k, unsigned int r, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d)
{
k[r + 4] = *a;
k[r + 5] = *b;
k[r + 6] = *c;
k[r + 7] = *d;
}
void serpent_set_key(const uint8_t userKey[], int keylen, uint8_t *ks)
{
uint32_t a,b,c,d,e;
uint32_t *k = (uint32_t *)ks;
uint32_t t;
int i;
for (i = 0; i < keylen / (int)sizeof(__int32); i++)
k[i] = LE32(((uint32_t*)userKey)[i]);
if (keylen < 32)
k[keylen/4] |= (uint32_t)1 << ((keylen%4)*8);
k += 8;
t = k[-1];
for (i = 0; i < 132; ++i)
k[i] = t = rotlFixed(k[i-8] ^ k[i-5] ^ k[i-3] ^ t ^ 0x9e3779b9 ^ i, 11);
k -= 20;
for (i=0; i<4; i++)
{
LKf (k, 20, &a, &e, &b, &d); S3f (&a, &e, &b, &d, &c); SKf (k, 16, &e, &b, &d, &c);
LKf (k, 24, &c, &b, &a, &e); S2f (&c, &b, &a, &e, &d); SKf (k, 20, &a, &e, &b, &d);
LKf (k, 28, &b, &e, &c, &a); S1f (&b, &e, &c, &a, &d); SKf (k, 24, &c, &b, &a, &e);
LKf (k, 32, &a, &b, &c, &d); S0f (&a, &b, &c, &d, &e); SKf (k, 28, &b, &e, &c, &a);
k += 8*4;
LKf (k, 4, &a, &c, &d, &b); S7f (&a, &c, &d, &b, &e); SKf (k, 0, &d, &e, &b, &a);
LKf (k, 8, &a, &c, &b, &e); S6f (&a, &c, &b, &e, &d); SKf (k, 4, &a, &c, &d, &b);
LKf (k, 12, &b, &a, &e, &c); S5f (&b, &a, &e, &c, &d); SKf (k, 8, &a, &c, &b, &e);
LKf (k, 16, &e, &b, &d, &c); S4f (&e, &b, &d, &c, &a); SKf (k, 12, &b, &a, &e, &c);
}
LKf (k, 20, &a, &e, &b, &d); S3f (&a, &e, &b, &d, &c); SKf (k, 16, &e, &b, &d, &c);
}
#endif // TC_MINIMIZE_CODE_SIZE
#ifndef TC_MINIMIZE_CODE_SIZE
void serpent_encrypt(const uint8_t *inBlock, uint8_t *outBlock, uint8_t *ks)
{
uint32_t a, b, c, d, e;
unsigned int i=1;
const uint32_t *k = (uint32_t *)ks + 8;
uint32_t *in = (uint32_t *) inBlock;
uint32_t *out = (uint32_t *) outBlock;
a = LE32(in[0]);
b = LE32(in[1]);
c = LE32(in[2]);
d = LE32(in[3]);
do
{
beforeS0(KX); beforeS0(S0); afterS0(LT);
afterS0(KX); afterS0(S1); afterS1(LT);
afterS1(KX); afterS1(S2); afterS2(LT);
afterS2(KX); afterS2(S3); afterS3(LT);
afterS3(KX); afterS3(S4); afterS4(LT);
afterS4(KX); afterS4(S5); afterS5(LT);
afterS5(KX); afterS5(S6); afterS6(LT);
afterS6(KX); afterS6(S7);
if (i == 4)
break;
++i;
c = b;
b = e;
e = d;
d = a;
a = e;
k += 32;
beforeS0(LT);
}
while (1);
afterS7(KX);
out[0] = LE32(d);
out[1] = LE32(e);
out[2] = LE32(b);
out[3] = LE32(a);
}
#else // TC_MINIMIZE_CODE_SIZE
typedef uint32_t uint32;
static void LTf (uint32 *a, uint32 *b, uint32 *c, uint32 *d)
{
*a = rotlFixed(*a, 13);
*c = rotlFixed(*c, 3);
*d = rotlFixed(*d ^ *c ^ (*a << 3), 7);
*b = rotlFixed(*b ^ *a ^ *c, 1);
*a = rotlFixed(*a ^ *b ^ *d, 5);
*c = rotlFixed(*c ^ *d ^ (*b << 7), 22);
}
void serpent_encrypt(const uint8_t *inBlock, uint8_t *outBlock, uint8_t *ks)
{
uint32_t a, b, c, d, e;
unsigned int i=1;
const uint32_t *k = (uint32_t *)ks + 8;
uint32_t *in = (uint32_t *) inBlock;
uint32_t *out = (uint32_t *) outBlock;
a = LE32(in[0]);
b = LE32(in[1]);
c = LE32(in[2]);
d = LE32(in[3]);
do
{
KXf (k, 0, &a, &b, &c, &d); S0f (&a, &b, &c, &d, &e); LTf (&b, &e, &c, &a);
KXf (k, 4, &b, &e, &c, &a); S1f (&b, &e, &c, &a, &d); LTf (&c, &b, &a, &e);
KXf (k, 8, &c, &b, &a, &e); S2f (&c, &b, &a, &e, &d); LTf (&a, &e, &b, &d);
KXf (k, 12, &a, &e, &b, &d); S3f (&a, &e, &b, &d, &c); LTf (&e, &b, &d, &c);
KXf (k, 16, &e, &b, &d, &c); S4f (&e, &b, &d, &c, &a); LTf (&b, &a, &e, &c);
KXf (k, 20, &b, &a, &e, &c); S5f (&b, &a, &e, &c, &d); LTf (&a, &c, &b, &e);
KXf (k, 24, &a, &c, &b, &e); S6f (&a, &c, &b, &e, &d); LTf (&a, &c, &d, &b);
KXf (k, 28, &a, &c, &d, &b); S7f (&a, &c, &d, &b, &e);
if (i == 4)
break;
++i;
c = b;
b = e;
e = d;
d = a;
a = e;
k += 32;
LTf (&a,&b,&c,&d);
}
while (1);
KXf (k, 32, &d, &e, &b, &a);
out[0] = LE32(d);
out[1] = LE32(e);
out[2] = LE32(b);
out[3] = LE32(a);
}
#endif // TC_MINIMIZE_CODE_SIZE
#if !defined (TC_MINIMIZE_CODE_SIZE) || defined (TC_WINDOWS_BOOT_SERPENT)
void serpent_decrypt(const uint8_t *inBlock, uint8_t *outBlock, uint8_t *ks)
{
uint32_t a, b, c, d, e;
const uint32_t *k = (uint32_t *)ks + 104;
unsigned int i=4;
uint32_t *in = (uint32_t *) inBlock;
uint32_t *out = (uint32_t *) outBlock;
a = LE32(in[0]);
b = LE32(in[1]);
c = LE32(in[2]);
d = LE32(in[3]);
beforeI7(KX);
goto start;
do
{
c = b;
b = d;
d = e;
k -= 32;
beforeI7(ILT);
start:
beforeI7(I7); afterI7(KX);
afterI7(ILT); afterI7(I6); afterI6(KX);
afterI6(ILT); afterI6(I5); afterI5(KX);
afterI5(ILT); afterI5(I4); afterI4(KX);
afterI4(ILT); afterI4(I3); afterI3(KX);
afterI3(ILT); afterI3(I2); afterI2(KX);
afterI2(ILT); afterI2(I1); afterI1(KX);
afterI1(ILT); afterI1(I0); afterI0(KX);
}
while (--i != 0);
out[0] = LE32(a);
out[1] = LE32(d);
out[2] = LE32(b);
out[3] = LE32(e);
}
#else // TC_MINIMIZE_CODE_SIZE && !TC_WINDOWS_BOOT_SERPENT
static void ILTf (uint32 *a, uint32 *b, uint32 *c, uint32 *d)
{
*c = rotrFixed(*c, 22);
*a = rotrFixed(*a, 5);
*c ^= *d ^ (*b << 7);
*a ^= *b ^ *d;
*b = rotrFixed(*b, 1);
*d = rotrFixed(*d, 7) ^ *c ^ (*a << 3);
*b ^= *a ^ *c;
*c = rotrFixed(*c, 3);
*a = rotrFixed(*a, 13);
}
void serpent_decrypt(const uint8_t *inBlock, uint8_t *outBlock, uint8_t *ks)
{
uint32_t a, b, c, d, e;
const uint32_t *k = (uint32_t *)ks + 104;
unsigned int i=4;
uint32_t *in = (uint32_t *) inBlock;
uint32_t *out = (uint32_t *) outBlock;
a = LE32(in[0]);
b = LE32(in[1]);
c = LE32(in[2]);
d = LE32(in[3]);
KXf (k, 32, &a, &b, &c, &d);
goto start;
do
{
c = b;
b = d;
d = e;
k -= 32;
beforeI7(ILT);
start:
beforeI7(I7); KXf (k, 28, &d, &a, &b, &e);
ILTf (&d, &a, &b, &e); afterI7(I6); KXf (k, 24, &a, &b, &c, &e);
ILTf (&a, &b, &c, &e); afterI6(I5); KXf (k, 20, &b, &d, &e, &c);
ILTf (&b, &d, &e, &c); afterI5(I4); KXf (k, 16, &b, &c, &e, &a);
ILTf (&b, &c, &e, &a); afterI4(I3); KXf (k, 12, &a, &b, &e, &c);
ILTf (&a, &b, &e, &c); afterI3(I2); KXf (k, 8, &b, &d, &e, &c);
ILTf (&b, &d, &e, &c); afterI2(I1); KXf (k, 4, &a, &b, &c, &e);
ILTf (&a, &b, &c, &e); afterI1(I0); KXf (k, 0, &a, &d, &b, &e);
}
while (--i != 0);
out[0] = LE32(a);
out[1] = LE32(d);
out[2] = LE32(b);
out[3] = LE32(e);
}
#endif // TC_MINIMIZE_CODE_SIZE && !TC_WINDOWS_BOOT_SERPENT

View File

@@ -0,0 +1,19 @@
#ifndef HEADER_Crypto_Serpent
#define HEADER_Crypto_Serpent
#include <inttypes.h>
#ifdef __cplusplus
extern "C"
{
#endif
void serpent_set_key(const uint8_t userKey[], int keylen, uint8_t *ks);
void serpent_encrypt(const uint8_t *inBlock, uint8_t *outBlock, uint8_t *ks);
void serpent_decrypt(const uint8_t *inBlock, uint8_t *outBlock, uint8_t *ks);
#ifdef __cplusplus
}
#endif
#endif // HEADER_Crypto_Serpent

233
src/utils/crypto/set_key.c Normal file
View File

@@ -0,0 +1,233 @@
/* Deprecated/legacy */
/* crypto/des/set_key.c */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* set_key.c v 1.4 eay 24/9/91
* 1.4 Speed up by 400% :-)
* 1.3 added register declarations.
* 1.2 unrolled make_key_sched a bit more
* 1.1 added norm_expand_bits
* 1.0 First working version
*/
/* Adapted for TrueCrypt by the TrueCrypt Foundation */
#include "des_locl.h"
#include "podd.h"
#include "sk.h"
int des_check_key=1;
void des_set_odd_parity(des_cblock (*key))
{
int i;
for (i=0; i<(int)DES_KEY_SZ; i++)
(*key)[i]=odd_parity[(*key)[i]];
}
/* Weak and semi week keys as take from
* %A D.W. Davies
* %A W.L. Price
* %T Security for Computer Networks
* %I John Wiley & Sons
* %D 1984
* Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
* (and actual cblock values).
*/
#define NUM_WEAK_KEY 18
static des_cblock weak_keys[NUM_WEAK_KEY]={
/* weak keys */
{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
{0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
{0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
{0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
{0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
{0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0},
/* semi-weak keys */
{0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
{0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
{0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
{0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
{0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
{0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
{0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
{0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
{0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
{0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
{0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
{0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
int des_is_weak_key(des_cblock (*key))
{
int i;
for (i=0; i<NUM_WEAK_KEY; i++)
{
/* Added == 0 to comparision, I obviously don't run
* this section very often :-(, thanks to
* engineering@MorningStar.Com for the fix
* eay 93/06/29
* Another problem, I was comparing only the first 4
* bytes, 97/03/18
* Parity bits are ignored, TF 2006-04-12 */
if (((*((int64_t *) weak_keys[i]) ^ *((int64_t *) key)) & 0xFEFEFEFEFEFEFEFEULL) == 0)
return(1);
}
return(0);
}
/* NOW DEFINED IN des_local.h
* See ecb_encrypt.c for a pseudo description of these macros.
* #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
* (b)^=(t),\
* (a)=((a)^((t)<<(n))))
*/
#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
(a)=(a)^(t)^(t>>(16-(n))))
/* return 0 if key parity is odd (correct),
* return -1 if key parity error,
* return -2 if illegal weak key.
*/
int des_set_key(des_cblock (*key), des_key_schedule schedule)
{
static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
register DES_LONG c,d,t,s,t2;
register unsigned char *in;
register DES_LONG *k;
register int i;
k=(DES_LONG *)schedule;
in=(unsigned char *)key;
c2l(in,c);
c2l(in,d);
/* do PC1 in 60 simple operations */
/* PERM_OP(d,c,t,4,0x0f0f0f0fL);
HPERM_OP(c,t,-2, 0xcccc0000L);
HPERM_OP(c,t,-1, 0xaaaa0000L);
HPERM_OP(c,t, 8, 0x00ff0000L);
HPERM_OP(c,t,-1, 0xaaaa0000L);
HPERM_OP(d,t,-8, 0xff000000L);
HPERM_OP(d,t, 8, 0x00ff0000L);
HPERM_OP(d,t, 2, 0x33330000L);
d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L);
d=(d>>8)|((c&0xf0000000L)>>4);
c&=0x0fffffffL; */
/* I now do it in 47 simple operations :-)
* Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
* for the inspiration. :-) */
PERM_OP (d,c,t,4,0x0f0f0f0fL);
HPERM_OP(c,t,-2,0xcccc0000L);
HPERM_OP(d,t,-2,0xcccc0000L);
PERM_OP (d,c,t,1,0x55555555L);
PERM_OP (c,d,t,8,0x00ff00ffL);
PERM_OP (d,c,t,1,0x55555555L);
d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) |
((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
c&=0x0fffffffL;
for (i=0; i<ITERATIONS; i++)
{
if (shifts2[i])
{ c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
else
{ c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
c&=0x0fffffffL;
d&=0x0fffffffL;
/* could be a few less shifts but I am to lazy at this
* point in time to investigate */
s= des_skb[0][ (c )&0x3f ]|
des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]|
des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]|
des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) |
((c>>22L)&0x38)];
t= des_skb[4][ (d )&0x3f ]|
des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
des_skb[6][ (d>>15L)&0x3f ]|
des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
/* table contained 0213 4657 */
t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
*(k++)=ROTATE(t2,30)&0xffffffffL;
t2=((s>>16L)|(t&0xffff0000L));
*(k++)=ROTATE(t2,26)&0xffffffffL;
}
if (des_check_key)
{
//if (!check_parity(key))
// return(-1);
if (des_is_weak_key(key))
return(-2);
}
return(0);
}
int des_key_sched(des_cblock (*key), des_key_schedule schedule)
{
return(des_set_key(key,schedule));
}

View File

@@ -0,0 +1,6 @@
/* Deprecated/legacy */
void des_set_odd_parity ( des_cblock (*key ));
int des_is_weak_key ( des_cblock (*key ));
int des_set_key ( des_cblock (*key ), des_key_schedule schedule );
int des_key_sched ( des_cblock (*key ), des_key_schedule schedule );

280
src/utils/crypto/sha1.c Normal file
View File

@@ -0,0 +1,280 @@
/* Deprecated/legacy */
/*
---------------------------------------------------------------------------
Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved.
LICENSE TERMS
The free distribution and use of this software is allowed (with or without
changes) provided that:
1. source code distributions include the above copyright notice, this
list of conditions and the following disclaimer;
2. binary distributions include the above copyright notice, this list
of conditions and the following disclaimer in their documentation;
3. the name of the copyright holder is not used to endorse products
built using this software without specific written permission.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue Date: 18/06/2004
This is a byte oriented version of SHA1 that operates on arrays of bytes
stored in memory.
*/
#include <string.h> /* for memcpy() etc. */
#include <stdlib.h> /* for _lrotl with VC++ */
#include "sha1.h"
#if defined(__cplusplus)
extern "C"
{
#endif
/*
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 specify their endian definitions.
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.
*/
/* PLATFORM SPECIFIC INCLUDES */
/* Original byte order detection removed */
#include "../common/endian.h"
#define BRG_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
#define BRG_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
#if BYTE_ORDER == LITTLE_ENDIAN
# define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
#endif
#if BYTE_ORDER == BIG_ENDIAN
# define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
#endif
#ifdef _MSC_VER
#pragma intrinsic(memcpy)
#endif
#if 1 && defined(_MSC_VER) && !defined(_DEBUG)
#define rotl32 _rotl
#define rotr32 _rotr
#else
#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n)))
#endif
#if !defined(bswap_32)
#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00))
#endif
#if (PLATFORM_BYTE_ORDER == BRG_LITTLE_ENDIAN)
#define SWAP_BYTES
#else
#undef SWAP_BYTES
#endif
#if defined(SWAP_BYTES)
#define bsw_32(p,n) \
{ int _i = (n); while(_i--) ((sha1_32t*)p)[_i] = bswap_32(((sha1_32t*)p)[_i]); }
#else
#define bsw_32(p,n)
#endif
#define SHA1_MASK (SHA1_BLOCK_SIZE - 1)
#if 0
#define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
#define parity(x,y,z) ((x) ^ (y) ^ (z))
#define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
#else /* Discovered by Rich Schroeppel and Colin Plumb */
#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
#define parity(x,y,z) ((x) ^ (y) ^ (z))
#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y))))
#endif
/* Compile 64 bytes of hash data into SHA1 context. Note */
/* that this routine assumes that the byte order in the */
/* ctx->wbuf[] at this point is in such an order that low */
/* address bytes in the ORIGINAL byte stream will go in */
/* this buffer to the high end of 32-bit words on BOTH big */
/* and little endian systems */
#ifdef ARRAY
#define q(v,n) v[n]
#else
#define q(v,n) v##n
#endif
#define one_cycle(v,a,b,c,d,e,f,k,h) \
q(v,e) += rotr32(q(v,a),27) + \
f(q(v,b),q(v,c),q(v,d)) + k + h; \
q(v,b) = rotr32(q(v,b), 2)
#define five_cycle(v,f,k,i) \
one_cycle(v, 0,1,2,3,4, f,k,hf(i )); \
one_cycle(v, 4,0,1,2,3, f,k,hf(i+1)); \
one_cycle(v, 3,4,0,1,2, f,k,hf(i+2)); \
one_cycle(v, 2,3,4,0,1, f,k,hf(i+3)); \
one_cycle(v, 1,2,3,4,0, f,k,hf(i+4))
void sha1_compile(sha1_ctx ctx[1])
{ sha1_32t *w = ctx->wbuf;
#ifdef ARRAY
sha1_32t v[5];
memcpy(v, ctx->hash, 5 * sizeof(sha1_32t));
#else
sha1_32t v0, v1, v2, v3, v4;
v0 = ctx->hash[0]; v1 = ctx->hash[1];
v2 = ctx->hash[2]; v3 = ctx->hash[3];
v4 = ctx->hash[4];
#endif
#define hf(i) w[i]
five_cycle(v, ch, 0x5a827999, 0);
five_cycle(v, ch, 0x5a827999, 5);
five_cycle(v, ch, 0x5a827999, 10);
one_cycle(v,0,1,2,3,4, ch, 0x5a827999, hf(15)); \
#undef hf
#define hf(i) (w[(i) & 15] = rotl32( \
w[((i) + 13) & 15] ^ w[((i) + 8) & 15] \
^ w[((i) + 2) & 15] ^ w[(i) & 15], 1))
one_cycle(v,4,0,1,2,3, ch, 0x5a827999, hf(16));
one_cycle(v,3,4,0,1,2, ch, 0x5a827999, hf(17));
one_cycle(v,2,3,4,0,1, ch, 0x5a827999, hf(18));
one_cycle(v,1,2,3,4,0, ch, 0x5a827999, hf(19));
five_cycle(v, parity, 0x6ed9eba1, 20);
five_cycle(v, parity, 0x6ed9eba1, 25);
five_cycle(v, parity, 0x6ed9eba1, 30);
five_cycle(v, parity, 0x6ed9eba1, 35);
five_cycle(v, maj, 0x8f1bbcdc, 40);
five_cycle(v, maj, 0x8f1bbcdc, 45);
five_cycle(v, maj, 0x8f1bbcdc, 50);
five_cycle(v, maj, 0x8f1bbcdc, 55);
five_cycle(v, parity, 0xca62c1d6, 60);
five_cycle(v, parity, 0xca62c1d6, 65);
five_cycle(v, parity, 0xca62c1d6, 70);
five_cycle(v, parity, 0xca62c1d6, 75);
#ifdef ARRAY
ctx->hash[0] += v[0]; ctx->hash[1] += v[1];
ctx->hash[2] += v[2]; ctx->hash[3] += v[3];
ctx->hash[4] += v[4];
#else
ctx->hash[0] += v0; ctx->hash[1] += v1;
ctx->hash[2] += v2; ctx->hash[3] += v3;
ctx->hash[4] += v4;
#endif
}
void sha1_begin(sha1_ctx ctx[1])
{
ctx->count[0] = ctx->count[1] = 0;
ctx->hash[0] = 0x67452301;
ctx->hash[1] = 0xefcdab89;
ctx->hash[2] = 0x98badcfe;
ctx->hash[3] = 0x10325476;
ctx->hash[4] = 0xc3d2e1f0;
}
/* SHA1 hash data in an array of bytes into hash buffer and */
/* call the hash_compile function as required. */
void sha1_hash(const unsigned char data[], uint32_t len, sha1_ctx ctx[1])
{ sha1_32t pos = (sha1_32t)(ctx->count[0] & SHA1_MASK),
space = SHA1_BLOCK_SIZE - pos;
const unsigned char *sp = data;
if((ctx->count[0] += len) < len)
++(ctx->count[1]);
while(len >= space) /* tranfer whole blocks if possible */
{
memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
sp += space; len -= space; space = SHA1_BLOCK_SIZE; pos = 0;
bsw_32(ctx->wbuf, SHA1_BLOCK_SIZE >> 2);
sha1_compile(ctx);
}
memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);
}
/* SHA1 final padding and digest calculation */
void sha1_end(unsigned char hval[], sha1_ctx ctx[1])
{ sha1_32t i = (sha1_32t)(ctx->count[0] & SHA1_MASK);
/* put bytes in the buffer in an order in which references to */
/* 32-bit words will put bytes with lower addresses into the */
/* top of 32 bit words on BOTH big and little endian machines */
bsw_32(ctx->wbuf, (i + 3) >> 2);
/* we now need to mask valid bytes and add the padding which is */
/* a single 1 bit and as many zero bits as necessary. Note that */
/* we can always add the first padding byte here because the */
/* buffer always has at least one empty slot */
ctx->wbuf[i >> 2] &= 0xffffff80 << 8 * (~i & 3);
ctx->wbuf[i >> 2] |= 0x00000080 << 8 * (~i & 3);
/* we need 9 or more empty positions, one for the padding byte */
/* (above) and eight for the length count. If there is not */
/* enough space, pad and empty the buffer */
if(i > SHA1_BLOCK_SIZE - 9)
{
if(i < 60) ctx->wbuf[15] = 0;
sha1_compile(ctx);
i = 0;
}
else /* compute a word index for the empty buffer positions */
i = (i >> 2) + 1;
while(i < 14) /* and zero pad all but last two positions */
ctx->wbuf[i++] = 0;
/* the following 32-bit length fields are assembled in the */
/* wrong byte order on little endian machines but this is */
/* corrected later since they are only ever used as 32-bit */
/* word values. */
ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29);
ctx->wbuf[15] = ctx->count[0] << 3;
sha1_compile(ctx);
/* extract the hash value as bytes in case the hash buffer is */
/* misaligned for 32-bit words */
for(i = 0; i < SHA1_DIGEST_SIZE; ++i)
hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3)));
}
void sha1(unsigned char hval[], const unsigned char data[], uint32_t len)
{ sha1_ctx cx[1];
sha1_begin(cx); sha1_hash(data, len, cx); sha1_end(hval, cx);
}
#if defined(__cplusplus)
}
#endif

80
src/utils/crypto/sha1.h Normal file
View File

@@ -0,0 +1,80 @@
/*
---------------------------------------------------------------------------
Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved.
LICENSE TERMS
The free distribution and use of this software is allowed (with or without
changes) provided that:
1. source code distributions include the above copyright notice, this
list of conditions and the following disclaimer;
2. binary distributions include the above copyright notice, this list
of conditions and the following disclaimer in their documentation;
3. the name of the copyright holder is not used to endorse products
built using this software without specific written permission.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue Date: 26/08/2003
*/
#ifndef _SHA1_H
#define _SHA1_H
#include <limits.h>
#include <inttypes.h>
#define SHA1_BLOCK_SIZE 64
#define SHA1_DIGEST_SIZE 20
#if defined(__cplusplus)
extern "C"
{
#endif
/* define an unsigned 32-bit type */
#if defined(_MSC_VER)
typedef uint32_t sha1_32t;
#elif defined(ULONG_MAX) && ULONG_MAX == 0xfffffffful
typedef uint32_t sha1_32t;
#elif defined(UINT_MAX) && UINT_MAX == 0xffffffff
typedef uint32_t sha1_32t;
#else
# error Please define sha1_32t as an unsigned 32 bit type in sha1.h
#endif
/* type to hold the SHA256 context */
typedef struct
{ sha1_32t count[2];
sha1_32t hash[5];
sha1_32t wbuf[16];
} sha1_ctx;
/* Note that these prototypes are the same for both bit and */
/* byte oriented implementations. However the length fields */
/* are in bytes or bits as appropriate for the version used */
/* and bit sequences are input as arrays of bytes in which */
/* bit sequences run from the most to the least significant */
/* end of each byte */
void sha1_compile(sha1_ctx ctx[1]);
void sha1_begin(sha1_ctx ctx[1]);
void sha1_hash(const uint8_t data[], uint32_t len, sha1_ctx ctx[1]);
void sha1_end(uint8_t hval[], sha1_ctx ctx[1]);
void sha1(uint8_t hval[], const uint8_t data[], uint32_t len);
#if defined(__cplusplus)
}
#endif
#endif

770
src/utils/crypto/sha2.c Normal file
View File

@@ -0,0 +1,770 @@
/*
---------------------------------------------------------------------------
Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved.
LICENSE TERMS
The free distribution and use of this software is allowed (with or without
changes) provided that:
1. source code distributions include the above copyright notice, this
list of conditions and the following disclaimer;
2. binary distributions include the above copyright notice, this list
of conditions and the following disclaimer in their documentation;
3. the name of the copyright holder is not used to endorse products
built using this software without specific written permission.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue Date: 01/08/2005
This is a byte oriented version of SHA2 that operates on arrays of bytes
stored in memory. This code implements sha256, sha384 and sha512 but the
latter two functions rely on efficient 64-bit integer operations that
may not be very efficient on 32-bit machines
The sha256 functions use a type 'sha256_ctx' to hold details of the
current hash state and uses the following three calls:
void sha256_begin(sha256_ctx ctx[1])
void sha256_hash(const unsigned char data[],
unsigned long len, sha256_ctx ctx[1])
void sha_end1(unsigned char hval[], sha256_ctx ctx[1])
The first subroutine initialises a hash computation by setting up the
context in the sha256_ctx context. The second subroutine hashes 8-bit
bytes from array data[] into the hash state withinh sha256_ctx context,
the number of bytes to be hashed being given by the the unsigned long
integer len. The third subroutine completes the hash calculation and
places the resulting digest value in the array of 8-bit bytes hval[].
The sha384 and sha512 functions are similar and use the interfaces:
void sha384_begin(sha384_ctx ctx[1]);
void sha384_hash(const unsigned char data[],
unsigned long len, sha384_ctx ctx[1]);
void sha384_end(unsigned char hval[], sha384_ctx ctx[1]);
void sha512_begin(sha512_ctx ctx[1]);
void sha512_hash(const unsigned char data[],
unsigned long len, sha512_ctx ctx[1]);
void sha512_end(unsigned char hval[], sha512_ctx ctx[1]);
In addition there is a function sha2 that can be used to call all these
functions using a call with a hash length parameter as follows:
int sha2_begin(unsigned long len, sha2_ctx ctx[1]);
void sha2_hash(const unsigned char data[],
unsigned long len, sha2_ctx ctx[1]);
void sha2_end(unsigned char hval[], sha2_ctx ctx[1]);
My thanks to Erik Andersen <andersen@codepoet.org> for testing this code
on big-endian systems and for his assistance with corrections
*/
#include "../common/endian.h"
#define PLATFORM_BYTE_ORDER BYTE_ORDER
#define IS_LITTLE_ENDIAN LITTLE_ENDIAN
#if 0
#define UNROLL_SHA2 /* for SHA2 loop unroll */
#endif
#include <string.h> /* for memcpy() etc. */
#include "sha2.h"
#if defined(__cplusplus)
extern "C"
{
#endif
#if defined( _MSC_VER ) && ( _MSC_VER > 800 )
#pragma intrinsic(memcpy)
#endif
#if 0 && defined(_MSC_VER)
#define rotl32 _lrotl
#define rotr32 _lrotr
#else
#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n)))
#endif
#if !defined(bswap_32)
#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00))
#endif
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
#define SWAP_BYTES
#else
#undef SWAP_BYTES
#endif
#if 0
#define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
#define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
#else /* Thanks to Rich Schroeppel and Colin Plumb for the following */
#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y))))
#endif
/* round transforms for SHA256 and SHA512 compression functions */
#define vf(n,i) v[(n - i) & 7]
#define hf(i) (p[i & 15] += \
g_1(p[(i + 14) & 15]) + p[(i + 9) & 15] + g_0(p[(i + 1) & 15]))
#define v_cycle(i,j) \
vf(7,i) += (j ? hf(i) : p[i]) + k_0[i+j] \
+ s_1(vf(4,i)) + ch(vf(4,i),vf(5,i),vf(6,i)); \
vf(3,i) += vf(7,i); \
vf(7,i) += s_0(vf(0,i))+ maj(vf(0,i),vf(1,i),vf(2,i))
#if defined(SHA_224) || defined(SHA_256)
#define SHA256_MASK (SHA256_BLOCK_SIZE - 1)
#if defined(SWAP_BYTES)
#define bsw_32(p,n) \
{ int _i = (n); while(_i--) ((uint_32t*)p)[_i] = bswap_32(((uint_32t*)p)[_i]); }
#else
#define bsw_32(p,n)
#endif
#define s_0(x) (rotr32((x), 2) ^ rotr32((x), 13) ^ rotr32((x), 22))
#define s_1(x) (rotr32((x), 6) ^ rotr32((x), 11) ^ rotr32((x), 25))
#define g_0(x) (rotr32((x), 7) ^ rotr32((x), 18) ^ ((x) >> 3))
#define g_1(x) (rotr32((x), 17) ^ rotr32((x), 19) ^ ((x) >> 10))
#define k_0 k256
/* rotated SHA256 round definition. Rather than swapping variables as in */
/* FIPS-180, different variables are 'rotated' on each round, returning */
/* to their starting positions every eight rounds */
#define q(n) v##n
#define one_cycle(a,b,c,d,e,f,g,h,k,w) \
q(h) += s_1(q(e)) + ch(q(e), q(f), q(g)) + k + w; \
q(d) += q(h); q(h) += s_0(q(a)) + maj(q(a), q(b), q(c))
/* SHA256 mixing data */
const uint_32t k256[64] =
{ 0x428a2f98ul, 0x71374491ul, 0xb5c0fbcful, 0xe9b5dba5ul,
0x3956c25bul, 0x59f111f1ul, 0x923f82a4ul, 0xab1c5ed5ul,
0xd807aa98ul, 0x12835b01ul, 0x243185beul, 0x550c7dc3ul,
0x72be5d74ul, 0x80deb1feul, 0x9bdc06a7ul, 0xc19bf174ul,
0xe49b69c1ul, 0xefbe4786ul, 0x0fc19dc6ul, 0x240ca1ccul,
0x2de92c6ful, 0x4a7484aaul, 0x5cb0a9dcul, 0x76f988daul,
0x983e5152ul, 0xa831c66dul, 0xb00327c8ul, 0xbf597fc7ul,
0xc6e00bf3ul, 0xd5a79147ul, 0x06ca6351ul, 0x14292967ul,
0x27b70a85ul, 0x2e1b2138ul, 0x4d2c6dfcul, 0x53380d13ul,
0x650a7354ul, 0x766a0abbul, 0x81c2c92eul, 0x92722c85ul,
0xa2bfe8a1ul, 0xa81a664bul, 0xc24b8b70ul, 0xc76c51a3ul,
0xd192e819ul, 0xd6990624ul, 0xf40e3585ul, 0x106aa070ul,
0x19a4c116ul, 0x1e376c08ul, 0x2748774cul, 0x34b0bcb5ul,
0x391c0cb3ul, 0x4ed8aa4aul, 0x5b9cca4ful, 0x682e6ff3ul,
0x748f82eeul, 0x78a5636ful, 0x84c87814ul, 0x8cc70208ul,
0x90befffaul, 0xa4506cebul, 0xbef9a3f7ul, 0xc67178f2ul,
};
/* Compile 64 bytes of hash data into SHA256 digest value */
/* NOTE: this routine assumes that the byte order in the */
/* ctx->wbuf[] at this point is such that low address bytes */
/* in the ORIGINAL byte stream will go into the high end of */
/* words on BOTH big and little endian systems */
VOID_RETURN sha256_compile(sha256_ctx ctx[1])
{
#if !defined(UNROLL_SHA2)
uint_32t j, *p = ctx->wbuf, v[8];
memcpy(v, ctx->hash, 8 * sizeof(uint_32t));
for(j = 0; j < 64; j += 16)
{
v_cycle( 0, j); v_cycle( 1, j);
v_cycle( 2, j); v_cycle( 3, j);
v_cycle( 4, j); v_cycle( 5, j);
v_cycle( 6, j); v_cycle( 7, j);
v_cycle( 8, j); v_cycle( 9, j);
v_cycle(10, j); v_cycle(11, j);
v_cycle(12, j); v_cycle(13, j);
v_cycle(14, j); v_cycle(15, j);
}
ctx->hash[0] += v[0]; ctx->hash[1] += v[1];
ctx->hash[2] += v[2]; ctx->hash[3] += v[3];
ctx->hash[4] += v[4]; ctx->hash[5] += v[5];
ctx->hash[6] += v[6]; ctx->hash[7] += v[7];
#else
uint_32t *p = ctx->wbuf,v0,v1,v2,v3,v4,v5,v6,v7;
v0 = ctx->hash[0]; v1 = ctx->hash[1];
v2 = ctx->hash[2]; v3 = ctx->hash[3];
v4 = ctx->hash[4]; v5 = ctx->hash[5];
v6 = ctx->hash[6]; v7 = ctx->hash[7];
one_cycle(0,1,2,3,4,5,6,7,k256[ 0],p[ 0]);
one_cycle(7,0,1,2,3,4,5,6,k256[ 1],p[ 1]);
one_cycle(6,7,0,1,2,3,4,5,k256[ 2],p[ 2]);
one_cycle(5,6,7,0,1,2,3,4,k256[ 3],p[ 3]);
one_cycle(4,5,6,7,0,1,2,3,k256[ 4],p[ 4]);
one_cycle(3,4,5,6,7,0,1,2,k256[ 5],p[ 5]);
one_cycle(2,3,4,5,6,7,0,1,k256[ 6],p[ 6]);
one_cycle(1,2,3,4,5,6,7,0,k256[ 7],p[ 7]);
one_cycle(0,1,2,3,4,5,6,7,k256[ 8],p[ 8]);
one_cycle(7,0,1,2,3,4,5,6,k256[ 9],p[ 9]);
one_cycle(6,7,0,1,2,3,4,5,k256[10],p[10]);
one_cycle(5,6,7,0,1,2,3,4,k256[11],p[11]);
one_cycle(4,5,6,7,0,1,2,3,k256[12],p[12]);
one_cycle(3,4,5,6,7,0,1,2,k256[13],p[13]);
one_cycle(2,3,4,5,6,7,0,1,k256[14],p[14]);
one_cycle(1,2,3,4,5,6,7,0,k256[15],p[15]);
one_cycle(0,1,2,3,4,5,6,7,k256[16],hf( 0));
one_cycle(7,0,1,2,3,4,5,6,k256[17],hf( 1));
one_cycle(6,7,0,1,2,3,4,5,k256[18],hf( 2));
one_cycle(5,6,7,0,1,2,3,4,k256[19],hf( 3));
one_cycle(4,5,6,7,0,1,2,3,k256[20],hf( 4));
one_cycle(3,4,5,6,7,0,1,2,k256[21],hf( 5));
one_cycle(2,3,4,5,6,7,0,1,k256[22],hf( 6));
one_cycle(1,2,3,4,5,6,7,0,k256[23],hf( 7));
one_cycle(0,1,2,3,4,5,6,7,k256[24],hf( 8));
one_cycle(7,0,1,2,3,4,5,6,k256[25],hf( 9));
one_cycle(6,7,0,1,2,3,4,5,k256[26],hf(10));
one_cycle(5,6,7,0,1,2,3,4,k256[27],hf(11));
one_cycle(4,5,6,7,0,1,2,3,k256[28],hf(12));
one_cycle(3,4,5,6,7,0,1,2,k256[29],hf(13));
one_cycle(2,3,4,5,6,7,0,1,k256[30],hf(14));
one_cycle(1,2,3,4,5,6,7,0,k256[31],hf(15));
one_cycle(0,1,2,3,4,5,6,7,k256[32],hf( 0));
one_cycle(7,0,1,2,3,4,5,6,k256[33],hf( 1));
one_cycle(6,7,0,1,2,3,4,5,k256[34],hf( 2));
one_cycle(5,6,7,0,1,2,3,4,k256[35],hf( 3));
one_cycle(4,5,6,7,0,1,2,3,k256[36],hf( 4));
one_cycle(3,4,5,6,7,0,1,2,k256[37],hf( 5));
one_cycle(2,3,4,5,6,7,0,1,k256[38],hf( 6));
one_cycle(1,2,3,4,5,6,7,0,k256[39],hf( 7));
one_cycle(0,1,2,3,4,5,6,7,k256[40],hf( 8));
one_cycle(7,0,1,2,3,4,5,6,k256[41],hf( 9));
one_cycle(6,7,0,1,2,3,4,5,k256[42],hf(10));
one_cycle(5,6,7,0,1,2,3,4,k256[43],hf(11));
one_cycle(4,5,6,7,0,1,2,3,k256[44],hf(12));
one_cycle(3,4,5,6,7,0,1,2,k256[45],hf(13));
one_cycle(2,3,4,5,6,7,0,1,k256[46],hf(14));
one_cycle(1,2,3,4,5,6,7,0,k256[47],hf(15));
one_cycle(0,1,2,3,4,5,6,7,k256[48],hf( 0));
one_cycle(7,0,1,2,3,4,5,6,k256[49],hf( 1));
one_cycle(6,7,0,1,2,3,4,5,k256[50],hf( 2));
one_cycle(5,6,7,0,1,2,3,4,k256[51],hf( 3));
one_cycle(4,5,6,7,0,1,2,3,k256[52],hf( 4));
one_cycle(3,4,5,6,7,0,1,2,k256[53],hf( 5));
one_cycle(2,3,4,5,6,7,0,1,k256[54],hf( 6));
one_cycle(1,2,3,4,5,6,7,0,k256[55],hf( 7));
one_cycle(0,1,2,3,4,5,6,7,k256[56],hf( 8));
one_cycle(7,0,1,2,3,4,5,6,k256[57],hf( 9));
one_cycle(6,7,0,1,2,3,4,5,k256[58],hf(10));
one_cycle(5,6,7,0,1,2,3,4,k256[59],hf(11));
one_cycle(4,5,6,7,0,1,2,3,k256[60],hf(12));
one_cycle(3,4,5,6,7,0,1,2,k256[61],hf(13));
one_cycle(2,3,4,5,6,7,0,1,k256[62],hf(14));
one_cycle(1,2,3,4,5,6,7,0,k256[63],hf(15));
ctx->hash[0] += v0; ctx->hash[1] += v1;
ctx->hash[2] += v2; ctx->hash[3] += v3;
ctx->hash[4] += v4; ctx->hash[5] += v5;
ctx->hash[6] += v6; ctx->hash[7] += v7;
#endif
}
/* SHA256 hash data in an array of bytes into hash buffer */
/* and call the hash_compile function as required. */
VOID_RETURN sha256_hash(const unsigned char data[], unsigned long len, sha256_ctx ctx[1])
{ uint_32t pos = (uint_32t)(ctx->count[0] & SHA256_MASK),
space = SHA256_BLOCK_SIZE - pos;
const unsigned char *sp = data;
if((ctx->count[0] += len) < len)
++(ctx->count[1]);
while(len >= space) /* tranfer whole blocks while possible */
{
memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
sp += space; len -= space; space = SHA256_BLOCK_SIZE; pos = 0;
bsw_32(ctx->wbuf, SHA256_BLOCK_SIZE >> 2)
sha256_compile(ctx);
}
memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);
}
/* SHA256 Final padding and digest calculation */
static void sha_end1(unsigned char hval[], sha256_ctx ctx[1], const unsigned int hlen)
{ uint_32t i = (uint_32t)(ctx->count[0] & SHA256_MASK);
/* put bytes in the buffer in an order in which references to */
/* 32-bit words will put bytes with lower addresses into the */
/* top of 32 bit words on BOTH big and little endian machines */
bsw_32(ctx->wbuf, (i + 3) >> 2)
/* we now need to mask valid bytes and add the padding which is */
/* a single 1 bit and as many zero bits as necessary. Note that */
/* we can always add the first padding byte here because the */
/* buffer always has at least one empty slot */
ctx->wbuf[i >> 2] &= 0xffffff80 << 8 * (~i & 3);
ctx->wbuf[i >> 2] |= 0x00000080 << 8 * (~i & 3);
/* we need 9 or more empty positions, one for the padding byte */
/* (above) and eight for the length count. If there is not */
/* enough space pad and empty the buffer */
if(i > SHA256_BLOCK_SIZE - 9)
{
if(i < 60) ctx->wbuf[15] = 0;
sha256_compile(ctx);
i = 0;
}
else /* compute a word index for the empty buffer positions */
i = (i >> 2) + 1;
while(i < 14) /* and zero pad all but last two positions */
ctx->wbuf[i++] = 0;
/* the following 32-bit length fields are assembled in the */
/* wrong byte order on little endian machines but this is */
/* corrected later since they are only ever used as 32-bit */
/* word values. */
ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29);
ctx->wbuf[15] = ctx->count[0] << 3;
sha256_compile(ctx);
/* extract the hash value as bytes in case the hash buffer is */
/* mislaigned for 32-bit words */
for(i = 0; i < hlen; ++i)
hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3)));
}
#endif
#if defined(SHA_224)
const uint_32t i224[8] =
{
0xc1059ed8ul, 0x367cd507ul, 0x3070dd17ul, 0xf70e5939ul,
0xffc00b31ul, 0x68581511ul, 0x64f98fa7ul, 0xbefa4fa4ul
};
VOID_RETURN sha224_begin(sha224_ctx ctx[1])
{
ctx->count[0] = ctx->count[1] = 0;
memcpy(ctx->hash, i224, 8 * sizeof(uint_32t));
}
VOID_RETURN sha224_end(unsigned char hval[], sha224_ctx ctx[1])
{
sha_end1(hval, ctx, SHA224_DIGEST_SIZE);
}
VOID_RETURN sha224(unsigned char hval[], const unsigned char data[], unsigned long len)
{ sha224_ctx cx[1];
sha224_begin(cx);
sha224_hash(data, len, cx);
sha_end1(hval, cx, SHA224_DIGEST_SIZE);
}
#endif
#if defined(SHA_256)
const uint_32t i256[8] =
{
0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul,
0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul
};
VOID_RETURN sha256_begin(sha256_ctx ctx[1])
{
ctx->count[0] = ctx->count[1] = 0;
memcpy(ctx->hash, i256, 8 * sizeof(uint_32t));
}
VOID_RETURN sha256_end(unsigned char hval[], sha256_ctx ctx[1])
{
sha_end1(hval, ctx, SHA256_DIGEST_SIZE);
}
VOID_RETURN sha256(unsigned char hval[], const unsigned char data[], unsigned long len)
{ sha256_ctx cx[1];
sha256_begin(cx);
sha256_hash(data, len, cx);
sha_end1(hval, cx, SHA256_DIGEST_SIZE);
}
#endif
#if defined(SHA_384) || defined(SHA_512)
#define SHA512_MASK (SHA512_BLOCK_SIZE - 1)
#define rotr64(x,n) (((x) >> n) | ((x) << (64 - n)))
#if !defined(bswap_64)
#define bswap_64(x) (((uint_64t)(bswap_32((uint_32t)(x)))) << 32 | bswap_32((uint_32t)((x) >> 32)))
#endif
#if defined(SWAP_BYTES)
#define bsw_64(p,n) \
{ int _i = (n); while(_i--) ((uint_64t*)p)[_i] = bswap_64(((uint_64t*)p)[_i]); }
#else
#define bsw_64(p,n)
#endif
/* SHA512 mixing function definitions */
#ifdef s_0
# undef s_0
# undef s_1
# undef g_0
# undef g_1
# undef k_0
#endif
#define s_0(x) (rotr64((x), 28) ^ rotr64((x), 34) ^ rotr64((x), 39))
#define s_1(x) (rotr64((x), 14) ^ rotr64((x), 18) ^ rotr64((x), 41))
#define g_0(x) (rotr64((x), 1) ^ rotr64((x), 8) ^ ((x) >> 7))
#define g_1(x) (rotr64((x), 19) ^ rotr64((x), 61) ^ ((x) >> 6))
#define k_0 k512
/* SHA384/SHA512 mixing data */
const uint_64t k512[80] =
{
li_64(428a2f98d728ae22), li_64(7137449123ef65cd),
li_64(b5c0fbcfec4d3b2f), li_64(e9b5dba58189dbbc),
li_64(3956c25bf348b538), li_64(59f111f1b605d019),
li_64(923f82a4af194f9b), li_64(ab1c5ed5da6d8118),
li_64(d807aa98a3030242), li_64(12835b0145706fbe),
li_64(243185be4ee4b28c), li_64(550c7dc3d5ffb4e2),
li_64(72be5d74f27b896f), li_64(80deb1fe3b1696b1),
li_64(9bdc06a725c71235), li_64(c19bf174cf692694),
li_64(e49b69c19ef14ad2), li_64(efbe4786384f25e3),
li_64(0fc19dc68b8cd5b5), li_64(240ca1cc77ac9c65),
li_64(2de92c6f592b0275), li_64(4a7484aa6ea6e483),
li_64(5cb0a9dcbd41fbd4), li_64(76f988da831153b5),
li_64(983e5152ee66dfab), li_64(a831c66d2db43210),
li_64(b00327c898fb213f), li_64(bf597fc7beef0ee4),
li_64(c6e00bf33da88fc2), li_64(d5a79147930aa725),
li_64(06ca6351e003826f), li_64(142929670a0e6e70),
li_64(27b70a8546d22ffc), li_64(2e1b21385c26c926),
li_64(4d2c6dfc5ac42aed), li_64(53380d139d95b3df),
li_64(650a73548baf63de), li_64(766a0abb3c77b2a8),
li_64(81c2c92e47edaee6), li_64(92722c851482353b),
li_64(a2bfe8a14cf10364), li_64(a81a664bbc423001),
li_64(c24b8b70d0f89791), li_64(c76c51a30654be30),
li_64(d192e819d6ef5218), li_64(d69906245565a910),
li_64(f40e35855771202a), li_64(106aa07032bbd1b8),
li_64(19a4c116b8d2d0c8), li_64(1e376c085141ab53),
li_64(2748774cdf8eeb99), li_64(34b0bcb5e19b48a8),
li_64(391c0cb3c5c95a63), li_64(4ed8aa4ae3418acb),
li_64(5b9cca4f7763e373), li_64(682e6ff3d6b2b8a3),
li_64(748f82ee5defb2fc), li_64(78a5636f43172f60),
li_64(84c87814a1f0ab72), li_64(8cc702081a6439ec),
li_64(90befffa23631e28), li_64(a4506cebde82bde9),
li_64(bef9a3f7b2c67915), li_64(c67178f2e372532b),
li_64(ca273eceea26619c), li_64(d186b8c721c0c207),
li_64(eada7dd6cde0eb1e), li_64(f57d4f7fee6ed178),
li_64(06f067aa72176fba), li_64(0a637dc5a2c898a6),
li_64(113f9804bef90dae), li_64(1b710b35131c471b),
li_64(28db77f523047d84), li_64(32caab7b40c72493),
li_64(3c9ebe0a15c9bebc), li_64(431d67c49c100d4c),
li_64(4cc5d4becb3e42b6), li_64(597f299cfc657e2a),
li_64(5fcb6fab3ad6faec), li_64(6c44198c4a475817)
};
/* Compile 128 bytes of hash data into SHA384/512 digest */
/* NOTE: this routine assumes that the byte order in the */
/* ctx->wbuf[] at this point is such that low address bytes */
/* in the ORIGINAL byte stream will go into the high end of */
/* words on BOTH big and little endian systems */
VOID_RETURN sha512_compile(sha512_ctx ctx[1])
{ uint_64t v[8], *p = ctx->wbuf;
uint_32t j;
memcpy(v, ctx->hash, 8 * sizeof(uint_64t));
for(j = 0; j < 80; j += 16)
{
v_cycle( 0, j); v_cycle( 1, j);
v_cycle( 2, j); v_cycle( 3, j);
v_cycle( 4, j); v_cycle( 5, j);
v_cycle( 6, j); v_cycle( 7, j);
v_cycle( 8, j); v_cycle( 9, j);
v_cycle(10, j); v_cycle(11, j);
v_cycle(12, j); v_cycle(13, j);
v_cycle(14, j); v_cycle(15, j);
}
ctx->hash[0] += v[0]; ctx->hash[1] += v[1];
ctx->hash[2] += v[2]; ctx->hash[3] += v[3];
ctx->hash[4] += v[4]; ctx->hash[5] += v[5];
ctx->hash[6] += v[6]; ctx->hash[7] += v[7];
}
/* Compile 128 bytes of hash data into SHA256 digest value */
/* NOTE: this routine assumes that the byte order in the */
/* ctx->wbuf[] at this point is in such an order that low */
/* address bytes in the ORIGINAL byte stream placed in this */
/* buffer will now go to the high end of words on BOTH big */
/* and little endian systems */
VOID_RETURN sha512_hash(const unsigned char data[], unsigned long len, sha512_ctx ctx[1])
{ uint_32t pos = (uint_32t)(ctx->count[0] & SHA512_MASK),
space = SHA512_BLOCK_SIZE - pos;
const unsigned char *sp = data;
if((ctx->count[0] += len) < len)
++(ctx->count[1]);
while(len >= space) /* tranfer whole blocks while possible */
{
memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
sp += space; len -= space; space = SHA512_BLOCK_SIZE; pos = 0;
bsw_64(ctx->wbuf, SHA512_BLOCK_SIZE >> 3);
sha512_compile(ctx);
}
memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);
}
/* SHA384/512 Final padding and digest calculation */
static void sha_end2(unsigned char hval[], sha512_ctx ctx[1], const unsigned int hlen)
{ uint_32t i = (uint_32t)(ctx->count[0] & SHA512_MASK);
/* put bytes in the buffer in an order in which references to */
/* 32-bit words will put bytes with lower addresses into the */
/* top of 32 bit words on BOTH big and little endian machines */
bsw_64(ctx->wbuf, (i + 7) >> 3);
/* we now need to mask valid bytes and add the padding which is */
/* a single 1 bit and as many zero bits as necessary. Note that */
/* we can always add the first padding byte here because the */
/* buffer always has at least one empty slot */
ctx->wbuf[i >> 3] &= li_64(ffffffffffffff00) << 8 * (~i & 7);
ctx->wbuf[i >> 3] |= li_64(0000000000000080) << 8 * (~i & 7);
/* we need 17 or more empty byte positions, one for the padding */
/* byte (above) and sixteen for the length count. If there is */
/* not enough space pad and empty the buffer */
if(i > SHA512_BLOCK_SIZE - 17)
{
if(i < 120) ctx->wbuf[15] = 0;
sha512_compile(ctx);
i = 0;
}
else
i = (i >> 3) + 1;
while(i < 14)
ctx->wbuf[i++] = 0;
/* the following 64-bit length fields are assembled in the */
/* wrong byte order on little endian machines but this is */
/* corrected later since they are only ever used as 64-bit */
/* word values. */
ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 61);
ctx->wbuf[15] = ctx->count[0] << 3;
sha512_compile(ctx);
/* extract the hash value as bytes in case the hash buffer is */
/* misaligned for 32-bit words */
for(i = 0; i < hlen; ++i)
hval[i] = (unsigned char)(ctx->hash[i >> 3] >> (8 * (~i & 7)));
}
#endif
#if defined(SHA_384)
/* SHA384 initialisation data */
const uint_64t i384[80] =
{
li_64(cbbb9d5dc1059ed8), li_64(629a292a367cd507),
li_64(9159015a3070dd17), li_64(152fecd8f70e5939),
li_64(67332667ffc00b31), li_64(8eb44a8768581511),
li_64(db0c2e0d64f98fa7), li_64(47b5481dbefa4fa4)
};
VOID_RETURN sha384_begin(sha384_ctx ctx[1])
{
ctx->count[0] = ctx->count[1] = 0;
memcpy(ctx->hash, i384, 8 * sizeof(uint_64t));
}
VOID_RETURN sha384_end(unsigned char hval[], sha384_ctx ctx[1])
{
sha_end2(hval, ctx, SHA384_DIGEST_SIZE);
}
VOID_RETURN sha384(unsigned char hval[], const unsigned char data[], unsigned long len)
{ sha384_ctx cx[1];
sha384_begin(cx);
sha384_hash(data, len, cx);
sha_end2(hval, cx, SHA384_DIGEST_SIZE);
}
#endif
#if defined(SHA_512)
/* SHA512 initialisation data */
const uint_64t i512[80] =
{
li_64(6a09e667f3bcc908), li_64(bb67ae8584caa73b),
li_64(3c6ef372fe94f82b), li_64(a54ff53a5f1d36f1),
li_64(510e527fade682d1), li_64(9b05688c2b3e6c1f),
li_64(1f83d9abfb41bd6b), li_64(5be0cd19137e2179)
};
VOID_RETURN sha512_begin(sha512_ctx ctx[1])
{
ctx->count[0] = ctx->count[1] = 0;
memcpy(ctx->hash, i512, 8 * sizeof(uint_64t));
}
VOID_RETURN sha512_end(unsigned char hval[], sha512_ctx ctx[1])
{
sha_end2(hval, ctx, SHA512_DIGEST_SIZE);
}
VOID_RETURN sha512(unsigned char hval[], const unsigned char data[], unsigned long len)
{ sha512_ctx cx[1];
sha512_begin(cx);
sha512_hash(data, len, cx);
sha_end2(hval, cx, SHA512_DIGEST_SIZE);
}
#endif
#if defined(SHA_2)
#define CTX_224(x) ((x)->uu->ctx256)
#define CTX_256(x) ((x)->uu->ctx256)
#define CTX_384(x) ((x)->uu->ctx512)
#define CTX_512(x) ((x)->uu->ctx512)
/* SHA2 initialisation */
INT_RETURN sha2_begin(unsigned long len, sha2_ctx ctx[1])
{
switch(len)
{
#if defined(SHA_224)
case 224:
case 28: CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0;
memcpy(CTX_256(ctx)->hash, i224, 32);
ctx->sha2_len = 28; return EXIT_SUCCESS;
#endif
#if defined(SHA_256)
case 256:
case 32: CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0;
memcpy(CTX_256(ctx)->hash, i256, 32);
ctx->sha2_len = 32; return EXIT_SUCCESS;
#endif
#if defined(SHA_384)
case 384:
case 48: CTX_384(ctx)->count[0] = CTX_384(ctx)->count[1] = 0;
memcpy(CTX_384(ctx)->hash, i384, 64);
ctx->sha2_len = 48; return EXIT_SUCCESS;
#endif
#if defined(SHA_512)
case 512:
case 64: CTX_512(ctx)->count[0] = CTX_512(ctx)->count[1] = 0;
memcpy(CTX_512(ctx)->hash, i512, 64);
ctx->sha2_len = 64; return EXIT_SUCCESS;
#endif
default: return EXIT_FAILURE;
}
}
VOID_RETURN sha2_hash(const unsigned char data[], unsigned long len, sha2_ctx ctx[1])
{
switch(ctx->sha2_len)
{
#if defined(SHA_224)
case 28: sha224_hash(data, len, CTX_224(ctx)); return;
#endif
#if defined(SHA_256)
case 32: sha256_hash(data, len, CTX_256(ctx)); return;
#endif
#if defined(SHA_384)
case 48: sha384_hash(data, len, CTX_384(ctx)); return;
#endif
#if defined(SHA_512)
case 64: sha512_hash(data, len, CTX_512(ctx)); return;
#endif
}
}
VOID_RETURN sha2_end(unsigned char hval[], sha2_ctx ctx[1])
{
switch(ctx->sha2_len)
{
#if defined(SHA_224)
case 28: sha_end1(hval, CTX_224(ctx), SHA224_DIGEST_SIZE); return;
#endif
#if defined(SHA_256)
case 32: sha_end1(hval, CTX_256(ctx), SHA256_DIGEST_SIZE); return;
#endif
#if defined(SHA_384)
case 48: sha_end2(hval, CTX_384(ctx), SHA384_DIGEST_SIZE); return;
#endif
#if defined(SHA_512)
case 64: sha_end2(hval, CTX_512(ctx), SHA512_DIGEST_SIZE); return;
#endif
}
}
INT_RETURN sha2(unsigned char hval[], unsigned long size,
const unsigned char data[], unsigned long len)
{ sha2_ctx cx[1];
if(sha2_begin(size, cx) == EXIT_SUCCESS)
{
sha2_hash(data, len, cx); sha2_end(hval, cx); return EXIT_SUCCESS;
}
else
return EXIT_FAILURE;
}
#endif
#if defined(__cplusplus)
}
#endif

155
src/utils/crypto/sha2.h Normal file
View File

@@ -0,0 +1,155 @@
/*
---------------------------------------------------------------------------
Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved.
LICENSE TERMS
The free distribution and use of this software is allowed (with or without
changes) provided that:
1. source code distributions include the above copyright notice, this
list of conditions and the following disclaimer;
2. binary distributions include the above copyright notice, this list
of conditions and the following disclaimer in their documentation;
3. the name of the copyright holder is not used to endorse products
built using this software without specific written permission.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue Date: 01/08/2005
*/
#ifndef _SHA2_H
#define _SHA2_H
#include "../common/tcdefs.h"
#include "../common/endian.h"
#define SHA_64BIT
/* define the hash functions that you need */
#define SHA_2 /* for dynamic hash length */
#define SHA_224
#define SHA_256
#ifdef SHA_64BIT
# define SHA_384
# define SHA_512
# define NEED_UINT_64T
#endif
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
#endif
#define li_64(h) 0x##h##ull
#define VOID_RETURN void
#define INT_RETURN int
#if defined(__cplusplus)
extern "C"
{
#endif
/* Note that the following function prototypes are the same */
/* for both the bit and byte oriented implementations. But */
/* the length fields are in bytes or bits as is appropriate */
/* for the version used. Bit sequences are arrays of bytes */
/* in which bit sequence indexes increase from the most to */
/* the least significant end of each byte */
#define SHA224_DIGEST_SIZE 28
#define SHA224_BLOCK_SIZE 64
#define SHA256_DIGEST_SIZE 32
#define SHA256_BLOCK_SIZE 64
/* type to hold the SHA256 (and SHA224) context */
typedef struct
{ uint_32t count[2];
uint_32t hash[8];
uint_32t wbuf[16];
} sha256_ctx;
typedef sha256_ctx sha224_ctx;
VOID_RETURN sha256_compile(sha256_ctx ctx[1]);
VOID_RETURN sha224_begin(sha224_ctx ctx[1]);
#define sha224_hash sha256_hash
VOID_RETURN sha224_end(uint8_t hval[], sha224_ctx ctx[1]);
VOID_RETURN sha224(uint8_t hval[], const uint8_t data[], unsigned long len);
VOID_RETURN sha256_begin(sha256_ctx ctx[1]);
VOID_RETURN sha256_hash(const uint8_t data[], unsigned long len, sha256_ctx ctx[1]);
VOID_RETURN sha256_end(uint8_t hval[], sha256_ctx ctx[1]);
VOID_RETURN sha256(uint8_t hval[], const uint8_t data[], unsigned long len);
#ifndef SHA_64BIT
typedef struct
{ union
{ sha256_ctx ctx256[1];
} uu[1];
uint_32t sha2_len;
} sha2_ctx;
#define SHA2_MAX_DIGEST_SIZE SHA256_DIGEST_SIZE
#else
#define SHA384_DIGEST_SIZE 48
#define SHA384_BLOCK_SIZE 128
#define SHA512_DIGEST_SIZE 64
#define SHA512_BLOCK_SIZE 128
#define SHA2_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
/* type to hold the SHA384 (and SHA512) context */
typedef struct
{ uint_64t count[2];
uint_64t hash[8];
uint_64t wbuf[16];
} sha512_ctx;
typedef sha512_ctx sha384_ctx;
typedef struct
{ union
{ sha256_ctx ctx256[1];
sha512_ctx ctx512[1];
} uu[1];
uint_32t sha2_len;
} sha2_ctx;
VOID_RETURN sha512_compile(sha512_ctx ctx[1]);
VOID_RETURN sha384_begin(sha384_ctx ctx[1]);
#define sha384_hash sha512_hash
VOID_RETURN sha384_end(uint8_t hval[], sha384_ctx ctx[1]);
VOID_RETURN sha384(uint8_t hval[], const uint8_t data[], unsigned long len);
VOID_RETURN sha512_begin(sha512_ctx ctx[1]);
VOID_RETURN sha512_hash(const uint8_t data[], unsigned long len, sha512_ctx ctx[1]);
VOID_RETURN sha512_end(uint8_t hval[], sha512_ctx ctx[1]);
VOID_RETURN sha512(uint8_t hval[], const uint8_t data[], unsigned long len);
INT_RETURN sha2_begin(unsigned long size, sha2_ctx ctx[1]);
VOID_RETURN sha2_hash(const uint8_t data[], unsigned long len, sha2_ctx ctx[1]);
VOID_RETURN sha2_end(uint8_t hval[], sha2_ctx ctx[1]);
INT_RETURN sha2(uint8_t hval[], unsigned long size, const uint8_t data[], unsigned long len);
#endif
#if defined(__cplusplus)
}
#endif
#endif

206
src/utils/crypto/sk.h Normal file
View File

@@ -0,0 +1,206 @@
/* Deprecated/legacy */
/* crypto/des/sk.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
static const DES_LONG des_skb[8][64]={
{
/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
0x00000000L,0x00000010L,0x20000000L,0x20000010L,
0x00010000L,0x00010010L,0x20010000L,0x20010010L,
0x00000800L,0x00000810L,0x20000800L,0x20000810L,
0x00010800L,0x00010810L,0x20010800L,0x20010810L,
0x00000020L,0x00000030L,0x20000020L,0x20000030L,
0x00010020L,0x00010030L,0x20010020L,0x20010030L,
0x00000820L,0x00000830L,0x20000820L,0x20000830L,
0x00010820L,0x00010830L,0x20010820L,0x20010830L,
0x00080000L,0x00080010L,0x20080000L,0x20080010L,
0x00090000L,0x00090010L,0x20090000L,0x20090010L,
0x00080800L,0x00080810L,0x20080800L,0x20080810L,
0x00090800L,0x00090810L,0x20090800L,0x20090810L,
0x00080020L,0x00080030L,0x20080020L,0x20080030L,
0x00090020L,0x00090030L,0x20090020L,0x20090030L,
0x00080820L,0x00080830L,0x20080820L,0x20080830L,
0x00090820L,0x00090830L,0x20090820L,0x20090830L,
},{
/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
0x00000000L,0x02000000L,0x00002000L,0x02002000L,
0x00200000L,0x02200000L,0x00202000L,0x02202000L,
0x00000004L,0x02000004L,0x00002004L,0x02002004L,
0x00200004L,0x02200004L,0x00202004L,0x02202004L,
0x00000400L,0x02000400L,0x00002400L,0x02002400L,
0x00200400L,0x02200400L,0x00202400L,0x02202400L,
0x00000404L,0x02000404L,0x00002404L,0x02002404L,
0x00200404L,0x02200404L,0x00202404L,0x02202404L,
0x10000000L,0x12000000L,0x10002000L,0x12002000L,
0x10200000L,0x12200000L,0x10202000L,0x12202000L,
0x10000004L,0x12000004L,0x10002004L,0x12002004L,
0x10200004L,0x12200004L,0x10202004L,0x12202004L,
0x10000400L,0x12000400L,0x10002400L,0x12002400L,
0x10200400L,0x12200400L,0x10202400L,0x12202400L,
0x10000404L,0x12000404L,0x10002404L,0x12002404L,
0x10200404L,0x12200404L,0x10202404L,0x12202404L,
},{
/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
0x00000000L,0x00000001L,0x00040000L,0x00040001L,
0x01000000L,0x01000001L,0x01040000L,0x01040001L,
0x00000002L,0x00000003L,0x00040002L,0x00040003L,
0x01000002L,0x01000003L,0x01040002L,0x01040003L,
0x00000200L,0x00000201L,0x00040200L,0x00040201L,
0x01000200L,0x01000201L,0x01040200L,0x01040201L,
0x00000202L,0x00000203L,0x00040202L,0x00040203L,
0x01000202L,0x01000203L,0x01040202L,0x01040203L,
0x08000000L,0x08000001L,0x08040000L,0x08040001L,
0x09000000L,0x09000001L,0x09040000L,0x09040001L,
0x08000002L,0x08000003L,0x08040002L,0x08040003L,
0x09000002L,0x09000003L,0x09040002L,0x09040003L,
0x08000200L,0x08000201L,0x08040200L,0x08040201L,
0x09000200L,0x09000201L,0x09040200L,0x09040201L,
0x08000202L,0x08000203L,0x08040202L,0x08040203L,
0x09000202L,0x09000203L,0x09040202L,0x09040203L,
},{
/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
0x00000000L,0x00100000L,0x00000100L,0x00100100L,
0x00000008L,0x00100008L,0x00000108L,0x00100108L,
0x00001000L,0x00101000L,0x00001100L,0x00101100L,
0x00001008L,0x00101008L,0x00001108L,0x00101108L,
0x04000000L,0x04100000L,0x04000100L,0x04100100L,
0x04000008L,0x04100008L,0x04000108L,0x04100108L,
0x04001000L,0x04101000L,0x04001100L,0x04101100L,
0x04001008L,0x04101008L,0x04001108L,0x04101108L,
0x00020000L,0x00120000L,0x00020100L,0x00120100L,
0x00020008L,0x00120008L,0x00020108L,0x00120108L,
0x00021000L,0x00121000L,0x00021100L,0x00121100L,
0x00021008L,0x00121008L,0x00021108L,0x00121108L,
0x04020000L,0x04120000L,0x04020100L,0x04120100L,
0x04020008L,0x04120008L,0x04020108L,0x04120108L,
0x04021000L,0x04121000L,0x04021100L,0x04121100L,
0x04021008L,0x04121008L,0x04021108L,0x04121108L,
},{
/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
0x00000000L,0x10000000L,0x00010000L,0x10010000L,
0x00000004L,0x10000004L,0x00010004L,0x10010004L,
0x20000000L,0x30000000L,0x20010000L,0x30010000L,
0x20000004L,0x30000004L,0x20010004L,0x30010004L,
0x00100000L,0x10100000L,0x00110000L,0x10110000L,
0x00100004L,0x10100004L,0x00110004L,0x10110004L,
0x20100000L,0x30100000L,0x20110000L,0x30110000L,
0x20100004L,0x30100004L,0x20110004L,0x30110004L,
0x00001000L,0x10001000L,0x00011000L,0x10011000L,
0x00001004L,0x10001004L,0x00011004L,0x10011004L,
0x20001000L,0x30001000L,0x20011000L,0x30011000L,
0x20001004L,0x30001004L,0x20011004L,0x30011004L,
0x00101000L,0x10101000L,0x00111000L,0x10111000L,
0x00101004L,0x10101004L,0x00111004L,0x10111004L,
0x20101000L,0x30101000L,0x20111000L,0x30111000L,
0x20101004L,0x30101004L,0x20111004L,0x30111004L,
},{
/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
0x00000000L,0x08000000L,0x00000008L,0x08000008L,
0x00000400L,0x08000400L,0x00000408L,0x08000408L,
0x00020000L,0x08020000L,0x00020008L,0x08020008L,
0x00020400L,0x08020400L,0x00020408L,0x08020408L,
0x00000001L,0x08000001L,0x00000009L,0x08000009L,
0x00000401L,0x08000401L,0x00000409L,0x08000409L,
0x00020001L,0x08020001L,0x00020009L,0x08020009L,
0x00020401L,0x08020401L,0x00020409L,0x08020409L,
0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
},{
/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
0x00000000L,0x00000100L,0x00080000L,0x00080100L,
0x01000000L,0x01000100L,0x01080000L,0x01080100L,
0x00000010L,0x00000110L,0x00080010L,0x00080110L,
0x01000010L,0x01000110L,0x01080010L,0x01080110L,
0x00200000L,0x00200100L,0x00280000L,0x00280100L,
0x01200000L,0x01200100L,0x01280000L,0x01280100L,
0x00200010L,0x00200110L,0x00280010L,0x00280110L,
0x01200010L,0x01200110L,0x01280010L,0x01280110L,
0x00000200L,0x00000300L,0x00080200L,0x00080300L,
0x01000200L,0x01000300L,0x01080200L,0x01080300L,
0x00000210L,0x00000310L,0x00080210L,0x00080310L,
0x01000210L,0x01000310L,0x01080210L,0x01080310L,
0x00200200L,0x00200300L,0x00280200L,0x00280300L,
0x01200200L,0x01200300L,0x01280200L,0x01280300L,
0x00200210L,0x00200310L,0x00280210L,0x00280310L,
0x01200210L,0x01200310L,0x01280210L,0x01280310L,
},{
/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
0x00000000L,0x04000000L,0x00040000L,0x04040000L,
0x00000002L,0x04000002L,0x00040002L,0x04040002L,
0x00002000L,0x04002000L,0x00042000L,0x04042000L,
0x00002002L,0x04002002L,0x00042002L,0x04042002L,
0x00000020L,0x04000020L,0x00040020L,0x04040020L,
0x00000022L,0x04000022L,0x00040022L,0x04040022L,
0x00002020L,0x04002020L,0x00042020L,0x04042020L,
0x00002022L,0x04002022L,0x00042022L,0x04042022L,
0x00000800L,0x04000800L,0x00040800L,0x04040800L,
0x00000802L,0x04000802L,0x00040802L,0x04040802L,
0x00002800L,0x04002800L,0x00042800L,0x04042800L,
0x00002802L,0x04002802L,0x00042802L,0x04042802L,
0x00000820L,0x04000820L,0x00040820L,0x04040820L,
0x00000822L,0x04000822L,0x00040822L,0x04040822L,
0x00002820L,0x04002820L,0x00042820L,0x04042820L,
0x00002822L,0x04002822L,0x00042822L,0x04042822L,
}};

206
src/utils/crypto/spr.h Normal file
View File

@@ -0,0 +1,206 @@
/* Deprecated/legacy */
/* crypto/des/spr.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
const DES_LONG des_SPtrans[8][64]={
{
/* nibble 0 */
0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
},{
/* nibble 1 */
0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
},{
/* nibble 2 */
0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
},{
/* nibble 3 */
0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
},{
/* nibble 4 */
0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
},{
/* nibble 5 */
0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
},{
/* nibble 6 */
0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
},{
/* nibble 7 */
0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
}};

548
src/utils/crypto/twofish.c Normal file
View File

@@ -0,0 +1,548 @@
/*
---------------------------------------------------------------------------
Copyright (c) 1999, Dr Brian Gladman, Worcester, UK. All rights reserved.
LICENSE TERMS
The free distribution and use of this software is allowed (with or without
changes) provided that:
1. source code distributions include the above copyright notice, this
list of conditions and the following disclaimer;
2. binary distributions include the above copyright notice, this list
of conditions and the following disclaimer in their documentation;
3. the name of the copyright holder is not used to endorse products
built using this software without specific written permission.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
My thanks to Doug Whiting and Niels Ferguson for comments that led
to improvements in this implementation.
Issue Date: 14th January 1999
*/
/* Adapted for TrueCrypt by the TrueCrypt Foundation */
#ifdef TC_WINDOWS_BOOT
#pragma optimize ("tl", on)
#endif
#include "twofish.h"
#include "../common/endian.h"
#define Q_TABLES
#define M_TABLE
#if !defined (TC_MINIMIZE_CODE_SIZE) || defined (TC_WINDOWS_BOOT_TWOFISH)
# define MK_TABLE
# define ONE_STEP
#endif
/* finite field arithmetic for GF(2**8) with the modular */
/* polynomial x^8 + x^6 + x^5 + x^3 + 1 (0x169) */
#define G_M 0x0169
static u1byte tab_5b[4] = { 0, G_M >> 2, G_M >> 1, (G_M >> 1) ^ (G_M >> 2) };
static u1byte tab_ef[4] = { 0, (G_M >> 1) ^ (G_M >> 2), G_M >> 1, G_M >> 2 };
#define ffm_01(x) (x)
#define ffm_5b(x) ((x) ^ ((x) >> 2) ^ tab_5b[(x) & 3])
#define ffm_ef(x) ((x) ^ ((x) >> 1) ^ ((x) >> 2) ^ tab_ef[(x) & 3])
static u1byte ror4[16] = { 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15 };
static u1byte ashx[16] = { 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 5, 14, 7 };
static u1byte qt0[2][16] =
{ { 8, 1, 7, 13, 6, 15, 3, 2, 0, 11, 5, 9, 14, 12, 10, 4 },
{ 2, 8, 11, 13, 15, 7, 6, 14, 3, 1, 9, 4, 0, 10, 12, 5 }
};
static u1byte qt1[2][16] =
{ { 14, 12, 11, 8, 1, 2, 3, 5, 15, 4, 10, 6, 7, 0, 9, 13 },
{ 1, 14, 2, 11, 4, 12, 3, 7, 6, 13, 10, 5, 15, 9, 0, 8 }
};
static u1byte qt2[2][16] =
{ { 11, 10, 5, 14, 6, 13, 9, 0, 12, 8, 15, 3, 2, 4, 7, 1 },
{ 4, 12, 7, 5, 1, 6, 9, 10, 0, 14, 13, 8, 2, 11, 3, 15 }
};
static u1byte qt3[2][16] =
{ { 13, 7, 15, 4, 1, 2, 6, 14, 9, 11, 3, 0, 8, 5, 12, 10 },
{ 11, 9, 5, 1, 12, 3, 13, 14, 6, 4, 7, 15, 2, 0, 8, 10 }
};
static u1byte qp(const u4byte n, const u1byte x)
{ u1byte a0, a1, a2, a3, a4, b0, b1, b2, b3, b4;
a0 = x >> 4; b0 = x & 15;
a1 = a0 ^ b0; b1 = ror4[b0] ^ ashx[a0];
a2 = qt0[n][a1]; b2 = qt1[n][b1];
a3 = a2 ^ b2; b3 = ror4[b2] ^ ashx[a2];
a4 = qt2[n][a3]; b4 = qt3[n][b3];
return (b4 << 4) | a4;
};
#ifdef Q_TABLES
static u4byte qt_gen = 0;
static u1byte q_tab[2][256];
#define q(n,x) q_tab[n][x]
static void gen_qtab(void)
{ u4byte i;
for(i = 0; i < 256; ++i)
{
q(0,i) = qp(0, (u1byte)i);
q(1,i) = qp(1, (u1byte)i);
}
};
#else
#define q(n,x) qp(n, x)
#endif
#ifdef M_TABLE
static u4byte mt_gen = 0;
static u4byte m_tab[4][256];
static void gen_mtab(void)
{ u4byte i, f01, f5b, fef;
for(i = 0; i < 256; ++i)
{
f01 = q(1,i); f5b = ffm_5b(f01); fef = ffm_ef(f01);
m_tab[0][i] = f01 + (f5b << 8) + (fef << 16) + (fef << 24);
m_tab[2][i] = f5b + (fef << 8) + (f01 << 16) + (fef << 24);
f01 = q(0,i); f5b = ffm_5b(f01); fef = ffm_ef(f01);
m_tab[1][i] = fef + (fef << 8) + (f5b << 16) + (f01 << 24);
m_tab[3][i] = f5b + (f01 << 8) + (fef << 16) + (f5b << 24);
}
};
#define mds(n,x) m_tab[n][x]
#else
#define fm_00 ffm_01
#define fm_10 ffm_5b
#define fm_20 ffm_ef
#define fm_30 ffm_ef
#define q_0(x) q(1,x)
#define fm_01 ffm_ef
#define fm_11 ffm_ef
#define fm_21 ffm_5b
#define fm_31 ffm_01
#define q_1(x) q(0,x)
#define fm_02 ffm_5b
#define fm_12 ffm_ef
#define fm_22 ffm_01
#define fm_32 ffm_ef
#define q_2(x) q(1,x)
#define fm_03 ffm_5b
#define fm_13 ffm_01
#define fm_23 ffm_ef
#define fm_33 ffm_5b
#define q_3(x) q(0,x)
#define f_0(n,x) ((u4byte)fm_0##n(x))
#define f_1(n,x) ((u4byte)fm_1##n(x) << 8)
#define f_2(n,x) ((u4byte)fm_2##n(x) << 16)
#define f_3(n,x) ((u4byte)fm_3##n(x) << 24)
#define mds(n,x) f_0(n,q_##n(x)) ^ f_1(n,q_##n(x)) ^ f_2(n,q_##n(x)) ^ f_3(n,q_##n(x))
#endif
static u4byte h_fun(TwofishInstance *instance, const u4byte x, const u4byte key[])
{ u4byte b0, b1, b2, b3;
#ifndef M_TABLE
u4byte m5b_b0, m5b_b1, m5b_b2, m5b_b3;
u4byte mef_b0, mef_b1, mef_b2, mef_b3;
#endif
b0 = extract_byte(x, 0); b1 = extract_byte(x, 1); b2 = extract_byte(x, 2); b3 = extract_byte(x, 3);
switch(instance->k_len)
{
case 4: b0 = q(1, (u1byte) b0) ^ extract_byte(key[3],0);
b1 = q(0, (u1byte) b1) ^ extract_byte(key[3],1);
b2 = q(0, (u1byte) b2) ^ extract_byte(key[3],2);
b3 = q(1, (u1byte) b3) ^ extract_byte(key[3],3);
case 3: b0 = q(1, (u1byte) b0) ^ extract_byte(key[2],0);
b1 = q(1, (u1byte) b1) ^ extract_byte(key[2],1);
b2 = q(0, (u1byte) b2) ^ extract_byte(key[2],2);
b3 = q(0, (u1byte) b3) ^ extract_byte(key[2],3);
case 2: b0 = q(0, (u1byte) (q(0, (u1byte) b0) ^ extract_byte(key[1],0))) ^ extract_byte(key[0],0);
b1 = q(0, (u1byte) (q(1, (u1byte) b1) ^ extract_byte(key[1],1))) ^ extract_byte(key[0],1);
b2 = q(1, (u1byte) (q(0, (u1byte) b2) ^ extract_byte(key[1],2))) ^ extract_byte(key[0],2);
b3 = q(1, (u1byte) (q(1, (u1byte) b3) ^ extract_byte(key[1],3))) ^ extract_byte(key[0],3);
}
#ifdef M_TABLE
return mds(0, b0) ^ mds(1, b1) ^ mds(2, b2) ^ mds(3, b3);
#else
b0 = q(1, (u1byte) b0); b1 = q(0, (u1byte) b1); b2 = q(1, (u1byte) b2); b3 = q(0, (u1byte) b3);
m5b_b0 = ffm_5b(b0); m5b_b1 = ffm_5b(b1); m5b_b2 = ffm_5b(b2); m5b_b3 = ffm_5b(b3);
mef_b0 = ffm_ef(b0); mef_b1 = ffm_ef(b1); mef_b2 = ffm_ef(b2); mef_b3 = ffm_ef(b3);
b0 ^= mef_b1 ^ m5b_b2 ^ m5b_b3; b3 ^= m5b_b0 ^ mef_b1 ^ mef_b2;
b2 ^= mef_b0 ^ m5b_b1 ^ mef_b3; b1 ^= mef_b0 ^ mef_b2 ^ m5b_b3;
return b0 | (b3 << 8) | (b2 << 16) | (b1 << 24);
#endif
};
#ifdef MK_TABLE
#ifdef ONE_STEP
//u4byte mk_tab[4][256];
#else
static u1byte sb[4][256];
#endif
#define q20(x) q(0,q(0,x) ^ extract_byte(key[1],0)) ^ extract_byte(key[0],0)
#define q21(x) q(0,q(1,x) ^ extract_byte(key[1],1)) ^ extract_byte(key[0],1)
#define q22(x) q(1,q(0,x) ^ extract_byte(key[1],2)) ^ extract_byte(key[0],2)
#define q23(x) q(1,q(1,x) ^ extract_byte(key[1],3)) ^ extract_byte(key[0],3)
#define q30(x) q(0,q(0,q(1, x) ^ extract_byte(key[2],0)) ^ extract_byte(key[1],0)) ^ extract_byte(key[0],0)
#define q31(x) q(0,q(1,q(1, x) ^ extract_byte(key[2],1)) ^ extract_byte(key[1],1)) ^ extract_byte(key[0],1)
#define q32(x) q(1,q(0,q(0, x) ^ extract_byte(key[2],2)) ^ extract_byte(key[1],2)) ^ extract_byte(key[0],2)
#define q33(x) q(1,q(1,q(0, x) ^ extract_byte(key[2],3)) ^ extract_byte(key[1],3)) ^ extract_byte(key[0],3)
#define q40(x) q(0,q(0,q(1, q(1, x) ^ extract_byte(key[3],0)) ^ extract_byte(key[2],0)) ^ extract_byte(key[1],0)) ^ extract_byte(key[0],0)
#define q41(x) q(0,q(1,q(1, q(0, x) ^ extract_byte(key[3],1)) ^ extract_byte(key[2],1)) ^ extract_byte(key[1],1)) ^ extract_byte(key[0],1)
#define q42(x) q(1,q(0,q(0, q(0, x) ^ extract_byte(key[3],2)) ^ extract_byte(key[2],2)) ^ extract_byte(key[1],2)) ^ extract_byte(key[0],2)
#define q43(x) q(1,q(1,q(0, q(1, x) ^ extract_byte(key[3],3)) ^ extract_byte(key[2],3)) ^ extract_byte(key[1],3)) ^ extract_byte(key[0],3)
static void gen_mk_tab(TwofishInstance *instance, u4byte key[])
{ u4byte i;
u1byte by;
u4byte *mk_tab = instance->mk_tab;
switch(instance->k_len)
{
case 2: for(i = 0; i < 256; ++i)
{
by = (u1byte)i;
#ifdef ONE_STEP
mk_tab[0 + 4*i] = mds(0, q20(by)); mk_tab[1 + 4*i] = mds(1, q21(by));
mk_tab[2 + 4*i] = mds(2, q22(by)); mk_tab[3 + 4*i] = mds(3, q23(by));
#else
sb[0][i] = q20(by); sb[1][i] = q21(by);
sb[2][i] = q22(by); sb[3][i] = q23(by);
#endif
}
break;
case 3: for(i = 0; i < 256; ++i)
{
by = (u1byte)i;
#ifdef ONE_STEP
mk_tab[0 + 4*i] = mds(0, q30(by)); mk_tab[1 + 4*i] = mds(1, q31(by));
mk_tab[2 + 4*i] = mds(2, q32(by)); mk_tab[3 + 4*i] = mds(3, q33(by));
#else
sb[0][i] = q30(by); sb[1][i] = q31(by);
sb[2][i] = q32(by); sb[3][i] = q33(by);
#endif
}
break;
case 4: for(i = 0; i < 256; ++i)
{
by = (u1byte)i;
#ifdef ONE_STEP
mk_tab[0 + 4*i] = mds(0, q40(by)); mk_tab[1 + 4*i] = mds(1, q41(by));
mk_tab[2 + 4*i] = mds(2, q42(by)); mk_tab[3 + 4*i] = mds(3, q43(by));
#else
sb[0][i] = q40(by); sb[1][i] = q41(by);
sb[2][i] = q42(by); sb[3][i] = q43(by);
#endif
}
}
};
# ifdef ONE_STEP
# define g0_fun(x) ( mk_tab[0 + 4*extract_byte(x,0)] ^ mk_tab[1 + 4*extract_byte(x,1)] \
^ mk_tab[2 + 4*extract_byte(x,2)] ^ mk_tab[3 + 4*extract_byte(x,3)] )
# define g1_fun(x) ( mk_tab[0 + 4*extract_byte(x,3)] ^ mk_tab[1 + 4*extract_byte(x,0)] \
^ mk_tab[2 + 4*extract_byte(x,1)] ^ mk_tab[3 + 4*extract_byte(x,2)] )
# else
# define g0_fun(x) ( mds(0, sb[0][extract_byte(x,0)]) ^ mds(1, sb[1][extract_byte(x,1)]) \
^ mds(2, sb[2][extract_byte(x,2)]) ^ mds(3, sb[3][extract_byte(x,3)]) )
# define g1_fun(x) ( mds(0, sb[0][extract_byte(x,3)]) ^ mds(1, sb[1][extract_byte(x,0)]) \
^ mds(2, sb[2][extract_byte(x,1)]) ^ mds(3, sb[3][extract_byte(x,2)]) )
# endif
#else
#define g0_fun(x) h_fun(instance, x, instance->s_key)
#define g1_fun(x) h_fun(instance, rotl(x,8), instance->s_key)
#endif
/* The (12,8) Reed Soloman code has the generator polynomial
g(x) = x^4 + (a + 1/a) * x^3 + a * x^2 + (a + 1/a) * x + 1
where the coefficients are in the finite field GF(2^8) with a
modular polynomial a^8 + a^6 + a^3 + a^2 + 1. To generate the
remainder we have to start with a 12th order polynomial with our
eight input bytes as the coefficients of the 4th to 11th terms.
That is:
m[7] * x^11 + m[6] * x^10 ... + m[0] * x^4 + 0 * x^3 +... + 0
We then multiply the generator polynomial by m[7] * x^7 and subtract
it - xor in GF(2^8) - from the above to eliminate the x^7 term (the
artihmetic on the coefficients is done in GF(2^8). We then multiply
the generator polynomial by x^6 * coeff(x^10) and use this to remove
the x^10 term. We carry on in this way until the x^4 term is removed
so that we are left with:
r[3] * x^3 + r[2] * x^2 + r[1] 8 x^1 + r[0]
which give the resulting 4 bytes of the remainder. This is equivalent
to the matrix multiplication in the Twofish description but much faster
to implement.
*/
#define G_MOD 0x0000014d
static u4byte mds_rem(u4byte p0, u4byte p1)
{ u4byte i, t, u;
for(i = 0; i < 8; ++i)
{
t = p1 >> 24; // get most significant coefficient
p1 = (p1 << 8) | (p0 >> 24); p0 <<= 8; // shift others up
// multiply t by a (the primitive element - i.e. left shift)
u = (t << 1);
if(t & 0x80) // subtract modular polynomial on overflow
u ^= G_MOD;
p1 ^= t ^ (u << 16); // remove t * (a * x^2 + 1)
u ^= (t >> 1); // form u = a * t + t / a = t * (a + 1 / a);
if(t & 0x01) // add the modular polynomial on underflow
u ^= G_MOD >> 1;
p1 ^= (u << 24) | (u << 8); // remove t * (a + 1/a) * (x^3 + x)
}
return p1;
};
/* initialise the key schedule from the user supplied key */
u4byte *twofish_set_key(TwofishInstance *instance, const u4byte in_key[], const u4byte key_len)
{ u4byte i, a, b, me_key[4], mo_key[4];
u4byte *l_key, *s_key;
l_key = instance->l_key;
s_key = instance->s_key;
#ifdef Q_TABLES
if(!qt_gen)
{
gen_qtab(); qt_gen = 1;
}
#endif
#ifdef M_TABLE
if(!mt_gen)
{
gen_mtab(); mt_gen = 1;
}
#endif
instance->k_len = key_len / 64; /* 2, 3 or 4 */
for(i = 0; i < instance->k_len; ++i)
{
a = LE32(in_key[i + i]); me_key[i] = a;
b = LE32(in_key[i + i + 1]); mo_key[i] = b;
s_key[instance->k_len - i - 1] = mds_rem(a, b);
}
for(i = 0; i < 40; i += 2)
{
a = 0x01010101 * i; b = a + 0x01010101;
a = h_fun(instance, a, me_key);
b = rotl(h_fun(instance, b, mo_key), 8);
l_key[i] = a + b;
l_key[i + 1] = rotl(a + 2 * b, 9);
}
#ifdef MK_TABLE
gen_mk_tab(instance, s_key);
#endif
return l_key;
};
/* encrypt a block of text */
#ifndef TC_MINIMIZE_CODE_SIZE
#define f_rnd(i) \
t1 = g1_fun(blk[1]); t0 = g0_fun(blk[0]); \
blk[2] = rotr(blk[2] ^ (t0 + t1 + l_key[4 * (i) + 8]), 1); \
blk[3] = rotl(blk[3], 1) ^ (t0 + 2 * t1 + l_key[4 * (i) + 9]); \
t1 = g1_fun(blk[3]); t0 = g0_fun(blk[2]); \
blk[0] = rotr(blk[0] ^ (t0 + t1 + l_key[4 * (i) + 10]), 1); \
blk[1] = rotl(blk[1], 1) ^ (t0 + 2 * t1 + l_key[4 * (i) + 11])
void twofish_encrypt(TwofishInstance *instance, const u4byte in_blk[4], u4byte out_blk[])
{ u4byte t0, t1, blk[4];
u4byte *l_key = instance->l_key;
u4byte *mk_tab = instance->mk_tab;
blk[0] = LE32(in_blk[0]) ^ l_key[0];
blk[1] = LE32(in_blk[1]) ^ l_key[1];
blk[2] = LE32(in_blk[2]) ^ l_key[2];
blk[3] = LE32(in_blk[3]) ^ l_key[3];
f_rnd(0); f_rnd(1); f_rnd(2); f_rnd(3);
f_rnd(4); f_rnd(5); f_rnd(6); f_rnd(7);
out_blk[0] = LE32(blk[2] ^ l_key[4]);
out_blk[1] = LE32(blk[3] ^ l_key[5]);
out_blk[2] = LE32(blk[0] ^ l_key[6]);
out_blk[3] = LE32(blk[1] ^ l_key[7]);
};
#else // TC_MINIMIZE_CODE_SIZE
void twofish_encrypt(TwofishInstance *instance, const u4byte in_blk[4], u4byte out_blk[])
{ u4byte t0, t1, blk[4];
u4byte *l_key = instance->l_key;
#ifdef TC_WINDOWS_BOOT_TWOFISH
u4byte *mk_tab = instance->mk_tab;
#endif
int i;
blk[0] = LE32(in_blk[0]) ^ l_key[0];
blk[1] = LE32(in_blk[1]) ^ l_key[1];
blk[2] = LE32(in_blk[2]) ^ l_key[2];
blk[3] = LE32(in_blk[3]) ^ l_key[3];
for (i = 0; i <= 7; ++i)
{
t1 = g1_fun(blk[1]); t0 = g0_fun(blk[0]);
blk[2] = rotr(blk[2] ^ (t0 + t1 + l_key[4 * (i) + 8]), 1);
blk[3] = rotl(blk[3], 1) ^ (t0 + 2 * t1 + l_key[4 * (i) + 9]);
t1 = g1_fun(blk[3]); t0 = g0_fun(blk[2]);
blk[0] = rotr(blk[0] ^ (t0 + t1 + l_key[4 * (i) + 10]), 1);
blk[1] = rotl(blk[1], 1) ^ (t0 + 2 * t1 + l_key[4 * (i) + 11]);
}
out_blk[0] = LE32(blk[2] ^ l_key[4]);
out_blk[1] = LE32(blk[3] ^ l_key[5]);
out_blk[2] = LE32(blk[0] ^ l_key[6]);
out_blk[3] = LE32(blk[1] ^ l_key[7]);
};
#endif // TC_MINIMIZE_CODE_SIZE
/* decrypt a block of text */
#ifndef TC_MINIMIZE_CODE_SIZE
#define i_rnd(i) \
t1 = g1_fun(blk[1]); t0 = g0_fun(blk[0]); \
blk[2] = rotl(blk[2], 1) ^ (t0 + t1 + l_key[4 * (i) + 10]); \
blk[3] = rotr(blk[3] ^ (t0 + 2 * t1 + l_key[4 * (i) + 11]), 1); \
t1 = g1_fun(blk[3]); t0 = g0_fun(blk[2]); \
blk[0] = rotl(blk[0], 1) ^ (t0 + t1 + l_key[4 * (i) + 8]); \
blk[1] = rotr(blk[1] ^ (t0 + 2 * t1 + l_key[4 * (i) + 9]), 1)
void twofish_decrypt(TwofishInstance *instance, const u4byte in_blk[4], u4byte out_blk[4])
{ u4byte t0, t1, blk[4];
u4byte *l_key = instance->l_key;
u4byte *mk_tab = instance->mk_tab;
blk[0] = LE32(in_blk[0]) ^ l_key[4];
blk[1] = LE32(in_blk[1]) ^ l_key[5];
blk[2] = LE32(in_blk[2]) ^ l_key[6];
blk[3] = LE32(in_blk[3]) ^ l_key[7];
i_rnd(7); i_rnd(6); i_rnd(5); i_rnd(4);
i_rnd(3); i_rnd(2); i_rnd(1); i_rnd(0);
out_blk[0] = LE32(blk[2] ^ l_key[0]);
out_blk[1] = LE32(blk[3] ^ l_key[1]);
out_blk[2] = LE32(blk[0] ^ l_key[2]);
out_blk[3] = LE32(blk[1] ^ l_key[3]);
};
#else // TC_MINIMIZE_CODE_SIZE
void twofish_decrypt(TwofishInstance *instance, const u4byte in_blk[4], u4byte out_blk[4])
{ u4byte t0, t1, blk[4];
u4byte *l_key = instance->l_key;
#ifdef TC_WINDOWS_BOOT_TWOFISH
u4byte *mk_tab = instance->mk_tab;
#endif
int i;
blk[0] = LE32(in_blk[0]) ^ l_key[4];
blk[1] = LE32(in_blk[1]) ^ l_key[5];
blk[2] = LE32(in_blk[2]) ^ l_key[6];
blk[3] = LE32(in_blk[3]) ^ l_key[7];
for (i = 7; i >= 0; --i)
{
t1 = g1_fun(blk[1]); t0 = g0_fun(blk[0]);
blk[2] = rotl(blk[2], 1) ^ (t0 + t1 + l_key[4 * (i) + 10]);
blk[3] = rotr(blk[3] ^ (t0 + 2 * t1 + l_key[4 * (i) + 11]), 1);
t1 = g1_fun(blk[3]); t0 = g0_fun(blk[2]);
blk[0] = rotl(blk[0], 1) ^ (t0 + t1 + l_key[4 * (i) + 8]);
blk[1] = rotr(blk[1] ^ (t0 + 2 * t1 + l_key[4 * (i) + 9]), 1);
}
out_blk[0] = LE32(blk[2] ^ l_key[0]);
out_blk[1] = LE32(blk[3] ^ l_key[1]);
out_blk[2] = LE32(blk[0] ^ l_key[2]);
out_blk[3] = LE32(blk[1] ^ l_key[3]);
};
#endif // TC_MINIMIZE_CODE_SIZE

View File

@@ -0,0 +1,56 @@
#ifndef TWOFISH_H
#define TWOFISH_H
#include <inttypes.h>
#if defined(__cplusplus)
extern "C"
{
#endif
#ifndef u4byte
#define u4byte uint32_t
#endif
#ifndef u1byte
#define u1byte uint8_t
#endif
#ifndef extract_byte
#define extract_byte(x,n) ((u1byte)((x) >> (8 * n)))
#endif
#ifndef rotl
#ifdef _WIN32
#include <stdlib.h>
// #pragma intrinsic(_lrotr,_lrotl)
#define rotr(x,n) _lrotr(x,n)
#define rotl(x,n) _lrotl(x,n)
#else
#define rotr(x,n) (((x)>>(n))|((x)<<(32-(n))))
#define rotl(x,n) (((x)<<(n))|((x)>>(32-(n))))
#endif
#endif
typedef struct
{
u4byte l_key[40];
u4byte s_key[4];
#if !defined (TC_MINIMIZE_CODE_SIZE) || defined (TC_WINDOWS_BOOT_TWOFISH)
u4byte mk_tab[4 * 256];
#endif
u4byte k_len;
} TwofishInstance;
#define TWOFISH_KS sizeof(TwofishInstance)
u4byte * twofish_set_key(TwofishInstance *instance, const u4byte in_key[], const u4byte key_len);
void twofish_encrypt(TwofishInstance *instance, const u4byte in_blk[4], u4byte out_blk[]);
void twofish_decrypt(TwofishInstance *instance, const u4byte in_blk[4], u4byte out_blk[4]);
#if defined(__cplusplus)
}
#endif
#endif // TWOFISH_H

1058
src/utils/crypto/whirlpool.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,150 @@
#ifndef WHIRLPOOL_H
#define WHIRLPOOL_H 1
#if defined(__cplusplus)
extern "C"
{
#endif
#ifndef PORTABLE_C__
#define PORTABLE_C__
#include <inttypes.h>
#include <limits.h>
/* Definition of minimum-width integer types
*
* u8 -> unsigned integer type, at least 8 bits, equivalent to unsigned char
* u16 -> unsigned integer type, at least 16 bits
* u32 -> unsigned integer type, at least 32 bits
*
* s8, s16, s32 -> signed counterparts of u8, u16, u32
*
* Always use macro's T8(), T16() or T32() to obtain exact-width results,
* i.e., to specify the size of the result of each expression.
*/
typedef int8_t s8;
typedef uint8_t u8;
#if UINT_MAX >= 4294967295UL
typedef int16_t s16;
typedef int32_t s32;
typedef uint16_t u16;
typedef uint32_t u32;
#define ONE32 0xffffffffU
#else
typedef int16_t s16;
typedef int32_t s32;
typedef uint16_t u16;
typedef uint32_t u32;
#define ONE32 0xffffffffUL
#endif
#define ONE8 0xffU
#define ONE16 0xffffU
#define T8(x) ((x) & ONE8)
#define T16(x) ((x) & ONE16)
#define T32(x) ((x) & ONE32)
#ifdef _MSC_VER
typedef uint64_t u64;
typedef int64_t s64;
#define LL(v) (v##i64)
#define ONE64 LL(0xffffffffffffffff)
#else /* !_MSC_VER */
typedef uint64_t u64;
typedef int64_t s64;
#define LL(v) (v##ULL)
#define ONE64 LL(0xffffffffffffffff)
#endif /* ?_MSC_VER */
#define T64(x) ((x) & ONE64)
#define ROTR64(v, n) (((v) >> (n)) | T64((v) << (64 - (n))))
/*
* Note: the test is used to detect native 64-bit architectures;
* if the unsigned long is strictly greater than 32-bit, it is
* assumed to be at least 64-bit. This will not work correctly
* on (old) 36-bit architectures (PDP-11 for instance).
*
* On non-64-bit architectures, "long long" is used.
*/
/*
* U8TO32_BIG(c) returns the 32-bit value stored in big-endian convention
* in the unsigned char array pointed to by c.
*/
#define U8TO32_BIG(c) (((u32)T8(*(c)) << 24) | ((u32)T8(*((c) + 1)) << 16) | ((u32)T8(*((c) + 2)) << 8) | ((u32)T8(*((c) + 3))))
/*
* U8TO32_LITTLE(c) returns the 32-bit value stored in little-endian convention
* in the unsigned char array pointed to by c.
*/
#define U8TO32_LITTLE(c) (((u32)T8(*(c))) | ((u32)T8(*((c) + 1)) << 8) | (u32)T8(*((c) + 2)) << 16) | ((u32)T8(*((c) + 3)) << 24))
/*
* U8TO32_BIG(c, v) stores the 32-bit-value v in big-endian convention
* into the unsigned char array pointed to by c.
*/
#define U32TO8_BIG(c, v) do { u32 x = (v); u8 *d = (c); d[0] = T8(x >> 24); d[1] = T8(x >> 16); d[2] = T8(x >> 8); d[3] = T8(x); } while (0)
/*
* U8TO32_LITTLE(c, v) stores the 32-bit-value v in little-endian convention
* into the unsigned char array pointed to by c.
*/
#define U32TO8_LITTLE(c, v) do { u32 x = (v); u8 *d = (c); d[0] = T8(x); d[1] = T8(x >> 8); d[2] = T8(x >> 16); d[3] = T8(x >> 24); } while (0)
/*
* ROTL32(v, n) returns the value of the 32-bit unsigned value v after
* a rotation of n bits to the left. It might be replaced by the appropriate
* architecture-specific macro.
*
* It evaluates v and n twice.
*
* The compiler might emit a warning if n is the constant 0. The result
* is undefined if n is greater than 31.
*/
#define ROTL32(v, n) (T32((v) << (n)) | ((v) >> (32 - (n))))
/*
* Whirlpool-specific definitions.
*/
#define DIGESTBYTES 64
#define DIGESTBITS (8*DIGESTBYTES) /* 512 */
#define WBLOCKBYTES 64
#define WBLOCKBITS (8*WBLOCKBYTES) /* 512 */
#define LENGTHBYTES 32
#define LENGTHBITS (8*LENGTHBYTES) /* 256 */
typedef struct NESSIEstruct {
u8 bitLength[LENGTHBYTES]; /* global number of hashed bits (256-bit counter) */
u8 buffer[WBLOCKBYTES]; /* buffer of data to hash */
int bufferBits; /* current number of bits on the buffer */
int bufferPos; /* current (possibly incomplete) byte slot on the buffer */
u64 hash[DIGESTBYTES/8]; /* the hashing state */
} NESSIEstruct;
#endif /* PORTABLE_C__ */
// -------------
typedef NESSIEstruct WHIRLPOOL_CTX;
void WHIRLPOOL_add(const uint8_t * const source, uint32_t sourceBits, struct NESSIEstruct * const structpointer);
void WHIRLPOOL_finalize(struct NESSIEstruct * const structpointer, uint8_t * const result);
void WHIRLPOOL_init(struct NESSIEstruct * const structpointer);
#if defined(__cplusplus)
}
#endif
#endif /* WHIRLPOOL_H */

462
src/utils/decode.c Normal file
View File

@@ -0,0 +1,462 @@
#include "mds.h"
#include "edc.h"
#include "common/tcdefs.h"
#include "common/crypto.h"
#include "common/endian.h"
#include "common/pkcs5.h"
#include "common/crc.h"
#include <string.h>
void unshuffle1(u8 *data)
{
u32 val = getEDC(data, 0x40) ^ 0x567372ff;
for(int i = 0; i < 0x40; i += 4)
{
val = (val * 0x35e85a6d) + 0x1548dce9;
u32 ud = getU32(data + i);
setU32(data + i, ud ^ val ^ 0xec564717);
if (data[i] == 0)
data[i] = 0x5f;
if (data[i+1] == 0)
data[i+1] = 0x5f;
if (data[i+2] == 0)
data[i+2] = 0x5f;
if (data[i+3] == 0)
data[i+3] = 0x5f;
}
}
void DecryptBlock(u8 *buf,
TC_LARGEST_COMPILER_UINT len,
u32 secSz,
u64 secN,
u8 flags,
PCRYPTO_INFO cryptoInfo)
{
const int blockSize = CipherGetBlockSize( EAGetFirstCipher(cryptoInfo->ea) );
u64 blk = 0x200;
if (blockSize <= secSz)
blk = secSz;
const u64 asz = blk - (blk % blockSize);
if ((flags & 4) == 0)
{
const u32 c = len / blk;
for (int i = 0; i < c; i++)
{
DecryptBuffer(buf + i * blk, asz, asz, secN + i, flags, cryptoInfo);
}
}
else
{
u32 adsz = len - (len % blockSize);
u64 pos = 0;
int i = 0;
while(adsz > 0)
{
u32 bsz = asz;
if (adsz <= asz)
bsz = adsz;
DecryptBuffer(buf + pos, bsz, adsz, secN + i, flags, cryptoInfo);
pos += bsz;
adsz -= bsz;
i++;
}
}
}
// From volumes.c + modifies
#define HEADER_OFFSET_CRC 64
#define HEADER_OFFSET_MAGIC 68
#define HEADER_OFFSET_DATA 80
#define HEADER_DATA_SIZE 0x100
#define HEADER_OFFSET_DATASZ 74
uint16 GetHeaderField16 (byte *header, size_t offset)
{
/* modify BE->LE */
return LE16 (*(uint16 *) (header + offset));
}
uint32 GetHeaderField32 (byte *header, size_t offset)
{
/* modify BE->LE */
return LE32 (*(uint32 *) (header + offset));
}
UINT64_STRUCT GetHeaderField64 (byte *header, size_t offset)
{
/* modify BE->LE */
UINT64_STRUCT uint64Struct;
#ifndef TC_NO_COMPILER_INT64
uint64Struct.Value = LE64 (*(uint64 *) (header + offset));
#else
uint64Struct.HighPart = LE32 (*(uint32 *) (header + offset));
uint64Struct.LowPart = LE32 (*(uint32 *) (header + offset + 4));
#endif
return uint64Struct;
}
int ReadHeader (int bBoot, char *encryptedHeader, Password *password, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo)
{
char header[HEADER_SIZE];
KEY_INFO keyInfo;
PCRYPTO_INFO cryptoInfo;
char dk[MASTER_KEYDATA_SIZE];
int pkcs5_prf;
int status;
int primaryKeyOffset;
if (retHeaderCryptoInfo != NULL)
{
cryptoInfo = retHeaderCryptoInfo;
}
else
{
cryptoInfo = *retInfo = crypto_open ();
if (cryptoInfo == NULL)
return ERR_OUTOFMEMORY;
}
crypto_loadkey (&keyInfo, (char *) password->Text, (int) password->Length);
// PKCS5 is used to derive the primary header key(s) and secondary header key(s) (XTS mode) from the password
memcpy (keyInfo.salt, encryptedHeader + HEADER_SALT_OFFSET, PKCS5_SALT_SIZE);
memset(dk, 0, sizeof(dk));
// Use this legacy incorrect(for XTS) size, because Daemon Tools use it in this way
// seems DTools manual upgrade their pre-TrueCrypt5.0 sources
int keysize = EAGetLargestKey() + LEGACY_VOL_IV_SIZE;
// Test only rp160/sha1/whirlpool only
for (pkcs5_prf = FIRST_PRF_ID; pkcs5_prf <= WHIRLPOOL; pkcs5_prf++)
{
int lrw64InitDone = 0; // Deprecated/legacy
int lrw128InitDone = 0; // Deprecated/legacy
keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, bBoot);
switch (pkcs5_prf)
{
case RIPEMD160:
derive_key_ripemd160 ((char *) keyInfo.userKey, keyInfo.keyLength, (char *) keyInfo.salt,
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, keysize);
break;
case SHA1:
// Deprecated/legacy
derive_key_sha1 ((char *) keyInfo.userKey, keyInfo.keyLength, (char *) keyInfo.salt,
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, keysize);
break;
case WHIRLPOOL:
derive_key_whirlpool ((char *) keyInfo.userKey, keyInfo.keyLength, (char *) keyInfo.salt,
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, keysize);
break;
default:
// Unknown/wrong ID
TC_THROW_FATAL_EXCEPTION;
}
// Test all available modes of operation
for (cryptoInfo->mode = FIRST_MODE_OF_OPERATION_ID;
cryptoInfo->mode <= LAST_MODE_OF_OPERATION;
cryptoInfo->mode++)
{
switch (cryptoInfo->mode)
{
case LRW:
case CBC:
case INNER_CBC:
case OUTER_CBC:
// For LRW (deprecated/legacy), copy the tweak key
// For CBC (deprecated/legacy), copy the IV/whitening seed
memcpy (cryptoInfo->k2, dk, LEGACY_VOL_IV_SIZE);
primaryKeyOffset = LEGACY_VOL_IV_SIZE;
break;
default:
primaryKeyOffset = 0;
}
// Test all available encryption algorithms
for (cryptoInfo->ea = EAGetFirst ();
cryptoInfo->ea != 0;
cryptoInfo->ea = EAGetNext (cryptoInfo->ea))
{
int blockSize;
if (!EAIsModeSupported (cryptoInfo->ea, cryptoInfo->mode))
continue; // This encryption algorithm has never been available with this mode of operation
blockSize = CipherGetBlockSize (EAGetFirstCipher (cryptoInfo->ea));
status = EAInit (cryptoInfo->ea, (unsigned char *) (dk + primaryKeyOffset), cryptoInfo->ks);
if (status == ERR_CIPHER_INIT_FAILURE)
goto err;
// Init objects related to the mode of operation
if (cryptoInfo->mode == XTS)
{
// Copy the secondary key (if cascade, multiple concatenated)
memcpy (cryptoInfo->k2, dk + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
// Secondary key schedule
if (!EAInitMode (cryptoInfo))
{
status = ERR_MODE_INIT_FAILED;
goto err;
}
}
else if (cryptoInfo->mode == LRW
&& ((blockSize == 8 && !lrw64InitDone) || (blockSize == 16 && !lrw128InitDone)))
{
// Deprecated/legacy
if (!EAInitMode (cryptoInfo))
{
status = ERR_MODE_INIT_FAILED;
goto err;
}
if (blockSize == 8)
lrw64InitDone = 1;
else if (blockSize == 16)
lrw128InitDone = 1;
}
// Copy the header for decryption
memcpy (header, encryptedHeader, HEADER_SIZE);
// Try to decrypt header
DecryptBlock((unsigned char *) (header + HEADER_ENCRYPTED_DATA_OFFSET), HEADER_ENCRYPTED_DATA_SIZE, HEADER_SIZE, 0, 4, cryptoInfo);
// Magic 'TRUE'
if (GetHeaderField32 ((unsigned char *) header, HEADER_OFFSET_MAGIC) != 0x54525545)
continue;
uint32_t crc = GetHeaderField32 ((unsigned char *) header, HEADER_OFFSET_CRC);
if (crc != GetCrc32 ((unsigned char *) ((unsigned char *) (header + HEADER_OFFSET_DATA)), HEADER_DATA_SIZE) )
continue;
if ( GetHeaderField16((unsigned char *) header, HEADER_OFFSET_DATASZ) > 0x100 )
continue;
memcpy(dk, header + HEADER_OFFSET_DATA, HEADER_DATA_SIZE);
memcpy(encryptedHeader, header, 0x200);
switch (cryptoInfo->mode)
{
case LRW:
case CBC:
case INNER_CBC:
case OUTER_CBC:
// For LRW (deprecated/legacy), copy the tweak key
// For CBC (deprecated/legacy), copy the IV/whitening seed
memcpy (cryptoInfo->k2, dk, LEGACY_VOL_IV_SIZE);
primaryKeyOffset = LEGACY_VOL_IV_SIZE;
break;
default:
primaryKeyOffset = 0;
}
if (EAInit (cryptoInfo->ea, (unsigned char *) (dk + primaryKeyOffset), cryptoInfo->ks) != 0 )
{
status = ERR_MODE_INIT_FAILED;
goto err;
}
if (cryptoInfo->mode == XTS)
memcpy (cryptoInfo->k2, dk + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
if (!EAInitMode (cryptoInfo))
{
status = ERR_MODE_INIT_FAILED;
goto err;
}
// Clear out the temporary key buffers
// ret:
burn (dk, sizeof(dk));
burn (&keyInfo, sizeof (keyInfo));
return 0;
}
}
}
status = ERR_PASSWORD_WRONG;
err:
if (cryptoInfo != retHeaderCryptoInfo)
{
crypto_close(cryptoInfo);
*retInfo = NULL;
}
burn (&keyInfo, sizeof (keyInfo));
burn (dk, sizeof(dk));
return status;
}
int decode1(u8 *data, const char *pass, PCRYPTO_INFO *ci)
{
u32 passlen = 0;
u8 unsh[0x101];
memset(unsh, 0, 0x101);
if (!pass)
{
memcpy(unsh, data, 0x40);
unshuffle1(unsh);
passlen = 0x40;
}
else
{
passlen = strlen(pass);
if (passlen > 0x40)
passlen = 0x40;
memcpy(unsh, pass, passlen);
}
Password pwd;
pwd.Length = passlen;
memcpy(pwd.Text, unsh, passlen);
return ReadHeader(0, (char *) data, &pwd, ci, NULL);
}
void decryptMode2(Decoder *ctx, u8 *buffer, u32 length, u64 blockIndex)
{
u8 *p = buffer;
u8 i[8];
u8 t[16];
u64 b;
*(u64 *)i = BE64(blockIndex);
for (b = 0; b < length >> 4; b++)
{
Gf128MulBy64Tab (i, t, &ctx->gf_ctx);
Xor128 ((u64 *)p, (u64 *)t);
aes_decrypt (p, p, &ctx->decr);
Xor128 ((u64 *)p, (u64 *)t);
p += 16;
if (i[7] != 0xff)
i[7]++;
else
*(u64 *)i = BE64 ( BE64(*(u64 *)i) + 1 );
}
}
void MdxDecryptBufferCBC (Decoder *ctx, u32 *data, unsigned int len, u32 *iv, u32 *whitening)
{
u32 bufIV[4];
u64 i;
u32 ct[4];
// IV
bufIV[0] = iv[0];
bufIV[1] = iv[1];
bufIV[2] = iv[2];
bufIV[3] = iv[3];
// Decrypt each block
for (i = 0; i < len/16; i++)
{
// Dewhitening
if (whitening)
{
data[0] ^= whitening[0];
data[1] ^= whitening[1];
data[2] ^= whitening[0];
data[3] ^= whitening[1];
//CBC
ct[0] = data[0];
ct[1] = data[1];
ct[2] = data[2];
ct[3] = data[3];
}
aes_decrypt((u8 *)data, (u8 *)data, &ctx->decr);
// CBC
data[0] ^= bufIV[0];
data[1] ^= bufIV[1];
data[2] ^= bufIV[2];
data[3] ^= bufIV[3];
if (whitening)
{
bufIV[0] = ct[0];
bufIV[1] = ct[1];
bufIV[2] = ct[2];
bufIV[3] = ct[3];
}
data += 4;
}
}
void decryptMdxData(Decoder *ctx, u8 *buffer, u32 length, u64 blockSize, u64 blockIndex)
{
if (ctx->mode == 1)
{
if (ctx->ctr)
{
u32 sectorIV[4];
u32 secWhitening[4];
InitSectorIVAndWhitening (blockIndex, 16, sectorIV, (u64 *)(ctx->dg + 16), secWhitening);
MdxDecryptBufferCBC (ctx, (u32 *)buffer, length, sectorIV, secWhitening);
}
else
{
MdxDecryptBufferCBC (ctx, (u32 *)buffer, length, (u32 *)ctx->dg, (u32 *)(ctx->dg + 8));
}
}
else if (ctx->mode == 2)
{
if (ctx->ctr)
decryptMode2(ctx, buffer, length, 1 + (blockSize / 16) * blockIndex);
else
decryptMode2(ctx, buffer, length, 1);
}
else
{
MdxDecryptBufferCBC (ctx, (u32 *)buffer, length, (u32 *)ctx->dg, NULL);
}
}

13
src/utils/defines.h Normal file
View File

@@ -0,0 +1,13 @@
#ifndef DEFINES_H
#define DEFINES_H
#include <inttypes.h>
typedef uint64_t u64;
typedef int64_t s64;
typedef uint32_t u32;
typedef int32_t s32;
typedef uint8_t u8;
typedef int BOOL;
#endif

78
src/utils/edc.c Normal file
View File

@@ -0,0 +1,78 @@
#include "defines.h"
u32 EDC_crctable[256] = {
0x0, 0x90910101, 0x91210201, 0x1B00300,
0x92410401, 0x2D00500, 0x3600600, 0x93F10701,
0x94810801, 0x4100900, 0x5A00A00, 0x95310B01,
0x6C00C00, 0x96510D01, 0x97E10E01, 0x7700F00,
0x99011001, 0x9901100, 0x8201200, 0x98B11301,
0xB401400, 0x9BD11501, 0x9A611601, 0xAF01700,
0xD801800, 0x9D111901, 0x9CA11A01, 0xC301B00,
0x9FC11C01, 0xF501D00, 0xEE01E00, 0x9E711F01,
0x82012001, 0x12902100, 0x13202200, 0x83B12301,
0x10402400, 0x80D12501, 0x81612601, 0x11F02700,
0x16802800, 0x86112901, 0x87A12A01, 0x17302B00,
0x84C12C01, 0x14502D00, 0x15E02E00, 0x85712F01,
0x1B003000, 0x8B913101, 0x8A213201, 0x1AB03300,
0x89413401, 0x19D03500, 0x18603600, 0x88F13701,
0x8F813801, 0x1F103900, 0x1EA03A00, 0x8E313B01,
0x1DC03C00, 0x8D513D01, 0x8CE13E01, 0x1C703F00,
0xB4014001, 0x24904100, 0x25204200, 0xB5B14301,
0x26404400, 0xB6D14501, 0xB7614601, 0x27F04700,
0x20804800, 0xB0114901, 0xB1A14A01, 0x21304B00,
0xB2C14C01, 0x22504D00, 0x23E04E00, 0xB3714F01,
0x2D005000, 0xBD915101, 0xBC215201, 0x2CB05300,
0xBF415401, 0x2FD05500, 0x2E605600, 0xBEF15701,
0xB9815801, 0x29105900, 0x28A05A00, 0xB8315B01,
0x2BC05C00, 0xBB515D01, 0xBAE15E01, 0x2A705F00,
0x36006000, 0xA6916101, 0xA7216201, 0x37B06300,
0xA4416401, 0x34D06500, 0x35606600, 0xA5F16701,
0xA2816801, 0x32106900, 0x33A06A00, 0xA3316B01,
0x30C06C00, 0xA0516D01, 0xA1E16E01, 0x31706F00,
0xAF017001, 0x3F907100, 0x3E207200, 0xAEB17301,
0x3D407400, 0xADD17501, 0xAC617601, 0x3CF07700,
0x3B807800, 0xAB117901, 0xAAA17A01, 0x3A307B00,
0xA9C17C01, 0x39507D00, 0x38E07E00, 0xA8717F01,
0xD8018001, 0x48908100, 0x49208200, 0xD9B18301,
0x4A408400, 0xDAD18501, 0xDB618601, 0x4BF08700,
0x4C808800, 0xDC118901, 0xDDA18A01, 0x4D308B00,
0xDEC18C01, 0x4E508D00, 0x4FE08E00, 0xDF718F01,
0x41009000, 0xD1919101, 0xD0219201, 0x40B09300,
0xD3419401, 0x43D09500, 0x42609600, 0xD2F19701,
0xD5819801, 0x45109900, 0x44A09A00, 0xD4319B01,
0x47C09C00, 0xD7519D01, 0xD6E19E01, 0x46709F00,
0x5A00A000, 0xCA91A101, 0xCB21A201, 0x5BB0A300,
0xC841A401, 0x58D0A500, 0x5960A600, 0xC9F1A701,
0xCE81A801, 0x5E10A900, 0x5FA0AA00, 0xCF31AB01,
0x5CC0AC00, 0xCC51AD01, 0xCDE1AE01, 0x5D70AF00,
0xC301B001, 0x5390B100, 0x5220B200, 0xC2B1B301,
0x5140B400, 0xC1D1B501, 0xC061B601, 0x50F0B700,
0x5780B800, 0xC711B901, 0xC6A1BA01, 0x5630BB00,
0xC5C1BC01, 0x5550BD00, 0x54E0BE00, 0xC471BF01,
0x6C00C000, 0xFC91C101, 0xFD21C201, 0x6DB0C300,
0xFE41C401, 0x6ED0C500, 0x6F60C600, 0xFFF1C701,
0xF881C801, 0x6810C900, 0x69A0CA00, 0xF931CB01,
0x6AC0CC00, 0xFA51CD01, 0xFBE1CE01, 0x6B70CF00,
0xF501D001, 0x6590D100, 0x6420D200, 0xF4B1D301,
0x6740D400, 0xF7D1D501, 0xF661D601, 0x66F0D700,
0x6180D800, 0xF111D901, 0xF0A1DA01, 0x6030DB00,
0xF3C1DC01, 0x6350DD00, 0x62E0DE00, 0xF271DF01,
0xEE01E001, 0x7E90E100, 0x7F20E200, 0xEFB1E301,
0x7C40E400, 0xECD1E501, 0xED61E601, 0x7DF0E700,
0x7A80E800, 0xEA11E901, 0xEBA1EA01, 0x7B30EB00,
0xE8C1EC01, 0x7850ED00, 0x79E0EE00, 0xE971EF01,
0x7700F000, 0xE791F101, 0xE621F201, 0x76B0F300,
0xE541F401, 0x75D0F500, 0x7460F600, 0xE4F1F701,
0xE381F801, 0x7310F900, 0x72A0FA00, 0xE231FB01,
0x71C0FC00, 0xE151FD01, 0xE0E1FE01, 0x7070FF00 };
u32 getEDC(void *data, u32 num)
{
u8 *d = (u8 *)data;
u32 result = 0;
for(u32 i = 0; i < num; i++) {
result = EDC_crctable[ (result ^ d[i]) & 0xff ] ^ (result >> 8);
}
return result;
}

8
src/utils/edc.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef EDC_H
#define EDC_H
#include "defines.h"
u32 getEDC(void *data, u32 num);
#endif

188
src/utils/mds.h Normal file
View File

@@ -0,0 +1,188 @@
#ifndef MDS_H
#define MDS_H
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "defines.h"
#include "common/crypto.h"
typedef struct Decoder_t
{
u8 dg[32];
GfCtx gf_ctx;
aes_encrypt_ctx encr;
aes_decrypt_ctx decr;
u8 bsize;
int mode;
int ctr;
} Decoder;
enum TRACK_TYPE
{
TRK_T_MAINTENANCE = 0,
TRK_T_AUDIO = 1,
TRK_T_MODE1 = 2,
TRK_T_MODE2 = 3,
TRK_T_MODE2_FORM1 = 4,
TRK_T_MODE2_FORM2 = 5
};
enum TRACK_FLAG
{
TRK_F_TYPE_MASK = 7,
TRK_F_EDC = 8,
TRK_F_10 = 0x10,
TRK_F_HEADER = 0x20,
TRK_F_SUBHEADER = 0x40,
TRK_F_SYNC = 0x80
};
typedef struct __attribute__((packed))
{
u32 f0;
u32 f1;
u64 f3; //or two u32?
} UNK4;
typedef struct __attribute__((packed))
{
char signature[16];
u8 major; // 0x10
u8 minor;
u16 medium_type; // 0x12
u16 num_sessions; // 0x14
u16 _unk1_;
u16 _unk2_size_; // 0x18
u16 bca_len;
u16 _unk3_size_; // 0x1c
u16 _unk4_size_; // 0x1e
u32 _unk2_offset_; // 0x20
u32 bca_data_offset; // 0x24
u32 _unk3_offset_; // 0x28
u32 _unk4_offset_; // 0x2c 0x10 byte elements UNK4
u8 _unk5_; // 0x30
u32 _unk6_; // 0x31
u8 _unk7_; // 0x35
u64 _unk8_; // 0x36
u16 _unk9_; // 0x3e
u32 disc_structures_offset; // 0x40
u32 _unk10_offset_; // 0x44
u16 _unk10_size_; // 0x48
u8 _dummy1_[6]; // 0x4a not used by DT
u32 sessions_blocks_offset; // 0x50
u32 dpm_blocks_offset; // 0x54
u32 encryption_block_offset; // 0x58
u8 _dummy2_[4]; // 0x5c
} MDX_Header; // 0x60
typedef struct __attribute__((packed))
{
u64 session_start;
u16 session_number; // 0x8
u8 num_all_blocks; // 0xa
u8 num_nontrack_blocks; // 0xb
u16 first_track; // 0xc
u16 last_track; // 0xe
u32 _dummy_; // 0x10
u32 tracks_blocks_offset; // 0x14
u64 session_end; // 0x18
} MDX_SessionBlock; // 0x20
typedef struct __attribute__((packed))
{
u8 mode;
u8 subchannel;
u8 adr_ctl;
u8 tno;
u8 point; // 4
u8 min;
u8 sec;
u8 frame;
u8 zero; // 8
u8 pmin;
u8 psec;
u8 pframe;
u32 extra_offset; // 0xc
u16 file_block_size; // 0x10 original name. represent full size of data and additional data per sector
u8 _unk1_; // 0x12
u8 _dummy1_[5]; // 0x13
u32 _unk2_; // 0x18;
u32 _unk3_; // 0x1c;
u32 _unk4_; // 0x20;
u32 start_sector; // 0x24
u64 start_offset; // 0x28
u32 footer_count; // 0x30
u32 footer_offset; // 0x34
u64 start_sector64; // 0x38 major >= 2
u64 track_size64; // 0x40 major >= 2
u8 _dummy2_[8]; // 0x48
} MDX_TrackBlock; // 0x50
typedef struct __attribute__((packed))
{
u32 filename_offset;
u8 flags; // 4
u8 _dummy1_; // 5
u16 _unk1_size_; // 6
u32 _unk2_size_; // 8
u32 blocks_in_compression_group; // c major >= 2
u64 track_data_length; // 10 major >= 2
u64 compress_table_offset; // 18
} MDX_Footer; // 0x20
// decode.c
void DecryptBlock(u8 *buf, TC_LARGEST_COMPILER_UINT len, u32 secSz, u64 secN, u8 flags, PCRYPTO_INFO cryptoInfo);
int decode1(u8 *data, const char *pass, PCRYPTO_INFO *ci);
void decryptMdxData(Decoder *ctx, u8 *buffer, u32 length, u64 blockSize, u64 blockIndex);
// utils.c
inline static u64 getU64(const void *mem)
{
const u8 *mem8 = (const u8 *)mem;
return ((u64)mem8[0] | ((u64)mem8[1] << 8) | ((u64)mem8[2] << 16) | ((u64)mem8[3] << 24) | ((u64)mem8[4] << 32) | ((u64)mem8[5] << 40) | ((u64)mem8[6] << 48) | ((u64)mem8[7] << 56));
}
inline static u32 getU32(const void *mem)
{
const u8 *mem8 = (const u8 *)mem;
return ((u32)mem8[0] | ((u32)mem8[1] << 8) | ((u32)mem8[2] << 16) | ((u32)mem8[3] << 24));
}
inline static u16 getU16(const void *mem)
{
const u8 *mem8 = (const u8 *)mem;
return ((u16)mem8[0] | ((u16)mem8[1] << 8));
}
inline static u8 getU8(const void *mem)
{
const u8 *mem8 = (const u8 *)mem;
return (u8)mem8[0];
}
inline static void setU32(void *mem, u32 val)
{
u8 *mem8 = (u8 *)mem;
mem8[0] = val & 0xff;
mem8[1] = (val >> 8) & 0xff;
mem8[2] = (val >> 16) & 0xff;
mem8[3] = (val >> 24) & 0xff;
}
u32 freadU32(FILE *f);
u64 freadU64(FILE *f);
void printHex(void *data, int num);
#endif

27
src/utils/utils.c Normal file
View File

@@ -0,0 +1,27 @@
#include "mds.h"
u32 freadU32(FILE *f)
{
u8 val[4] = {0, 0, 0, 0};
fread(val, 4, 1, f);
return getU32(val);
}
u64 freadU64(FILE *f)
{
u8 val[8] = {0, 0, 0, 0, 0, 0, 0, 0};
fread(val, 8, 1, f);
return getU64(val);
}
void printHex(void *data, int num)
{
u8 *m = (u8 *)data;
while(num > 0)
{
printf("%02x", *m);
m++;
num--;
}
printf("\n");
}