📄 testphelix.c
字号:
/*
** Phelix function and performance test module
**
** Public domain code. Author: Doug Whiting, Hifn, 2005
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include <time.h>
#ifdef ECRYPT_API
#include "ecrypt-sync-ae.h"
#endif
#include "phelix.h"
#ifdef MIX_ASM /* randomly intermix C and assembly calls to check interoperability */
u32b PhelixEncryptPacket_ASM(PhelixPacketParms);
u32b PhelixDecryptPacket_ASM(PhelixPacketParms);
u32b PhelixNop_ASM (PhelixPacketParms);
void PhelixSetupKey_ASM (PhelixContext *ctx,const U08P keyPtr,
u32b keySize,u32b ivSize,u32b macSize);
void PhelixSetupNonce_ASM (PhelixContext *ctx,const U08P noncePtr);
void PhelixProcessAAD_ASM (PhelixContext *ctx,const U08P aadPtr,u32b aadLen);
void PhelixEncryptBytes_ASM (PhelixContext *ctx,const U08P pt,U08P ct,u32b msgLen);
void PhelixDecryptBytes_ASM (PhelixContext *ctx,const U08P ct,U08P pt,u32b msgLen);
void PhelixFinalize_ASM (PhelixContext *ctx,U08P mac);
#endif
typedef const char * refStr;
/************************************************************
********** COMPILER/PLATFORM-SPECIFIC DEFINITIONS **********
************************************************************/
#if defined(_ANSI_CHK) || defined(__STRICT_ANSI__)
#define DO_PERF_TEST 0
#define CompilerMode " [ANSI-C Mode]"
#else
#define CompilerMode ""
#endif
/************************************************************/
#if defined(_MSC_VER)
#define CompilerID "MSVC v%d.%d"
#define CompilerMajorVersion (_MSC_VER / 100)
#define CompilerMinorVersion (_MSC_VER % 100)
#ifndef DO_PERF_TEST
#define DO_PERF_TEST 1
#define _IsX86_ 1
#define _TRAP_ { if (_allowTrap_) _asm { int 3 }; }
u32b HighFreqCounter(void)
{ /* use this to perform timing measurements */
u32b x;
_asm /* counts CPU clocks (e.g., 1E9/sec for a 1GHz CPU) */
{
_emit 0x0F
_emit 0x31
mov x,eax
};
return x;
}
u32b Get_x86_CPU_ID(void)
{
u32b x;
_asm{
push ebx
push ecx
mov eax,1 /* eax == 1 --> get CPU type */
_emit 0x0F
_emit 0xA2
mov x,eax
pop ecx
pop ebx
};
return x;
}
#endif
/************************************************************/
#elif defined(__BORLANDC__)
#define CompilerID "BorlandC v %X.%X"
#define CompilerMajorVersion (__BORLANDC__ / 256)
#define CompilerMinorVersion (__BORLANDC__ % 256)
#define CompilerVersion
#ifndef DO_PERF_TEST
#define DO_PERF_TEST 1
#define _TRAP_ { if (_allowTrap_) __emit__(0xCC); }
#define _IsX86_ 1
u32b HighFreqCounter(void)
{ /* for performance timing */
u32b x;
__emit__(0x0F);
__emit__(0x31);
_asm
{
mov x,eax
};
return x;
}
u32b Get_x86_CPU_ID(void)
{
u32b x;
_asm{
push ebx
push ecx
mov eax,1 /* eax == 1 --> get CPU type */
};
__emit__(0x0F); __emit__(0xA2); /* CPU_ID opcode */
_asm
{
mov x,eax
pop ecx
pop ebx
};
return x;
}
#endif
/************************************************************/
#elif defined(__MINGW_H) || (defined(__GNUC__) && (defined(__i386__) || defined(__386)))
#define CompilerID "GCC v%d.%d"
#define CompilerMajorVersion (__GNUC__)
#define CompilerMinorVersion (__GNUC_MINOR__)
#ifndef DO_PERF_TEST
#define DO_PERF_TEST 1
#define _IsX86_ 1
#define _TRAP_ { if (_allowTrap_) asm volatile ("int $3"); }
u32b HighFreqCounter(void)
{
u32b x[2];
asm volatile("rdtsc" : "=a"(x[0]), "=d"(x[1]));
return x[0];
}
u32b Get_x86_CPU_ID(void)
{
u32b x;
asm volatile("movl $1, %eax");
asm volatile("cpuid" : "=a"(x));
return x;
}
#endif
/************************************************************/
#elif defined(sparc)
#define CompilerID "Solaris-GCC"
#ifndef DO_PERF_TEST
#define DO_PERF_TEST 1
#define CPU_INFO_STRING "SPARC CPU"
#include <sys/time.h>
u32b HighFreqCounter(void)
{
struct timezone tz;
struct timeval tv;
gettimeofday(&tv,&tz);
return tv.tv_usec;
}
#endif
/************************************************************/
/* extend to other platforms by adding new "sections" here */
#else
#define CompilerID "Unknown compiler"
#endif
/************************************************************/
/* some catch-all definitions, if not previously defined */
#if !defined(DO_PERF_TEST) || DO_PERF_TEST == 0
#define DO_PERF_TEST 0
u32b HighFreqCounter(void) { return 0; }
#endif
#ifndef _TRAP_ /* no debugger trap by default */
#define _TRAP_
#endif
/*************************************************************
************ END OF PLATFORM-SPECIFIC DEFINITIONS ***********
************************************************************/
/* global configuration variables */
int _verbose_ = 0; /* verbose output */
int _allowTrap_ = 0; /* allow debugger trap (INT 3 for x86) */
u32b _timeAADcnt_ = 0; /* # bytes of AAD to time */
extern int _debugPhelix_; /* instantiated in phelix.c */
/* put out a formatted error message, then exit */
void FatalError(refStr formatStr,...)
{
va_list ap;
printf("\n*** FATAL ERROR: ");
va_start(ap,formatStr);
vprintf(formatStr,ap);
va_end(ap);
printf("\n");
_TRAP_;
exit(2);
}
/* print a message showing the CPU type and speed */
void ShowCPUinfo(void)
{
#if defined(_IsX86_) && _IsX86_
u32b cpuID,cpuFamily,cpuModel;
cpuID = Get_x86_CPU_ID();
cpuFamily = (cpuID >> 8) & 0xF;
cpuModel = (cpuID >> 4) & 0xF;
printf("CPU_ID = %08X ==> ",cpuID);
switch (cpuFamily)
{
case 4: printf("486"); break;
case 5: printf("Pentium"); break;
case 6:
switch (cpuModel)
{
case 3:
case 5:
printf("Pentium II"); break;
case 6:
printf("Pentium II (Celeron)"); break;
case 7:
case 8:
case 10:
case 11:
printf("Pentium III"); break;
case 9:
case 13:
printf("Pentium M (III)"); break;
default:
printf("Unknown CPU (II/III)"); break;
}
break;
case 15: printf("Pentium 4"); break;
default: printf("Unknown CPU"); break;
}
#elif defined(CPU_INFO_STRING)
printf(CPU_INFO_STRING);
#else
printf("(Unknown CPU) ");
#endif
#if defined(DO_PERF_TEST) && DO_PERF_TEST
/* now calibrate the HighFreqCounter frequency and display it */
{
enum { FRAC = 10 }; /* calibrate for 1/FRAC second */
u32b x0,x1;
clock_t t,t0,t1,dt;
dt = CLOCKS_PER_SEC/FRAC;
for (t=clock();;) /* wait for clock() to change */
if (t != (t0 = clock()))
break;
x0 = HighFreqCounter(); /* starting value of HiFreqCounter */
do { t1 = clock(); } /* wait 1/10 of a second */
while ((t1-t0) < dt);
x1 = HighFreqCounter(); /* ending value */
printf(" [PerfClk =%7.4f GHz. clock() = %0.0f/sec]",
((x1-(double)x0)*FRAC)/1E9 , (double)CLOCKS_PER_SEC);
}
#endif
printf("\n");
}
/**********************************************************************
********************* Phelix Definitions and Code ********************
*********************************************************************/
typedef struct /* test vector (for KAT) */
{
u32b keySize,msgLen,aadLen,macSize,nonceSize;
u08b key [32]; /* "raw" key */
u08b nonce[16]; /* nonce */
u08b aad [36]; /* aad */
u08b pText[36]; /* plaintext */
u08b cText[36]; /* ciphertext */
u08b mac [16]; /* MAC result */
} TestVector;
const TestVector KAT[] = /* known answer test vectors */
{
#include "phelixKAT.h"
{0,0,0,0,0} /* all zero lengths --> end of vector list */
};
#define KAT_CNT (sizeof(KAT)/sizeof(KAT[0]))
/* cosmetic shortcuts for some of ProcessPacket function parms */
#define PPv &ctx,v.nonce,v.aad,v.aadLen
#define PP_ &ctx, nonce, aad, aadLen
/*
*********************************************************************
* Portable PRNG functions/variables, same results across platforms
*********************************************************************
*/
static struct
{
u08b i,j; /* RC4 variables */
u08b sbox[256]; /* RC4 s-box */
} RC4;
void RandFill(void *p,u32b byteCnt)
{
u32b n;
u08b a,b;
for (n=0;n<byteCnt;n++) /* run the RC4 algorithm as long as it needs */
{
RC4.i++;
a = RC4.sbox[RC4.i];
RC4.j = (u08b) (RC4.j + a); /* avoid MSVC picky compiler warning */
b = RC4.sbox[RC4.j];
RC4.sbox[RC4.i] = b;
RC4.sbox[RC4.j] = a;
((u08b *)p)[n] = RC4.sbox[(a+b) & 0xFF];
}
}
u32b Rand32(void) /* get a 32-bit word */
{
u08b x[4];
u32b n;
RandFill(x,sizeof(x));
n = x[3]; /* convert to u32b in little-endian format */
n = x[2] + (n << 8);
n = x[1] + (n << 8);
n = x[0] + (n << 8);
return n;
}
u08b Rand08(void) /* get an 8-bit byte */
{
u08b x[1];
RandFill(x,1);
return x[0];
}
void RandReseed(u32b randSeed) /* re-seed PRNG */
{
u32b i,j;
u08b tmp;
for (i=0;i<256;i++) /* initialize the permutation */
RC4.sbox[i] = (u08b) i;
for (i=j=0;i<256;i++) /* run the RC4 key schedule */
{ /* use "randSeed" as 32-bit key */
j =(RC4.sbox[i] + j + (randSeed >> (8*(i%4)))) & 0xFF;
tmp = RC4.sbox[i]; /* swap sbox[i], sbox[j] */
RC4.sbox[i] = RC4.sbox[j];
RC4.sbox[j] = tmp;
}
RC4.i = RC4.j = 0; /* init i,j variables for RC4 */
for (i=0;i<64;i++)
Rand32(); /* discard first 256 bytes of RC4 output */
}
u32b RandMacSize(u32b mod)
{
u32b i;
static u32b macSizeCnt = 0;
if (macSizeCnt == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -