Files
mars-matrixssl/crypto/test/throughputTest.c
Janne Johansson 69b5f2c6c3 MatrixSSL 4.5.1
2022-07-29 12:30:12 +03:00

1090 lines
30 KiB
C

/**
* @file throughputTest.c
* @version $Format:%h%d$
*
*/
/*
* Copyright (c) 2013-2017 Rambus Inc.
* Copyright (c) PeerSec Networks, 2002-2011
* All Rights Reserved
*
* The latest version of this code is available at http://www.matrixssl.org
*
* This software is open source; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This General Public License does NOT permit incorporating this software
* into proprietary programs. If you are unable to comply with the GPL, a
* commercial license for this software may be purchased from Rambus at
* http://www.rambus.com/
*
* This program is distributed in WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _POSIX_C_SOURCE
# define _POSIX_C_SOURCE 200112L
#endif
#ifndef NEED_PS_TIME_CONCRETE
# define NEED_PS_TIME_CONCRETE
#endif
#include "crypto/cryptoImpl.h"
#include "osdep_string.h"
#include "osdep_stdio.h"
#include "osdep-types.h"
#define DATABYTES_AMOUNT 100 * 1048576 /* # x 1MB (1024-byte variety) */
#define TINY_CHUNKS 16
#define CHACHA20_TINY_CHUNKS 64
#define SMALL_CHUNKS 256
#define MEDIUM_CHUNKS 1024
#define LARGE_CHUNKS 4096
#define HUGE_CHUNKS 16 * 1024
# ifdef USE_AES_CBC
static unsigned char iv[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
static unsigned char key[32] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f };
# endif
enum
{
AES_ENC_ALG = 1,
AES_DEC_ALG,
AES_GCM_ALG,
ARC4_ALG,
DES3_ALG,
SEED_ALG,
IDEA_ALG,
AES_HMAC_ALG,
AES_HMAC256_ALG,
SHA1_ALG,
SHA256_ALG,
SHA384_ALG,
SHA512_ALG,
MD5_ALG,
CHACHA20POLY1305IETF_ALG
};
#if defined(USE_AES_CBC) && (defined(USE_HMAC_SHA1) || defined(USE_HMAC_SHA256))
static void runWithHmac(psCipherContext_t *ctx, psHmac_t *hmac,
int32 hashSize, int32 chunk, int32 alg)
{
psTime_t start, end;
unsigned char *dataChunk;
int32 bytesSent, bytesToSend, round;
unsigned char mac[MAX_HASH_SIZE];
# ifdef USE_HIGHRES_TIME
int32 mod;
int64 diffu;
# else
int32 diffm;
# endif
dataChunk = psMalloc(NULL, chunk);
Memset(dataChunk, 0x0, chunk);
bytesToSend = (DATABYTES_AMOUNT / chunk) * chunk;
bytesSent = 0;
switch (alg)
{
# ifdef USE_AES
# ifdef USE_HMAC_SHA1
case AES_HMAC_ALG:
psGetTime(&start, NULL);
while (bytesSent < bytesToSend)
{
# ifdef USE_HMAC_TLS
static unsigned char hmacKey[64] = { 0, };
unsigned char mac_tmp[20];
psHmacSha1Tls(hmacKey, 20, dataChunk, chunk,
NULL, 0, NULL, 0, 0, mac_tmp);
# else
psHmacSha1Update(&hmac->u.sha1, dataChunk, chunk);
# endif
# ifdef USE_AES_CBC
psAesEncryptCBC(&ctx->aes, dataChunk, dataChunk, chunk);
# endif
bytesSent += chunk;
}
psHmacSha1Final(&hmac->u.sha1, mac);
psGetTime(&end, NULL);
break;
# endif
# ifdef USE_HMAC_SHA256
case AES_HMAC256_ALG:
psGetTime(&start, NULL);
while (bytesSent < bytesToSend)
{
# ifdef USE_HMAC_TLS
static unsigned char hmacKey[64] = { 0, };
unsigned char mac_tmp[32];
psHmacSha2Tls(hmacKey, 32, dataChunk, chunk,
NULL, 0, NULL, 0, 0, mac_tmp, 32);
# else
psHmacSha256Update(&hmac->u.sha256, dataChunk, chunk);
# endif
# ifdef USE_AES_CBC
psAesEncryptCBC(&ctx->aes, dataChunk, dataChunk, chunk);
# endif
bytesSent += chunk;
}
psHmacSha256Final(&hmac->u.sha256, mac);
psGetTime(&end, NULL);
break;
# endif
# endif
default:
Printf("Skipping HMAC Test\n");
psFree(dataChunk, NULL);
return;
}
# ifdef USE_HIGHRES_TIME
diffu = psDiffUsecs(start, end);
round = (bytesToSend / diffu);
mod = (bytesToSend % diffu);
Printf("%d byte chunks in %lld usecs total for rate of %d.%d MB/sec\n",
chunk, (unsigned long long) diffu, round, mod);
# else
diffm = psDiffMsecs(start, end, NULL);
round = (bytesToSend / diffm) / 1000;
Printf("%d byte chunks in %d msecs total for rate of %d MB/sec\n",
chunk, diffm, round);
# endif
psFree(dataChunk, NULL);
}
#endif /* USE_AES_CBC && USE_HMAC */
# ifdef USE_AES_CBC
static void runTime(psCipherContext_t *ctx, psCipherGivContext_t *ctx_giv,
int32 chunk, int32 alg)
{
psTime_t start, end;
unsigned char *dataChunk;
int32 bytesSent, bytesToSend, round;
#ifdef USE_HIGHRES_TIME
int32 mod;
int64 diffu;
#else
int32 diffm;
#endif
dataChunk = psMalloc(NULL, chunk + 16);
Memset(dataChunk, 0x0, chunk);
bytesToSend = (DATABYTES_AMOUNT / chunk) * chunk;
bytesSent = 0;
switch (alg)
{
#ifdef USE_AES_CBC
case AES_ENC_ALG:
Printf("Encrypt ");
psGetTime(&start, NULL);
while (bytesSent < bytesToSend)
{
psAesEncryptCBC(&ctx->aes, dataChunk, dataChunk, chunk);
bytesSent += chunk;
}
psGetTime(&end, NULL);
break;
case AES_DEC_ALG:
Printf("Decrypt ");
psGetTime(&start, NULL);
while (bytesSent < bytesToSend)
{
psAesDecryptCBC(&ctx->aes, dataChunk, dataChunk, chunk);
bytesSent += chunk;
}
psGetTime(&end, NULL);
break;
#endif
#ifdef USE_AES_GCM
case AES_GCM_ALG:
psGetTime(&start, NULL);
while (bytesSent < bytesToSend)
{
psAesEncryptGCM(&ctx->aesgcm, dataChunk, dataChunk, chunk);
bytesSent += chunk;
}
psAesGetGCMTag(&ctx->aesgcm, 16, dataChunk);
psGetTime(&end, NULL);
break;
#endif
#ifdef USE_ARC4
case ARC4_ALG:
psGetTime(&start, NULL);
while (bytesSent < bytesToSend)
{
psArc4(&ctx->arc4, dataChunk, dataChunk, chunk);
bytesSent += chunk;
}
psGetTime(&end, NULL);
break;
#endif
#ifdef USE_3DES
case DES3_ALG:
psGetTime(&start, NULL);
while (bytesSent < bytesToSend)
{
psDes3Encrypt(&ctx->des3, dataChunk, dataChunk, chunk);
bytesSent += chunk;
}
psGetTime(&end, NULL);
break;
#endif
#ifdef USE_SEED
case SEED_ALG:
psGetTime(&start, NULL);
while (bytesSent < bytesToSend)
{
psSeedEncrypt(&ctx->seed, dataChunk, dataChunk, chunk);
bytesSent += chunk;
}
psGetTime(&end, NULL);
break;
#endif
#ifdef USE_IDEA
case IDEA_ALG:
psGetTime(&start, NULL);
while (bytesSent < bytesToSend)
{
psIdeaEncrypt(&ctx->idea, dataChunk, dataChunk, chunk);
bytesSent += chunk;
}
psGetTime(&end, NULL);
break;
#endif
#ifdef USE_CHACHA20_POLY1305_IETF
case CHACHA20POLY1305IETF_ALG:
{
static unsigned char chacha20_iv[] =
{
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f
};
static unsigned char chacha20_aad[] =
{
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b,
};
psGetTime(&start, NULL);
while (bytesSent < bytesToSend)
{
psChacha20Poly1305IetfEncryptDetached(
&ctx->chacha20poly1305ietf,
dataChunk,
chunk,
chacha20_iv,
chacha20_aad,
sizeof chacha20_aad,
dataChunk,
chacha20_aad);
bytesSent += chunk;
}
psGetTime(&end, NULL);
break;
}
#endif
default:
psFree(dataChunk, NULL);
return;
}
psFree(dataChunk, NULL);
#ifdef USE_HIGHRES_TIME
diffu = psDiffUsecs(start, end);
round = (bytesToSend / diffu);
mod = (bytesToSend % diffu);
Printf("%d byte chunks in %lld usecs total for rate of %d.%d MB/sec\n",
chunk, (unsigned long long) diffu, round, mod);
#else
diffm = psDiffMsecs(start, end, NULL);
if (diffm > 0)
{
round = (bytesToSend / diffm) / 1000;
Printf("%d byte chunks in %d msecs total for rate of %d MB/sec\n",
chunk, diffm, round);
}
else
{
diffm = 1;
round = (bytesToSend / diffm) / 1000;
Printf("%d byte chunks in less than %d msec total for rate of more than %d MB/sec\n",
chunk, diffm, round);
Printf("Use USE_HIGHRES_TIME for more accurate results.\n");
}
#endif
}
# endif /* USE_AES_CBC */
/******************************************************************************/
#ifdef USE_AES_CBC
static int32 psAesTestCBC(void)
{
int32 err;
psCipherContext_t eCtx;
# if defined(USE_MATRIX_AES_CBC) && !defined(PS_AES_IMPROVE_PERF_INCREASE_CODESIZE)
Printf("##########\n#\n# ");
Printf("AES speeds can be improved by enabling\n# ");
Printf("PS_AES_IMPROVE_PERF_INCREASE_CODESIZE in cryptoConfig.h\n");
Printf("#\n#\n#########\n");
# endif
Printf("***** AES-128 CBC *****\n");
if ((err = psAesInitCBC(&eCtx.aes, iv, key, 16, PS_AES_ENCRYPT)) != PS_SUCCESS)
{
Printf("FAILED: returned %d\n", err);
return err;
}
runTime(&eCtx, NULL, TINY_CHUNKS, AES_ENC_ALG);
runTime(&eCtx, NULL, SMALL_CHUNKS, AES_ENC_ALG);
runTime(&eCtx, NULL, MEDIUM_CHUNKS, AES_ENC_ALG);
runTime(&eCtx, NULL, LARGE_CHUNKS, AES_ENC_ALG);
runTime(&eCtx, NULL, LARGE_CHUNKS, AES_DEC_ALG);
runTime(&eCtx, NULL, HUGE_CHUNKS, AES_ENC_ALG);
runTime(&eCtx, NULL, HUGE_CHUNKS, AES_DEC_ALG);
psAesClearCBC(&eCtx.aes);
Printf("***** AES-192 CBC *****\n");
if ((err = psAesInitCBC(&eCtx.aes, iv, key, 24, PS_AES_ENCRYPT)) != PS_SUCCESS)
{
Printf("FAILED: returned %d\n", err);
return err;
}
runTime(&eCtx, NULL, TINY_CHUNKS, AES_ENC_ALG);
runTime(&eCtx, NULL, SMALL_CHUNKS, AES_ENC_ALG);
runTime(&eCtx, NULL, MEDIUM_CHUNKS, AES_ENC_ALG);
runTime(&eCtx, NULL, LARGE_CHUNKS, AES_ENC_ALG);
runTime(&eCtx, NULL, LARGE_CHUNKS, AES_DEC_ALG);
runTime(&eCtx, NULL, HUGE_CHUNKS, AES_ENC_ALG);
runTime(&eCtx, NULL, HUGE_CHUNKS, AES_DEC_ALG);
psAesClearCBC(&eCtx.aes);
Printf("***** AES-256 CBC *****\n");
if ((err = psAesInitCBC(&eCtx.aes, iv, key, 32, PS_AES_ENCRYPT)) != PS_SUCCESS)
{
Printf("FAILED: returned %d\n", err);
return err;
}
runTime(&eCtx, NULL, TINY_CHUNKS, AES_ENC_ALG);
runTime(&eCtx, NULL, SMALL_CHUNKS, AES_ENC_ALG);
runTime(&eCtx, NULL, MEDIUM_CHUNKS, AES_ENC_ALG);
runTime(&eCtx, NULL, LARGE_CHUNKS, AES_ENC_ALG);
runTime(&eCtx, NULL, LARGE_CHUNKS, AES_DEC_ALG);
runTime(&eCtx, NULL, HUGE_CHUNKS, AES_ENC_ALG);
runTime(&eCtx, NULL, HUGE_CHUNKS, AES_DEC_ALG);
psAesClearCBC(&eCtx.aes);
return 0;
}
# if defined(USE_HMAC_SHA1) || defined(USE_HMAC_SHA256)
static int32 psAesTestCBCHmac(void)
{
int32 err;
psCipherContext_t eCtx;
psHmac_t hCtx;
# if defined(USE_MATRIX_AES_CBC) && !defined(PS_AES_IMPROVE_PERF_INCREASE_CODESIZE)
Printf("##########\n#\n# ");
Printf("AES speeds can be improved by enabling\n# ");
Printf("PS_AES_IMPROVE_PERF_INCREASE_CODESIZE in cryptoConfig.h\n");
Printf("#\n#\n#########\n");
# endif
# ifdef USE_HMAC_SHA1
Printf("***** AES-128 CBC + SHA1-HMAC *****\n");
if ((err = psAesInitCBC(&eCtx.aes, iv, key, 16, PS_AES_ENCRYPT)) != PS_SUCCESS)
{
Printf("FAILED: returned %d\n", err);
return err;
}
psHmacSha1Init(&hCtx.u.sha1, key, SHA1_HASH_SIZE);
runWithHmac(&eCtx, &hCtx, 0, TINY_CHUNKS, AES_HMAC_ALG);
psHmacSha1Init(&hCtx.u.sha1, key, SHA1_HASH_SIZE);
runWithHmac(&eCtx, &hCtx, 0, SMALL_CHUNKS, AES_HMAC_ALG);
psHmacSha1Init(&hCtx.u.sha1, key, SHA1_HASH_SIZE);
runWithHmac(&eCtx, &hCtx, 0, MEDIUM_CHUNKS, AES_HMAC_ALG);
psHmacSha1Init(&hCtx.u.sha1, key, SHA1_HASH_SIZE);
runWithHmac(&eCtx, &hCtx, 0, LARGE_CHUNKS, AES_HMAC_ALG);
psHmacSha1Init(&hCtx.u.sha1, key, SHA1_HASH_SIZE);
runWithHmac(&eCtx, &hCtx, 0, HUGE_CHUNKS, AES_HMAC_ALG);
psAesClearCBC(&eCtx.aes);
Printf("***** AES-256 CBC + SHA1-HMAC *****\n");
if ((err = psAesInitCBC(&eCtx.aes, iv, key, 32, PS_AES_ENCRYPT)) != PS_SUCCESS)
{
Printf("FAILED: returned %d\n", err);
return err;
}
psHmacSha1Init(&hCtx.u.sha1, key, SHA1_HASH_SIZE);
runWithHmac(&eCtx, &hCtx, 0, TINY_CHUNKS, AES_HMAC_ALG);
psHmacSha1Init(&hCtx.u.sha1, key, SHA1_HASH_SIZE);
runWithHmac(&eCtx, &hCtx, 0, SMALL_CHUNKS, AES_HMAC_ALG);
psHmacSha1Init(&hCtx.u.sha1, key, SHA1_HASH_SIZE);
runWithHmac(&eCtx, &hCtx, 0, MEDIUM_CHUNKS, AES_HMAC_ALG);
psHmacSha1Init(&hCtx.u.sha1, key, SHA1_HASH_SIZE);
runWithHmac(&eCtx, &hCtx, 0, LARGE_CHUNKS, AES_HMAC_ALG);
psHmacSha1Init(&hCtx.u.sha1, key, SHA1_HASH_SIZE);
runWithHmac(&eCtx, &hCtx, 0, HUGE_CHUNKS, AES_HMAC_ALG);
psAesClearCBC(&eCtx.aes);
# endif
# ifdef USE_HMAC_SHA256
Printf("***** AES-128 CBC + SHA256-HMAC *****\n");
if ((err = psAesInitCBC(&eCtx.aes, iv, key, 16, PS_AES_ENCRYPT)) != PS_SUCCESS)
{
Printf("FAILED: returned %d\n", err);
return err;
}
psHmacSha256Init(&hCtx.u.sha256, key, 32);
runWithHmac(&eCtx, &hCtx, SHA256_HASH_SIZE, TINY_CHUNKS, AES_HMAC256_ALG);
psHmacSha256Init(&hCtx.u.sha256, key, 32);
runWithHmac(&eCtx, &hCtx, SHA256_HASH_SIZE, SMALL_CHUNKS, AES_HMAC256_ALG);
psHmacSha256Init(&hCtx.u.sha256, key, 32);
runWithHmac(&eCtx, &hCtx, SHA256_HASH_SIZE, MEDIUM_CHUNKS, AES_HMAC256_ALG);
psHmacSha256Init(&hCtx.u.sha256, key, 32);
runWithHmac(&eCtx, &hCtx, SHA256_HASH_SIZE, LARGE_CHUNKS, AES_HMAC256_ALG);
psHmacSha256Init(&hCtx.u.sha256, key, 32);
runWithHmac(&eCtx, &hCtx, SHA256_HASH_SIZE, HUGE_CHUNKS, AES_HMAC256_ALG);
psAesClearCBC(&eCtx.aes);
Printf("***** AES-256 CBC + SHA256-HMAC *****\n");
if ((err = psAesInitCBC(&eCtx.aes, iv, key, 32, PS_AES_ENCRYPT)) != PS_SUCCESS)
{
Printf("FAILED: returned %d\n", err);
return err;
}
psHmacSha256Init(&hCtx.u.sha256, key, 32);
runWithHmac(&eCtx, &hCtx, SHA256_HASH_SIZE, TINY_CHUNKS, AES_HMAC256_ALG);
psHmacSha256Init(&hCtx.u.sha256, key, 32);
runWithHmac(&eCtx, &hCtx, SHA256_HASH_SIZE, SMALL_CHUNKS, AES_HMAC256_ALG);
psHmacSha256Init(&hCtx.u.sha256, key, 32);
runWithHmac(&eCtx, &hCtx, SHA256_HASH_SIZE, MEDIUM_CHUNKS, AES_HMAC256_ALG);
psHmacSha256Init(&hCtx.u.sha256, key, 32);
runWithHmac(&eCtx, &hCtx, SHA256_HASH_SIZE, LARGE_CHUNKS, AES_HMAC256_ALG);
psHmacSha256Init(&hCtx.u.sha256, key, 32);
runWithHmac(&eCtx, &hCtx, SHA256_HASH_SIZE, HUGE_CHUNKS, AES_HMAC256_ALG);
psHmacSha256Init(&hCtx.u.sha256, key, 32);
psAesClearCBC(&eCtx.aes);
# endif
return 0;
}
# endif /* USE_HMAC */
/******************************************************************************/
# ifdef USE_AES_GCM
int32 psAesTestGCM(void)
{
int32 err;
psCipherContext_t eCtx;
psCipherGivContext_t eCtxGiv;
Memset(&eCtxGiv, 0, sizeof(eCtxGiv));
# ifndef USE_LIBSODIUM_AES_GCM
Printf("***** AES-GCM-128 *****\n");
if ((err = psAesInitGCM(&eCtx.aesgcm, key, 16)) != PS_SUCCESS)
{
Printf("FAILED: psAesInitGCM returned %d\n", err);
return err;
}
psAesReadyGCM(&eCtx.aesgcm, iv, iv, 16);
runTime(&eCtx, &eCtxGiv, TINY_CHUNKS, AES_GCM_ALG);
runTime(&eCtx, &eCtxGiv, SMALL_CHUNKS, AES_GCM_ALG);
runTime(&eCtx, &eCtxGiv, MEDIUM_CHUNKS, AES_GCM_ALG);
runTime(&eCtx, &eCtxGiv, LARGE_CHUNKS, AES_GCM_ALG);
runTime(&eCtx, &eCtxGiv, HUGE_CHUNKS, AES_GCM_ALG);
# else
Printf("***** Skipping AES-GCM-128 *****\n");
# endif /* !USE_LIBSODIUM */
Printf("***** AES-GCM-256 *****\n");
if ((err = psAesInitGCM(&eCtx.aesgcm, key, 32)) != PS_SUCCESS)
{
Printf("FAILED: psAesInitGCM returned %d\n", err);
return err;
}
psAesReadyGCM(&eCtx.aesgcm, iv, iv, 16);
runTime(&eCtx, &eCtxGiv, TINY_CHUNKS, AES_GCM_ALG);
runTime(&eCtx, &eCtxGiv, SMALL_CHUNKS, AES_GCM_ALG);
runTime(&eCtx, &eCtxGiv, MEDIUM_CHUNKS, AES_GCM_ALG);
runTime(&eCtx, &eCtxGiv, LARGE_CHUNKS, AES_GCM_ALG);
runTime(&eCtx, &eCtxGiv, HUGE_CHUNKS, AES_GCM_ALG);
psAesClearGCM(&eCtx.aesgcm);
return PS_SUCCESS;
}
# endif /* USE_AES_GCM */
# ifdef USE_AES_CTR
int32 psAesTestCTR(void)
{
return PS_SUCCESS;
}
# endif /* USE_AES_CTR */
#endif /* USE_AES */
/******************************************************************************/
#ifdef USE_3DES
int32 psDes3Test(void)
{
psCipherContext_t eCtx;
# if defined(USE_MATRIX_3DES) && !defined(PS_3DES_IMPROVE_PERF_INCREASE_CODESIZE)
Printf("##########\n#\n# ");
Printf("3DES speeds can be improved by enabling\n# ");
Printf("PS_3DES_IMPROVE_PERF_INCREASE_CODESIZE in cryptoConfig.h\n");
Printf("#\n#\n#########\n");
# endif
psDes3Init(&eCtx.des3, iv, key);
runTime(&eCtx, NULL, TINY_CHUNKS, DES3_ALG);
runTime(&eCtx, NULL, SMALL_CHUNKS, DES3_ALG);
runTime(&eCtx, NULL, MEDIUM_CHUNKS, DES3_ALG);
runTime(&eCtx, NULL, LARGE_CHUNKS, DES3_ALG);
runTime(&eCtx, NULL, HUGE_CHUNKS, DES3_ALG);
psDes3Clear(&eCtx.des3);
return 0;
}
#endif /* USE_3DES */
/******************************************************************************/
#ifdef USE_ARC4
int32 psArc4Test(void)
{
psCipherContext_t eCtx;
psArc4Init(&eCtx.arc4, key, 16);
runTime(&eCtx, NULL, TINY_CHUNKS, ARC4_ALG);
runTime(&eCtx, NULL, SMALL_CHUNKS, ARC4_ALG);
runTime(&eCtx, NULL, MEDIUM_CHUNKS, ARC4_ALG);
runTime(&eCtx, NULL, LARGE_CHUNKS, ARC4_ALG);
runTime(&eCtx, NULL, HUGE_CHUNKS, ARC4_ALG);
psArc4Clear(&eCtx.arc4);
return 0;
}
#endif /* USE_ARC4 */
/******************************************************************************/
#ifdef USE_SEED
int32 psSeedTest(void)
{
psCipherContext_t eCtx;
psSeedInit(&eCtx.seed, iv, key);
runTime(&eCtx, NULL, TINY_CHUNKS, SEED_ALG);
runTime(&eCtx, NULL, SMALL_CHUNKS, SEED_ALG);
runTime(&eCtx, NULL, MEDIUM_CHUNKS, SEED_ALG);
runTime(&eCtx, NULL, LARGE_CHUNKS, SEED_ALG);
runTime(&eCtx, NULL, HUGE_CHUNKS, SEED_ALG);
psSeedClear(&eCtx.seed);
return PS_SUCCESS;
}
#endif /* USE_SEED */
/******************************************************************************/
#ifdef USE_IDEA
int32 psIdeaTest(void)
{
psCipherContext_t eCtx;
psIdeaInit(&eCtx.idea, iv, key);
runTime(&eCtx, NULL, TINY_CHUNKS, IDEA_ALG);
runTime(&eCtx, NULL, SMALL_CHUNKS, IDEA_ALG);
runTime(&eCtx, NULL, MEDIUM_CHUNKS, IDEA_ALG);
runTime(&eCtx, NULL, LARGE_CHUNKS, IDEA_ALG);
runTime(&eCtx, NULL, HUGE_CHUNKS, IDEA_ALG);
psIdeaClear(&eCtx.idea);
return PS_SUCCESS;
}
#endif /* USE_IDEA */
/******************************************************************************/
void runDigestTime(psDigestContext_t *ctx, int32 chunk, int32 alg)
{
psTime_t start, end;
unsigned char *dataChunk;
unsigned char hashout[64];
int32 bytesSent, bytesToSend, round;
psRes_t rv;
#ifdef USE_HIGHRES_TIME
int32 mod;
int64 diffu;
#else
int32 diffm;
#endif
(void)rv;
dataChunk = psMalloc(NULL, chunk);
bytesToSend = (DATABYTES_AMOUNT / chunk) * chunk;
bytesSent = 0;
switch (alg)
{
#ifdef USE_SHA1
case SHA1_ALG:
psSha1Init(&ctx->u.sha1);
psGetTime(&start, NULL);
while (bytesSent < bytesToSend)
{
psSha1Update(&ctx->u.sha1, dataChunk, chunk);
bytesSent += chunk;
}
psSha1Final(&ctx->u.sha1, hashout);
psGetTime(&end, NULL);
break;
#endif
#ifdef USE_SHA256
case SHA256_ALG:
psSha256Init(&ctx->u.sha256);
psGetTime(&start, NULL);
while (bytesSent < bytesToSend)
{
psSha256Update(&ctx->u.sha256, dataChunk, chunk);
bytesSent += chunk;
}
psSha256Final(&ctx->u.sha256, hashout);
psGetTime(&end, NULL);
break;
#endif
#ifdef USE_SHA384
case SHA384_ALG:
psSha384Init(&ctx->u.sha384);
psGetTime(&start, NULL);
while (bytesSent < bytesToSend)
{
psSha384Update(&ctx->u.sha384, dataChunk, chunk);
bytesSent += chunk;
}
psSha384Final(&ctx->u.sha384, hashout);
psGetTime(&end, NULL);
break;
#endif
#ifdef USE_SHA512
case SHA512_ALG:
psSha512Init(&ctx->u.sha512);
psGetTime(&start, NULL);
while (bytesSent < bytesToSend)
{
psSha512Update(&ctx->u.sha512, dataChunk, chunk);
bytesSent += chunk;
}
psSha512Final(&ctx->u.sha512, hashout);
psGetTime(&end, NULL);
break;
#endif
#ifdef USE_MD5
case MD5_ALG:
rv = psMd5Init(&ctx->u.md5);
if (rv != PS_SUCCESS)
goto skipped;
psGetTime(&start, NULL);
while (bytesSent < bytesToSend)
{
psMd5Update(&ctx->u.md5, dataChunk, chunk);
bytesSent += chunk;
}
psMd5Final(&ctx->u.md5, hashout);
psGetTime(&end, NULL);
break;
#endif
default:
#ifdef USE_MD5
skipped:
#endif
psFree(dataChunk, NULL);
Printf("Skipping Digest Tests\n");
return;
}
#ifdef USE_HIGHRES_TIME
diffu = psDiffUsecs(start, end);
round = (bytesToSend / diffu);
mod = (bytesToSend % diffu);
Printf("%d byte chunks in %lld usecs total for rate of %d.%d MB/sec\n",
chunk, (unsigned long long) diffu, round, mod);
#else
diffm = psDiffMsecs(start, end, NULL);
round = (bytesToSend / diffm) / 1000;
Printf("%d byte chunks in %d msecs total for rate of %d MB/sec\n",
chunk, diffm, round);
#endif
psFree(dataChunk, NULL);
}
/******************************************************************************/
#ifdef USE_SHA1
int32 psSha1Test(void)
{
psDigestContext_t ctx;
# if defined(USE_MATRIX_SHA1) && !defined(PS_SHA1_IMPROVE_PERF_INCREASE_CODESIZE)
Printf("##########\n#\n# ");
Printf("SHA-1 speeds can be improved by enabling\n# ");
Printf("PS_SHA1_IMPROVE_PERF_INCREASE_CODESIZE in cryptoConfig.h\n");
Printf("#\n#\n#########\n");
# endif
runDigestTime(&ctx, TINY_CHUNKS, SHA1_ALG);
runDigestTime(&ctx, SMALL_CHUNKS, SHA1_ALG);
runDigestTime(&ctx, MEDIUM_CHUNKS, SHA1_ALG);
runDigestTime(&ctx, LARGE_CHUNKS, SHA1_ALG);
runDigestTime(&ctx, HUGE_CHUNKS, SHA1_ALG);
return PS_SUCCESS;
}
#endif /* USE_SHA1 */
/******************************************************************************/
/******************************************************************************/
#ifdef USE_SHA256
int32 psSha256Test(void)
{
psDigestContext_t ctx;
runDigestTime(&ctx, TINY_CHUNKS, SHA256_ALG);
runDigestTime(&ctx, SMALL_CHUNKS, SHA256_ALG);
runDigestTime(&ctx, MEDIUM_CHUNKS, SHA256_ALG);
runDigestTime(&ctx, LARGE_CHUNKS, SHA256_ALG);
runDigestTime(&ctx, HUGE_CHUNKS, SHA256_ALG);
return PS_SUCCESS;
}
#endif /* USE_SHA256 */
/******************************************************************************/
#ifdef USE_SHA384
int32 psSha384Test(void)
{
psDigestContext_t ctx;
runDigestTime(&ctx, TINY_CHUNKS, SHA384_ALG);
runDigestTime(&ctx, SMALL_CHUNKS, SHA384_ALG);
runDigestTime(&ctx, MEDIUM_CHUNKS, SHA384_ALG);
runDigestTime(&ctx, LARGE_CHUNKS, SHA384_ALG);
runDigestTime(&ctx, HUGE_CHUNKS, SHA384_ALG);
return PS_SUCCESS;
}
#endif /* USE_SHA384 */
#ifdef USE_SHA512
int32 psSha512Test(void)
{
psDigestContext_t ctx;
runDigestTime(&ctx, TINY_CHUNKS, SHA512_ALG);
runDigestTime(&ctx, SMALL_CHUNKS, SHA512_ALG);
runDigestTime(&ctx, MEDIUM_CHUNKS, SHA512_ALG);
runDigestTime(&ctx, LARGE_CHUNKS, SHA512_ALG);
runDigestTime(&ctx, HUGE_CHUNKS, SHA512_ALG);
return PS_SUCCESS;
}
#endif /* USE_SHA512 */
/******************************************************************************/
#ifdef USE_MD5
int32 psMd5Test(void)
{
psDigestContext_t ctx;
# if defined(USE_MATRIX_MD5) && !defined(PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE)
Printf("##########\n#\n# ");
Printf("MD5 speeds can be improved by enabling\n# ");
Printf("PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE in cryptoConfig.h\n");
Printf("#\n#\n#########\n");
# endif
runDigestTime(&ctx, TINY_CHUNKS, MD5_ALG);
runDigestTime(&ctx, SMALL_CHUNKS, MD5_ALG);
runDigestTime(&ctx, MEDIUM_CHUNKS, MD5_ALG);
runDigestTime(&ctx, LARGE_CHUNKS, MD5_ALG);
runDigestTime(&ctx, HUGE_CHUNKS, MD5_ALG);
return PS_SUCCESS;
}
#endif /* USE_MD5 */
/******************************************************************************/
/******************************************************************************/
#ifdef USE_MD4
int32 psMd4Test(void)
{
return PS_SUCCESS;
}
#endif /* USE_MD4 */
/******************************************************************************/
/******************************************************************************/
#ifdef USE_MD2
int32 psMd2Test(void)
{
return PS_SUCCESS;
}
#endif /* USE_MD2 */
/******************************************************************************/
# ifdef USE_CHACHA20_POLY1305_IETF
static unsigned char chacha20_key[] =
{
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
};
int32 psChacha20Poly1305IetfTest(void)
{
psCipherContext_t cip;
psChacha20Poly1305Ietf_t *ctx = &(cip.chacha20poly1305ietf);
psChacha20Poly1305IetfInit(ctx, chacha20_key);
/* Use sizes starting from CHACHA20 minimum block. */
runTime(&cip, NULL, CHACHA20_TINY_CHUNKS, CHACHA20POLY1305IETF_ALG);
runTime(&cip, NULL, SMALL_CHUNKS, CHACHA20POLY1305IETF_ALG);
runTime(&cip, NULL, MEDIUM_CHUNKS, CHACHA20POLY1305IETF_ALG);
runTime(&cip, NULL, LARGE_CHUNKS, CHACHA20POLY1305IETF_ALG);
runTime(&cip, NULL, HUGE_CHUNKS, CHACHA20POLY1305IETF_ALG);
return PS_SUCCESS;
}
# endif /* USE_CHACHA20_POLY1305_IETF */
/******************************************************************************/
typedef struct
{
int32 (*fn)(void);
char name[64];
} test_t;
static test_t tests[] = {
#ifdef USE_AES_CBC
{ psAesTestCBC, "***** AES-CBC TESTS *****" },
# if defined(USE_HMAC_SHA1) || defined(USE_HMAC_SHA256)
{ psAesTestCBCHmac, "***** AES-CBC + HMAC TESTS *****" },
# endif
# ifdef USE_AES_GCM
{ psAesTestGCM, "***** AES-GCM TESTS *****" },
# endif
# ifdef USE_AES_CTR
{ psAesTestCTR, "***** AES-CTR TESTS *****" },
# endif
#else
{ NULL, "AES" },
#endif
#ifdef USE_3DES
{ psDes3Test
#else
{ NULL
#endif
, "***** 3DES TESTS *****" },
#ifdef USE_SEED
{ psSeedTest
#else
{ NULL
#endif
, "***** SEED TESTS *****" },
#ifdef USE_IDEA
{ psIdeaTest
#else
{ NULL
#endif
, "***** IDEA TESTS *****" },
#ifdef USE_ARC4
{ psArc4Test
#else
{ NULL
#endif
, "***** RC4 TESTS *****" },
#ifdef USE_SHA1
{ psSha1Test
#else
{ NULL
#endif
, "***** SHA1 TESTS *****" },
#ifdef USE_SHA256
{ psSha256Test
#else
{ NULL
#endif
, "***** SHA256 TESTS *****" },
#ifdef USE_SHA384
{ psSha384Test
#else
{ NULL
#endif
, "***** SHA384 TESTS *****" },
#ifdef USE_SHA512
{ psSha512Test
#else
{ NULL
#endif
, "***** SHA512 TESTS *****" },
#ifdef USE_MD5
{ psMd5Test
#else
{ NULL
#endif
, "***** MD5 TESTS *****" },
#ifdef USE_MD4
{ psMd4Test
#else
{ NULL
#endif
, "***** MD4 TESTS *****" },
#ifdef USE_MD2
{ psMd2Test
#else
{ NULL
#endif
, "***** MD2 TESTS *****" },
#ifdef USE_CHACHA20_POLY1305_IETF
{ psChacha20Poly1305IetfTest
#else
{ NULL
#endif
, "***** CHACHA20-POLY1305 *****" },
{ NULL, "" }
};
/******************************************************************************/
/*
Main
*/
int main(int argc, char **argv)
{
int32 i;
int l;
if (argc > 1)
{
if (!Strcmp(argv[1], "--list"))
{
Printf("Tests:\n");
for (i = 0; *tests[i].name; i++)
{
Printf("%s\n", tests[i].name);
}
return 0;
}
for(l = 1; l < argc; l++)
{
for (i = 0; *tests[i].name; i++)
{
if (Strstr(tests[i].name, argv[l]))
{
break;
}
}
if (!*tests[i].name)
{
Fprintf(stderr, "Test not found: %s\n", argv[l]);
Fprintf(stderr, "Usage: %s [--list | test...]\n", argv[0]);
exit(1);
}
}
}
if (psCryptoOpen(PSCRYPTO_CONFIG) < PS_SUCCESS)
{
Printf("Failed to initialize library: psCryptoOpen failed\n");
return -1;
}
for (i = 0; *tests[i].name; i++)
{
for(l = 1; argc > 1 && l < argc; l++)
{
if (Strstr(tests[i].name, argv[l]))
{
break;
}
}
if (l == argc && argc > 1)
{
continue;
}
if (tests[i].fn)
{
Printf("%s\n", tests[i].name);
tests[i].fn();
}
else
{
Printf("%s: SKIPPED\n", tests[i].name);
}
}
psCryptoClose();
#ifdef WIN32
Printf("Press any key to close");
getchar();
#endif
return 0;
}