// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
#include "..\\common\\resource.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_SIZE_DIALOG DIALOGEX 0, 0, 376, 271
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "VeraCrypt Expander"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
EDITTEXT IDC_SIZEBOX,30,102,109,14,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER
CONTROL "&KB",IDC_KB,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,169,105,38,10
CONTROL "&MB",IDC_MB,"Button",BS_AUTORADIOBUTTON,209,105,38,10
CONTROL "&GB",IDC_GB,"Button",BS_AUTORADIOBUTTON,248,105,38,10
CONTROL "&TB",IDC_TB,"Button",BS_AUTORADIOBUTTON,288,105,38,10
CONTROL "Fill new space with random data",IDC_INIT_NEWSPACE,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,30,127,118,10
DEFPUSHBUTTON "Continue",IDOK,15,238,84,18
PUSHBUTTON "Cancel",IDCANCEL,277,238,84,18
LTEXT "Help Text",IDC_BOX_HELP,15,165,346,58,0,WS_EX_CLIENTEDGE
GROUPBOX "Enter new volume size",IDC_STATIC,15,83,346,63
RTEXT "Current size: ",IDT_CURRENT_SIZE,27,42,46,8
CONTROL "",IDC_EXPAND_VOLUME_OLDSIZE,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,80,42,275,8,WS_EX_TRANSPARENT
RTEXT "New size: ",IDT_NEW_SIZE,28,54,45,8
LTEXT "",IDC_EXPAND_VOLUME_NEWSIZE,80,54,275,8,0,WS_EX_TRANSPARENT
RTEXT "Volume: ",IDT_VOL_NAME,31,18,42,8
GROUPBOX "",IDC_STATIC,15,9,346,59
CONTROL "",IDC_EXPAND_VOLUME_NAME,"Static",SS_SIMPLE | WS_GROUP,80,18,275,8,WS_EX_TRANSPARENT
RTEXT "File system: ",IDT_FILE_SYS,31,30,42,8
CONTROL "",IDC_EXPAND_FILE_SYSTEM,"Static",SS_SIMPLE | WS_GROUP,80,30,275,8,WS_EX_TRANSPARENT
END
IDD_MOUNT_DLG DIALOGEX 0, 0, 376, 271
STYLE DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "VeraCrypt Expander"
MENU IDR_MENU
CLASS "VeraCryptCustomDlg"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
COMBOBOX IDC_VOLUME,56,192,212,74,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Select &File...",IDC_SELECT_FILE,276,192,84,14
PUSHBUTTON "Select D&evice...",IDC_SELECT_DEVICE,276,211,84,14
DEFPUSHBUTTON "Mount",IDOK,8,243,84,18,WS_GROUP
PUSHBUTTON "E&xit",IDC_EXIT,284,243,84,18,WS_GROUP
CONTROL 112,IDC_LOGO,"Static",SS_BITMAP | SS_NOTIFY | WS_BORDER,16,192,27,31
GROUPBOX "Volume",IDT_VOLUME,8,179,360,53
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDFRAME,1,0,373,147
GROUPBOX "",IDC_STATIC,282,238,88,24
GROUPBOX "",IDC_STATIC,6,238,88,24
GROUPBOX "",IDC_STATIC,1,147,373,123,BS_CENTER
LTEXT "1. Select the VeraCrypt volume to be expanded\n2. Click the 'Mount' button",IDC_STATIC,15,156,293,21
LTEXT "Static",IDC_INFOEXPAND,8,6,361,134,SS_NOPREFIX | SS_SUNKEN,WS_EX_STATICEDGE
END
IDD_PASSWORD_DLG DIALOGEX 0, 0, 322, 107
STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION
CAPTION "Enter VeraCrypt Volume Password"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
EDITTEXT IDC_PASSWORD,69,8,166,14,ES_PASSWORD | ES_AUTOHSCROLL
COMBOBOX IDC_PKCS5_PRF_ID,69,26,86,90,CBS_DROPDOWNLIST | WS_TABSTOP
CONTROL "TrueCrypt Mode",IDC_TRUECRYPT_MODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,159,28,76,10
EDITTEXT IDC_PIM,69,43,42,14,ES_RIGHT | ES_PASSWORD | ES_AUTOHSCROLL | ES_NUMBER | NOT WS_VISIBLE
CONTROL "Use P&IM",IDC_PIM_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,70,49,97,10
CONTROL "Cache passwords and keyfil&es in memory",IDC_CACHE,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,70,62,153,10
CONTROL "&Display password",IDC_SHOW_PASSWORD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,70,75,83,10
CONTROL "U&se keyfiles",IDC_KEYFILES_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,70,88,83,11
PUSHBUTTON "&Keyfiles...",IDC_KEY_FILES,171,86,64,14
PUSHBUTTON "Mount Opti&ons...",IDC_MOUNT_OPTIONS,243,86,64,14
DEFPUSHBUTTON "OK",IDOK,243,8,64,14
PUSHBUTTON "Cancel",IDCANCEL,243,25,64,14
RTEXT "Password:",IDT_PASSWORD,0,10,65,13
RTEXT "PKCS-5 PRF:",IDT_PKCS5_PRF,0,27,65,13
RTEXT "Volume PIM:",IDT_PIM,0,46,65,13,NOT WS_VISIBLE
LTEXT "(Empty or 0 for default iterations)",IDC_PIM_HELP,115,46,189,8,NOT WS_VISIBLE
END
IDD_EXPAND_PROGRESS_DLG DIALOGEX 0, 0, 376, 283
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "VeraCrypt Expander"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
RTEXT "Current size: ",IDT_CURRENT_SIZE,27,40,46,8
CONTROL "",IDC_EXPAND_VOLUME_OLDSIZE,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,80,40,275,8,WS_EX_TRANSPARENT
RTEXT "New size: ",IDT_NEW_SIZE,28,52,45,8
LTEXT "",IDC_EXPAND_VOLUME_NEWSIZE,80,52,275,8,0,WS_EX_TRANSPARENT
CONTROL "",IDC_PROGRESS_BAR,"msctls_progress32",PBS_SMOOTH | WS_BORDER,22,96,332,12
RTEXT "",IDC_TIMEREMAIN,275,114,42,11,SS_CENTERIMAGE,WS_EX_TRANSPARENT | WS_EX_RIGHT | WS_EX_STATICEDGE
RTEXT "",IDC_WRITESPEED,178,114,42,11,SS_CENTERIMAGE,WS_EX_TRANSPARENT | WS_EX_RIGHT | WS_EX_STATICEDGE
LTEXT "",IDC_BYTESWRITTEN,77,114,39,11,SS_CENTERIMAGE,WS_EX_TRANSPARENT | WS_EX_RIGHT | WS_EX_STATICEDGE
RTEXT "Done",IDT_DONE,53,115,22,8
RTEXT "Speed",IDT_SPEED,142,115,34,8
RTEXT "Left",IDT_LEFT,248,115,25,8
GROUPBOX "",IDC_STATIC,15,84,346,49
RTEXT "Volume: ",IDT_VOL_NAME,31,16,42,8
GROUPBOX "",IDC_STATIC,15,7,346,72
CONTROL "",IDC_EXPAND_VOLUME_NAME,"Static",SS_SIMPLE | WS_GROUP,80,16,275,8,WS_EX_TRANSPARENT
DEFPUSHBUTTON "Continue",IDOK,15,247,84,18
PUSHBUTTON "Cancel",IDCANCEL,277,247,84,18
EDITTEXT IDC_BOX_STATUS,15,176,346,66,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | ES_WANTRETURN | WS_VSCROLL
CONTROL "",IDC_EXPAND_VOLUME_INITSPACE,"Static",SS_SIMPLE | WS_GROUP,80,64,275,8,WS_EX_TRANSPARENT
RTEXT "Fill new space: ",IDT_INIT_SPACE,20,64,53,8
RTEXT "File system: ",IDT_FILE_SYS,31,28,42,8
CONTROL "",IDC_EXPAND_FILE_SYSTEM,"Static",SS_SIMPLE | WS_GROUP,80,28,275,8,WS_EX_TRANSPARENT
RTEXT "Random Pool: ",IDT_RANDOM_POOL2,20,144,53,8
CONTROL "",IDC_RANDOM_BYTES,"Static",SS_SIMPLE | WS_GROUP,80,144,149,8,WS_EX_TRANSPARENT
CONTROL "Display pool content",IDC_DISPLAY_POOL_CONTENTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,236,142,125,12
GROUPBOX "Randomness Collected From Mouse Movements",IDT_ENTROPY_BAR,20,156,214,18
CONTROL "",IDC_ENTROPY_BAR,"msctls_progress32",WS_BORDER,31,165,193,6
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_SIZE_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 15
RIGHTMARGIN, 361
VERTGUIDE, 30
TOPMARGIN, 14
BOTTOMMARGIN, 256
END
IDD_MOUNT_DLG, DIALOG
BEGIN
RIGHTMARGIN, 369
VERTGUIDE, 8
BOTTOMMARGIN, 269
END
IDD_PASSWORD_DLG, DIALOG
BEGIN
BOTTOMMARGIN, 102
END
IDD_EXPAND_PROGRESS_DLG, DIALOG
BEGIN
RIGHTMARGIN, 361
VERTGUIDE, 15
VERTGUIDE, 73
VERTGUIDE, 80
VERTGUIDE, 355
TOPMARGIN, 9
BOTTOMMARGIN, 268
HORZGUIDE, 176
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// HEADER
//
IDR_MOUNT_RSRC_HEADER HEADER "resource.h"
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,17,22,0
PRODUCTVERSION 1,17,22,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "IDRIX"
VALUE "FileDescription", "VeraCrypt Expander"
VALUE "FileVersion", "1.17"
VALUE "LegalTrademarks", "VeraCrypt"
VALUE "OriginalFilename", "VeraCryptExpander.exe"
VALUE "ProductName", "VeraCrypt"
VALUE "ProductVersion", "1.17"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"#include ""..\\\\common\\\\/*
---------------------------------------------------------------------------
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 Developers Association
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 "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 unsigned __int32 mode(32t);
typedef uint64 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 unsigned __int16 gft_le[256] = gf_dat(xp);
static const unsigned __int16 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 unsigned __int16 gft_be[256] = gf_dat(xp);
static const unsigned __int16 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)
{ unsigned __int32 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)
{ unsigned __int32 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(unsigned __int8 *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(unsigned __int8 *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, unsigned __int8 *a)
{
return a[(127 - bit) / 8] & (0x80 >> ((127 - bit) % 8));
}
static int IsBitSet64 (unsigned int bit, unsigned __int8 *a)
{
return a[(63 - bit) / 8] & (0x80 >> ((63 - bit) % 8));
}
static void SetBit128 (unsigned int bit, unsigned __int8 *a)
{
a[(127 - bit) / 8] |= 0x80 >> ((127 - bit) % 8);
}
static void SetBit64 (unsigned int bit, unsigned __int8 *a)
{
a[(63 - bit) / 8] |= 0x80 >> ((63 - bit) % 8);
}
void MirrorBits128 (unsigned __int8 *a)
{
unsigned __int8 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 (unsigned __int8 *a)
{
unsigned __int8 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 (unsigned __int8 *a, GfCtx *ctx)
{
GfCtx8k *ctx8k;
unsigned __int8 am[16];
int i, j;
ctx8k = (GfCtx8k *) TCalloc (sizeof (GfCtx8k));
if (!ctx8k)
return FALSE;
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 TRUE;
}
#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 (unsigned __int8 a[8], unsigned __int8 p[16], GfCtx *ctx)
{
unsigned __int32 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 (*(unsigned __int16 *)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);
}
/* Basic algorithms for testing of optimized algorithms */
static void xor128 (uint64 *a, uint64 *b)
{
*a++ ^= *b++;
*a ^= *b;
}
static void shl128 (unsigned __int8 *a)
{
int i, x = 0, xx;
for (i = 15; i >= 0; i--)
{
xx = (a[i] & 0x80) >> 7;
a[i] = (char) ((a[i] << 1) | x);
x = xx;
}
}
static void GfMul128Basic (unsigned __int8 *a, unsigned __int8 *b, unsigned __int8 *p)
{
int i;
unsigned __int8 la[16];
memcpy (la, a, 16);
memset (p, 0, 16);
for (i = 0; i < 128; i++)
{
if (IsBitSet128 (i, b))
xor128 ((uint64 *)p, (uint64 *)la);
if (la[0] & 0x80)
{
shl128 (la);
la[15] ^= 0x87;
}
else
{
shl128 (la);
}
}
}
BOOL GfMulSelfTest ()
{
BOOL result = TRUE;
unsigned __int8 a[16];
unsigned __int8 b[16];
unsigned __int8 p1[16];
unsigned __int8 p2[16];
GfCtx *gfCtx = (GfCtx *) TCalloc (sizeof (GfCtx));
int i, j;
if (!gfCtx)
return FALSE;
/* GF(2^128) */
for (i = 0; i < 0x100; i++)
{
for (j = 0; j < 16; j++)
{
a[j] = (unsigned __int8) 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 = FALSE;
}
TCfree (gfCtx);
return result;
}
#if defined(__cplusplus)
}
#endif