added libtomcrypt-0.76

This commit is contained in:
Tom St Denis 2003-03-03 01:00:16 +00:00 committed by Steffen Jaeckel
parent a6a5fc648b
commit a14a737164
27 changed files with 266 additions and 514 deletions

109
aes.c
View File

@ -317,73 +317,54 @@ void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
int rijndael_test(void)
{
int errno;
static const unsigned char pt128[16] = {
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
static const unsigned char key128[16] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
static const unsigned char ct128[16] = {
0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a };
static const unsigned char key192[24] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 };
static const unsigned char ct192[16] = {
0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 };
static const unsigned char key256[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 };
static const unsigned char ct256[16] = {
0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 };
static const struct {
int keylen;
unsigned char key[32], pt[16], ct[16];
} tests[] = {
{ 16,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }
}, {
24,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }
}, {
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 },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }
}
};
symmetric_key key;
unsigned char tmp[2][16];
int i;
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
if ((errno = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
return errno;
}
if ((errno = rijndael_setup(key128, 16, 0, &key)) != CRYPT_OK) {
return errno;
}
rijndael_ecb_encrypt(pt128, tmp[0], &key);
rijndael_ecb_decrypt(tmp[0], tmp[1], &key);
if (memcmp(tmp[0], ct128, 16)) {
return CRYPT_FAIL_TESTVECTOR;
}
if (memcmp(tmp[1], pt128, 16)) {
return CRYPT_FAIL_TESTVECTOR;
}
if ((errno = rijndael_setup(key192, 24, 0, &key)) != CRYPT_OK) {
return errno;
}
rijndael_ecb_encrypt(pt128, tmp[0], &key);
rijndael_ecb_decrypt(tmp[0], tmp[1], &key);
if (memcmp(tmp[0], ct192, 16)) {
return CRYPT_FAIL_TESTVECTOR;
}
if (memcmp(tmp[1], pt128, 16)) {
return CRYPT_FAIL_TESTVECTOR;
}
if ((errno = rijndael_setup(key256, 32, 0, &key)) != CRYPT_OK) {
return errno;
}
rijndael_ecb_encrypt(pt128, tmp[0], &key);
rijndael_ecb_decrypt(tmp[0], tmp[1], &key);
if (memcmp(tmp[0], ct256, 16)) {
return CRYPT_FAIL_TESTVECTOR;
}
if (memcmp(tmp[1], pt128, 16)) {
return CRYPT_FAIL_TESTVECTOR;
}
rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key);
rijndael_ecb_decrypt(tmp[0], tmp[1], &key);
if (memcmp(tmp[0], tests[i].ct, 16) || memcmp(tmp[1], tests[i].pt, 16)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
}

View File

@ -634,9 +634,9 @@ int blowfish_test(void)
}
};
unsigned char buf[2][8];
int x, failed;
int x;
for (x = failed = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
/* setup key */
if ((errno = blowfish_setup(tests[x].key, 8, 16, &key)) != CRYPT_OK) {
return errno;
@ -647,32 +647,11 @@ int blowfish_test(void)
blowfish_ecb_decrypt(buf[0], buf[1], &key);
/* compare */
if (memcmp(buf[0], tests[x].ct, 8)) {
#if 0
int y;
printf("\nEncrypt test %d failed\n", x);
for (y = 0; y < 8; y++) printf("%02x ", buf[0][y]);
printf("\n");
#endif
failed = 1;
}
if (memcmp(buf[1], tests[x].pt, 8)) {
#if 0
int y;
printf("\nDecrypt test %d failed\n", x);
for (y = 0; y < 8; y++) printf("%02x ", buf[1][y]);
printf("\n");
#endif
failed = 1;
if (memcmp(buf[0], tests[x].ct, 8) || memcmp(buf[1], tests[x].pt, 8)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
if (failed == 1) {
return CRYPT_FAIL_TESTVECTOR;
} else {
return CRYPT_OK;
}
return CRYPT_OK;
}
int blowfish_keysize(int *desired_keysize)

17
cast5.c
View File

@ -583,23 +583,8 @@ int cast5_test(void)
return errno;
}
cast5_ecb_encrypt(tests[i].pt, buf, &key);
if (memcmp(buf, tests[i].ct, 8)) {
#if 0
int j;
printf("\n\n\nFailed encrypt test: %d\n", i);
for (j = 0; j < 8; j++) printf("%02x ", buf[j]);
printf("\n");
#endif
return CRYPT_FAIL_TESTVECTOR;
}
cast5_ecb_decrypt(buf, buf2, &key);
if (memcmp(buf2, tests[i].pt, 8)) {
#if 0
int j;
printf("\n\n\nFailed decrypt test: %d\n", i);
for (j = 0; j < 8; j++) printf("%02x ", buf2[j]);
printf("\n");
#endif
if (memcmp(buf, tests[i].ct, 8) || memcmp(buf2, tests[i].pt, 8)) {
return CRYPT_FAIL_TESTVECTOR;
}

10
changes
View File

@ -1,3 +1,13 @@
Nov 25th, 2002
v0.76 -- Updated makefiles a bit more, use "-Os" instead of "-O2" to optimize for size. Got the lib
downto 265KB using GCC 3.2 on my x86 box.
-- Updated the SAFER+, Twofish and Rijndael test vector routine to use the table driven design.
-- Updated all other test vector routines to return as soon as an error is found
-- fixed a bug in the test program where errors in the hash test routines would not be reported
correctly. I found this by temporarily changing one of the bytes of the test vectors. All the
hashes check out [the demos/test.c would still have reported an error, just the wrong one].
Nov 24th, 2002
v0.75 -- Fixed a flaw in hash_filehandle, it should ARGCHK that the filehandle is not NULL
-- Fixed a bug where in hash_file if the call to hash_filehandle failed the open file would

BIN
crypt.pdf

Binary file not shown.

View File

@ -44,7 +44,7 @@
\def\gap{\vspace{0.5ex}}
\makeindex
\begin{document}
\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.75}
\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.76}
\author{Tom St Denis \\
Algonquin College \\
\\

View File

@ -307,7 +307,7 @@ void hash_tests(void)
printf("Hash tests\n");
for (x = 0; hash_descriptor[x].name != NULL; x++) {
printf(" %10s (%2d) ", hash_descriptor[x].name, hash_descriptor[x].ID);
if (hash_descriptor[x].test() != CRYPT_OK)
if ((errno = hash_descriptor[x].test()) != CRYPT_OK)
printf("**failed** Reason: %s\n", error_to_string(errno));
else
printf("passed\n");

23
des.c
View File

@ -630,7 +630,7 @@ int des_test(void)
http://www.ecs.soton.ac.uk/~prw99r/ez438/vectors.txt
***/
};
int i, failed=0;
int i;
unsigned char out[8];
symmetric_key des;
@ -646,29 +646,10 @@ int des_test(void)
}
if (memcmp(cases[i].out, out, sizeof out) != 0) {
#if 0
int j;
printf("DES test #%d failed!\n", cases[i].num);
printf( "got: ");
for (j=0; j < (int)sizeof out; j++) {
printf("%02x ", out[j] & 0xff);
}
printf("\nwanted: ");
for(j=0; j < (int)sizeof out; j++) {
printf("%02x ", cases[i].out[j] & 0xff);
}
printf("\n");
#endif
failed++;
return CRYPT_FAIL_TESTVECTOR;
}
}
if(failed > 0) {
return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
}

9
ecc.c
View File

@ -251,8 +251,8 @@ static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus)
if (mp_mul_2(&P->y, &tmp) != MP_OKAY) { goto error; } /* tmp = 2*y */
if (mp_invmod(&tmp, modulus, &tmp) != MP_OKAY) { goto error; } /* tmp = 1/tmp mod modulus */
if (mp_sqr(&P->x, &s) != MP_OKAY) { goto error; } /* s = x^2 */
if (mp_mul_d(&s, 3, &s) != MP_OKAY) { goto error; } /* s = 3*(x^2) */
if (mp_sub_d(&s, 3, &s) != MP_OKAY) { goto error; } /* s = 3*(x^2) - 3 */
if (mp_mul_d(&s,(mp_digit)3, &s) != MP_OKAY) { goto error; } /* s = 3*(x^2) */
if (mp_sub_d(&s,(mp_digit)3, &s) != MP_OKAY) { goto error; } /* s = 3*(x^2) - 3 */
if (mp_mulmod(&s, &tmp, modulus, &s) != MP_OKAY) { goto error; } /* s = tmp * s mod modulus */
/* Xr = s^2 - 2Xp */
@ -565,10 +565,11 @@ static int compress_y_point(ecc_point *pt, int idx, int *result)
if (mp_exptmod(&tmp, &tmp2, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = (x^3 - 3x + b)^((p+1)/4) mod p */
/* if tmp equals the y point give a 0, otherwise 1 */
if (mp_cmp(&tmp, &pt->y) == 0)
if (mp_cmp(&tmp, &pt->y) == 0) {
*result = 0;
else
} else {
*result = 1;
}
res = CRYPT_OK;
goto done;

View File

@ -9,7 +9,7 @@
# a build. This is easy to remedy though, for those that have problems.
# The version
VERSION=0.75
VERSION=0.76
#Compiler and Linker Names
CC=gcc
@ -34,10 +34,10 @@ CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wno-unused -Werror \
-DXCLOCKS_PER_SEC=$(XCLOCKS_PER_SEC)
#optimize for SPEED (comment out SIZE/DEBUG line as well)
#CFLAGS += -O3 -fomit-frame-pointer -funroll-loops
#CFLAGS += -O3 -funroll-loops
#optimize for SIZE (comment out SPEED/DEBUG line as well)
CFLAGS += -O2
CFLAGS += -Os
#compile for DEBUGGING
#CFLAGS += -g3

View File

@ -51,7 +51,7 @@ CFLAGS += -DNO_FILE
#CFLAGS += -O3 -fomit-frame-pointer -funroll-loops
#optimize for SIZE (comment out SPEED line as well)
CFLAGS += -O2
CFLAGS += -Os
#These flags control how the library gets built.

13
md2.c
View File

@ -180,19 +180,6 @@ int md2_test(void)
md2_process(&md, tests[i].msg, strlen(tests[i].msg));
md2_done(&md, buf);
if (memcmp(buf, tests[i].md, 16)) {
#if 0
int j;
printf("\n\nFailed test %d\n\n", i);
for (j = 0; j < 16; j++) {
printf("%02x ", buf[j]);
}
printf("\n");
printf("Should have been\n");
for (j = 0; j < 16; j++) {
printf("%02x ", tests[i].md[j]);
}
printf("\n");
#endif
return CRYPT_FAIL_TESTVECTOR;
}
}

26
md4.c
View File

@ -249,39 +249,19 @@ int md4_test(void)
{0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19,
0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36} },
};
int i, failed;
int i;
hash_state md;
unsigned char digest[16];
failed = 0;
for(i = 0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) {
md4_init(&md);
md4_process(&md, cases[i].input, cases[i].inputlen);
md4_done(&md, digest);
if(memcmp(digest, cases[i].digest, 16) != 0) {
#if 0
int j;
printf("\nMD4 test #%d failed\n", cases[i].num);
printf( "Result: 0x");
for(j=0; j < 16; j++) {
printf("%2x", digest[j]);
}
printf("\nCorrect: 0x");
for(j=0; j < 16; j++) {
printf("%2x", cases[i].digest[j]);
}
printf("\n");
#endif
failed++;
} else {
/* printf("MD4 test #%d succeeded.\n", cases[i].num); */
if (memcmp(digest, cases[i].digest, 16) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
}
if (failed) {
return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
}

20
md5.c
View File

@ -236,31 +236,19 @@ int md5_test(void)
{ NULL, { 0 } }
};
int failed, i;
int i;
unsigned char tmp[16];
hash_state md;
for (failed = i = 0; tests[i].msg != NULL; i++) {
for (i = 0; tests[i].msg != NULL; i++) {
md5_init(&md);
md5_process(&md, tests[i].msg, strlen(tests[i].msg));
md5_done(&md, tmp);
if (memcmp(tmp, tests[i].hash, 16)) {
#if 0
int j;
printf("MD5 Test %d (len == %d) failed\nGot (as a result): ", i, strlen(tests[i].msg));
for (j = 0; j < 16; j++) {
printf("%02x ", tmp[j]);
}
printf("\n");
#endif
failed = 1;
return CRYPT_FAIL_TESTVECTOR;
}
}
if (failed == 1) {
return CRYPT_FAIL_TESTVECTOR;
} else {
return CRYPT_OK;
}
return CRYPT_OK;
}
#endif

View File

@ -13,8 +13,8 @@ extern "C" {
#endif
/* version */
#define CRYPT 0x0075
#define SCRYPT "0.75"
#define CRYPT 0x0076
#define SCRYPT "0.76"
/* max size of either a cipher/hash block or symmetric key [largest of the two] */
#define MAXBLOCKSIZE 128

52
notes/tech0002.txt Normal file
View File

@ -0,0 +1,52 @@
Tech Note 0002
How to avoid non-intrusive timing attacks with online computations
Tom St Denis
Introduction
------------
A timing attack is when an attacker can observe a side channel of the device (in this case time). In this tech note
we consider only non-intrusive timing attacks with respect to online computations. That is an attacker can
determine when a computation (such as a public key encryption) begins and ends but cannot observe the device
directly. This is specifically important for applications which transmit data via a public network.
Consider a Diffie-Hellman encryption which requires the sender to make up a public key "y = g^x mod p". Libtomcrypt
uses the MPI bignum library to perform the operation. The time it takes to compute y is controlled by the number
of 1 bits in the exponent 'x'. To a large extent there will be the same number of squaring operations. "1" bits in
the exponent require the sender to perform a multiplication. This means to a certain extent an attacker can
determine not only the magnitude of 'x' but the number of one bits. With this information the attacker cannot directly
learn the key used. However, good cryptography mandates the close scrutiny of any practical side channel.
Similar logic applies to the other various routines. Fortunately for this case there is a simple solution. First,
determine the maximum time the particular operation can require. For instance, on an Athlon 1.53Ghz XP processor a
DH-768 encryption requires roughly 50 milliseconds. Take that time and round it up. Now place a delay after the call.
For example,
void demo(void) {
clock_t t1;
// get initial clock
t1 = clock();
// some PK function
// now delay
while (clock() < (t1 + 100));
// transmit data...
}
This code has the effect of taking at least 100 ms always. In effect someone analyzing the traffic will see that the
operations always take a fixed amount of time. Since no two platforms are the same this type of fix has not been
incorporated into libtomcrypt (nor is it desired for many platforms). This requires on the developers part to profile
the code to determine the delays required.
Note that this "quick" fix has no effect against an intrusive attacker. For example, power consumption will drop
significantly in the loop after the operation. However, this type of fix is more important to secure the user of the
application/device. For example, a user placing an order online won't try to cheat themselves by cracking open their
device and performing side-channel cryptanalysis. An attacker over a network might try to use the timing information
against the user.

34
rc2.c
View File

@ -258,11 +258,10 @@ int rc2_test(void)
{ 0x22, 0x69, 0x55, 0x2a, 0xb0, 0xf8, 0x5c, 0xa6 }
}
};
int x, failed, errno;
int x, errno;
symmetric_key skey;
unsigned char buf[2][8];
failed = 0;
for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
zeromem(buf, sizeof(buf));
if ((errno = rc2_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) {
@ -272,36 +271,11 @@ int rc2_test(void)
rc2_ecb_encrypt(tests[x].pt, buf[0], &skey);
rc2_ecb_decrypt(buf[0], buf[1], &skey);
if (memcmp(buf[0], tests[x].ct, 8)) {
#if 0
int y;
printf("\nTest %d failed to encrypt\n", x);
for (y = 0; y < 8; y++) {
printf("%02x ", buf[0][y]);
}
printf("\n");
#endif
failed = 1;
}
if (memcmp(buf[1], tests[x].pt, 8)) {
#if 0
int y;
printf("\nTest %d failed to decrypt\n", x);
for (y = 0; y < 8; y++) {
printf("%02x ", buf[1][y]);
}
printf("\n");
#endif
failed = 1;
if (memcmp(buf[0], tests[x].ct, 8) || memcmp(buf[1], tests[x].pt, 8)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
if (failed == 1) {
return CRYPT_FAIL_TESTVECTOR;
} else {
return CRYPT_OK;
}
return CRYPT_OK;
}
int rc2_keysize(int *keysize)

31
rc5.c
View File

@ -175,10 +175,10 @@ int rc5_test(void)
}
};
unsigned char buf[2][8];
int x, failed, errno;
int x, errno;
symmetric_key key;
for (x = failed = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
/* setup key */
if ((errno = rc5_setup(tests[x].key, 16, 12, &key)) != CRYPT_OK) {
return errno;
@ -189,32 +189,11 @@ int rc5_test(void)
rc5_ecb_decrypt(buf[0], buf[1], &key);
/* compare */
if (memcmp(buf[0], tests[x].ct, 8)) {
#if 0
int y;
printf("\nEncrypt test %d failed\n", x);
for (y = 0; y < 8; y++) printf("%02x ", buf[0][y]);
printf("\n");
#endif
failed = 1;
}
if (memcmp(buf[1], tests[x].pt, 8)) {
#if 0
int y;
printf("\nDecrypt test %d failed\n", x);
for (y = 0; y < 8; y++) printf("%02x ", buf[1][y]);
printf("\n");
#endif
failed = 1;
if (memcmp(buf[0], tests[x].ct, 8) || memcmp(buf[1], tests[x].pt, 8)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
if (failed == 1) {
return CRYPT_FAIL_TESTVECTOR;
} else {
return CRYPT_OK;
}
return CRYPT_OK;
}
int rc5_keysize(int *desired_keysize)

31
rc6.c
View File

@ -195,10 +195,10 @@ int rc6_test(void)
}
};
unsigned char buf[2][16];
int x, failed, errno;
int x, errno;
symmetric_key key;
for (x = failed = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
/* setup key */
if ((errno = rc6_setup(tests[x].key, tests[x].keylen, 0, &key)) != CRYPT_OK) {
return errno;
@ -209,32 +209,11 @@ int rc6_test(void)
rc6_ecb_decrypt(buf[0], buf[1], &key);
/* compare */
if (memcmp(buf[0], tests[x].ct, 16)) {
#if 0
int y;
printf("\nEncrypt test %d failed\n", x);
for (y = 0; y < 16; y++) printf("%02x ", buf[0][y]);
printf("\n");
#endif
failed = 1;
}
if (memcmp(buf[1], tests[x].pt, 16)) {
#if 0
int y;
printf("\nDecrypt test %d failed\n", x);
for (y = 0; y < 16; y++) printf("%02x ", buf[1][y]);
printf("\n");
#endif
failed = 1;
if (memcmp(buf[0], tests[x].ct, 16) || memcmp(buf[1], tests[x].pt, 16)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
if (failed == 1) {
return CRYPT_FAIL_TESTVECTOR;
} else {
return CRYPT_OK;
}
return CRYPT_OK;
}
int rc6_keysize(int *desired_keysize)

110
safer+.c
View File

@ -407,77 +407,55 @@ void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ke
int saferp_test(void)
{
static const unsigned char key128[16] =
{ 41, 35, 190, 132, 225, 108, 214, 174,
82, 144, 73, 241, 241, 187, 233, 235 };
static const unsigned char pt128[16] =
{ 179, 166, 219, 60, 135, 12, 62, 153,
36, 94, 13, 28, 6, 183, 71, 222 };
static const unsigned char ct128[16] =
{ 224, 31, 182, 10, 12, 255, 84, 70,
127, 13, 89, 249, 9, 57, 165, 220 };
static const unsigned char key192[24] =
{ 72, 211, 143, 117, 230, 217, 29, 42,
229, 192, 247, 43, 120, 129, 135, 68,
14, 95, 80, 0, 212, 97, 141, 190 };
static const unsigned char pt192[16] =
{ 123, 5, 21, 7, 59, 51, 130, 31,
24, 112, 146, 218, 100, 84, 206, 177 };
static const unsigned char ct192[16] =
{ 92, 136, 4, 63, 57, 95, 100, 0,
150, 130, 130, 16, 193, 111, 219, 133 };
static const unsigned char key256[32] =
{ 243, 168, 141, 254, 190, 242, 235, 113,
255, 160, 208, 59, 117, 6, 140, 126,
135, 120, 115, 77, 208, 190, 130, 190,
219, 194, 70, 65, 43, 140, 250, 48 };
static const unsigned char pt256[16] =
{ 127, 112, 240, 167, 84, 134, 50, 149,
170, 91, 104, 19, 11, 230, 252, 245 };
static const unsigned char ct256[16] =
{ 88, 11, 25, 36, 172, 229, 202, 213,
170, 65, 105, 153, 220, 104, 153, 138 };
static const struct {
int keylen;
unsigned char key[32], pt[16], ct[16];
} tests[] = {
{
16,
{ 41, 35, 190, 132, 225, 108, 214, 174,
82, 144, 73, 241, 241, 187, 233, 235 },
{ 179, 166, 219, 60, 135, 12, 62, 153,
36, 94, 13, 28, 6, 183, 71, 222 },
{ 224, 31, 182, 10, 12, 255, 84, 70,
127, 13, 89, 249, 9, 57, 165, 220 }
}, {
24,
{ 72, 211, 143, 117, 230, 217, 29, 42,
229, 192, 247, 43, 120, 129, 135, 68,
14, 95, 80, 0, 212, 97, 141, 190 },
{ 123, 5, 21, 7, 59, 51, 130, 31,
24, 112, 146, 218, 100, 84, 206, 177 },
{ 92, 136, 4, 63, 57, 95, 100, 0,
150, 130, 130, 16, 193, 111, 219, 133 }
}, {
32,
{ 243, 168, 141, 254, 190, 242, 235, 113,
255, 160, 208, 59, 117, 6, 140, 126,
135, 120, 115, 77, 208, 190, 130, 190,
219, 194, 70, 65, 43, 140, 250, 48 },
{ 127, 112, 240, 167, 84, 134, 50, 149,
170, 91, 104, 19, 11, 230, 252, 245 },
{ 88, 11, 25, 36, 172, 229, 202, 213,
170, 65, 105, 153, 220, 104, 153, 138 }
}
};
unsigned char buf[2][16];
symmetric_key skey;
int errno;
int errno, i;
/* test 128-bit key */
if ((errno = saferp_setup(key128, 16, 0, &skey)) != CRYPT_OK) {
return errno;
}
saferp_ecb_encrypt(pt128, buf[0], &skey);
saferp_ecb_decrypt(buf[0], buf[1], &skey);
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
if ((errno = saferp_setup(tests[i].key, tests[i].keylen, 0, &skey)) != CRYPT_OK) {
return errno;
}
saferp_ecb_encrypt(tests[i].pt, buf[0], &skey);
saferp_ecb_decrypt(buf[0], buf[1], &skey);
/* compare */
if (memcmp(buf[0], &ct128, 16) || memcmp(buf[1], &pt128, 16)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* test 192-bit key */
if ((errno = saferp_setup(key192, 24, 0, &skey)) != CRYPT_OK) {
return errno;
}
saferp_ecb_encrypt(pt192, buf[0], &skey);
saferp_ecb_decrypt(buf[0], buf[1], &skey);
/* compare */
if (memcmp(buf[0], &ct192, 16) || memcmp(buf[1], &pt192, 16)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* test 256-bit key */
if ((errno = saferp_setup(key256, 32, 0, &skey)) != CRYPT_OK) {
return errno;
}
saferp_ecb_encrypt(pt256, buf[0], &skey);
saferp_ecb_decrypt(buf[0], buf[1], &skey);
/* compare */
if (memcmp(buf[0], &ct256, 16) || memcmp(buf[1], &pt256, 16)) {
return CRYPT_FAIL_TESTVECTOR;
/* compare */
if (memcmp(buf[0], tests[i].ct, 16) || memcmp(buf[1], tests[i].pt, 16)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;

View File

@ -661,10 +661,10 @@ int serpent_test(void)
};
unsigned char buf[2][16];
int x, failed, errno;
int x, errno;
symmetric_key key;
for (x = failed = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
/* setup key */
if ((errno = serpent_setup(tests[x].key, tests[x].keylen, 0, &key))!= CRYPT_OK) {
return errno;
@ -675,32 +675,11 @@ int serpent_test(void)
serpent_ecb_decrypt(buf[0], buf[1], &key);
/* compare */
if (memcmp(buf[0], tests[x].ct, 16)) {
#if 0
int y;
printf("\nEncrypt test %d failed\n", x);
for (y = 0; y < 16; y++) printf("%02x ", buf[0][y]);
printf("\n");
#endif
failed = 1;
}
if (memcmp(buf[1], tests[x].pt, 16)) {
#if 0
int y;
printf("\nDecrypt test %d failed\n", x);
for (y = 0; y < 16; y++) printf("%02x ", buf[1][y]);
printf("\n");
#endif
failed = 1;
if (memcmp(buf[0], tests[x].ct, 16) || memcmp(buf[1], tests[x].pt, 16)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
if (failed == 1) {
return CRYPT_FAIL_TESTVECTOR;
} else {
return CRYPT_OK;
}
return CRYPT_OK;
}
int serpent_keysize(int *desired_keysize)

23
sha1.c
View File

@ -196,35 +196,22 @@ int sha1_test(void)
{ 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
0xE5, 0x46, 0x70, 0xF1 }
},
{ NULL, { 0 }}
}
};
int failed, i;
int i;
unsigned char tmp[20];
hash_state md;
for (failed = i = 0; tests[i].msg != NULL; i++) {
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha1_init(&md);
sha1_process(&md, tests[i].msg, strlen(tests[i].msg));
sha1_done(&md, tmp);
if (memcmp(tmp, tests[i].hash, 20)) {
#if 0
int j;
printf("\nSHA-1 Test %d failed\nGot (as a result): ", i);
for (j = 0; j < 20; j++) {
printf("%02x ", tmp[j]);
}
printf("\n");
#endif
failed = 1;
return CRYPT_FAIL_TESTVECTOR;
}
}
if (failed == 1) {
return CRYPT_FAIL_TESTVECTOR;
} else {
return CRYPT_OK;
}
return CRYPT_OK;
}
#endif

View File

@ -32,7 +32,7 @@ static const unsigned long K[64] = {
};
/* Various logical functions */
#define Ch(x,y,z) ((x & y) ^ (~x & z))
#define Ch(x,y,z) ((x & y) | (~x & z))
#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
#define S(x, n) ROR((x),(n))
#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
@ -194,34 +194,21 @@ int sha256_test(void)
0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 }
},
{ NULL, { 0 } }
};
int failed, i;
int i;
unsigned char tmp[32];
hash_state md;
for (failed = i = 0; tests[i].msg != NULL; i++) {
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha256_init(&md);
sha256_process(&md, tests[i].msg, strlen(tests[i].msg));
sha256_done(&md, tmp);
if (memcmp(tmp, tests[i].hash, 32)) {
#if 0
int j;
printf("\nSHA-256 Test %d failed\nGot (as a result): ", i);
for (j = 0; j < 32; j++) {
printf("%02x ", tmp[j]);
}
printf("\n");
#endif
failed = 1;
return CRYPT_FAIL_TESTVECTOR;
}
}
if (failed == 1) {
return CRYPT_FAIL_TESTVECTOR;
} else {
return CRYPT_OK;
}
return CRYPT_OK;
}
#endif

View File

@ -71,34 +71,21 @@ int sha384_test(void)
0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9,
0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 }
},
{ NULL, { 0 }}
};
int failed, i;
int i;
unsigned char tmp[48];
hash_state md;
for (failed = i = 0; tests[i].msg != NULL; i++) {
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha384_init(&md);
sha384_process(&md, tests[i].msg, strlen(tests[i].msg));
sha384_done(&md, tmp);
if (memcmp(tmp, tests[i].hash, 48)) {
#if 0
int j;
printf("\nSHA-384 Test %d failed\nGot (as a result): ", i);
for (j = 0; j < 48; j++) {
printf("%02x ", tmp[j]);
}
printf("\n");
#endif
failed = 1;
return CRYPT_FAIL_TESTVECTOR;
}
}
if (failed == 1) {
return CRYPT_FAIL_TESTVECTOR;
} else {
return CRYPT_OK;
}
return CRYPT_OK;
}

View File

@ -59,7 +59,7 @@ CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817)
};
/* Various logical functions */
#define Ch(x,y,z) ((x & y) ^ (~x & z))
#define Ch(x,y,z) ((x & y) | (~x & z))
#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
#define S(x, n) ROR64((x),(n))
#define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n))
@ -232,34 +232,21 @@ int sha512_test(void)
0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }
},
{ NULL, { 0 }}
};
int failed, i;
int i;
unsigned char tmp[64];
hash_state md;
for (failed = i = 0; tests[i].msg != NULL; i++) {
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha512_init(&md);
sha512_process(&md, tests[i].msg, strlen(tests[i].msg));
sha512_done(&md, tmp);
if (memcmp(tmp, tests[i].hash, 64)) {
#if 0
int j;
printf("\nSHA-512 Test %d failed\nGot (as a result): ", i);
for (j = 0; j < 64; j++) {
printf("%02x ", tmp[j]);
}
printf("\n");
#endif
failed = 1;
return CRYPT_FAIL_TESTVECTOR;
}
}
if (failed == 1) {
return CRYPT_FAIL_TESTVECTOR;
} else {
return CRYPT_OK;
}
return CRYPT_OK;
}
#ifdef SHA384

21
tiger.c
View File

@ -718,34 +718,21 @@ int tiger_test(void)
0x58, 0x48, 0xa7, 0xe0, 0xae, 0x6a, 0xac, 0x76,
0xe4, 0xff, 0x59, 0x0a, 0xe7, 0x15, 0xfd, 0x25 }
},
{ NULL, { 0 }}
};
int failed, i;
int i;
unsigned char tmp[24];
hash_state md;
for (failed = i = 0; tests[i].msg != NULL; i++) {
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
tiger_init(&md);
tiger_process(&md, tests[i].msg, strlen(tests[i].msg));
tiger_done(&md, tmp);
if (memcmp(tmp, tests[i].hash, 24)) {
#if 0
int j;
printf("\nTIGER-192 Test %d failed\nGot (as a result): ", i);
for (j = 0; j < 24; j++) {
printf("%02x ", tmp[j]);
}
printf("\n");
#endif
failed = 1;
return CRYPT_FAIL_TESTVECTOR;
}
}
if (failed == 1) {
return CRYPT_FAIL_TESTVECTOR;
} else {
return CRYPT_OK;
}
return CRYPT_OK;
}
#endif

106
twofish.c
View File

@ -225,9 +225,9 @@ static unsigned long sbox(int i, unsigned long x)
burn_stack(sizeof(unsigned char) * 11);
return y;
}
#endif
#endif /* CLEAN_STACK */
#endif
#endif /* TWOFISH_TABLES */
/* computes ab mod p */
static unsigned long gf_mult(unsigned long a, unsigned long b, unsigned long p)
@ -637,70 +637,54 @@ void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k
int twofish_test(void)
{
static const unsigned char key128[16] = {
0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,
0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A };
static const unsigned char pt128[16] = {
0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E,
0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19 };
static const unsigned char ct128[16] = {
0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85,
0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3 };
static const struct {
int keylen;
unsigned char key[32], pt[16], ct[16];
} tests[] = {
{ 16,
{ 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,
0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A },
{ 0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E,
0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19 },
{ 0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85,
0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3 }
}, {
24,
{ 0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36,
0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88,
0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44 },
{ 0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5,
0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 },
{ 0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45,
0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 }
}, {
32,
{ 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46,
0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D,
0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B,
0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F },
{ 0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F,
0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 },
{ 0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97,
0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA }
}
};
static const unsigned char key192[24] = {
0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36,
0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88,
0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44 };
static const unsigned char pt192[16] = {
0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5,
0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 };
static const unsigned char ct192[16] = {
0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45,
0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 };
static const unsigned char key256[32] = {
0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46,
0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D,
0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B,
0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F };
static const unsigned char pt256[16] = {
0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F,
0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 };
static const unsigned char ct256[16] = {
0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97,
0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA };
symmetric_key key;
unsigned char tmp[2][16];
int errno;
if ((errno = twofish_setup(key128, 16, 0, &key)) != CRYPT_OK) {
return errno;
}
twofish_ecb_encrypt(pt128, tmp[0], &key);
twofish_ecb_decrypt(tmp[0], tmp[1], &key);
if (memcmp(tmp[0], ct128, 16) || memcmp(tmp[1], pt128, 16)) {
return CRYPT_FAIL_TESTVECTOR;
}
int errno, i;
if ((errno = twofish_setup(key192, 24, 0, &key)) != CRYPT_OK) {
return errno;
}
twofish_ecb_encrypt(pt192, tmp[0], &key);
twofish_ecb_decrypt(tmp[0], tmp[1], &key);
if (memcmp(tmp[0], ct192, 16) || memcmp(tmp[1], pt192, 16)) {
return CRYPT_FAIL_TESTVECTOR;
}
if ((errno = twofish_setup(key256, 32, 0, &key)) != CRYPT_OK) {
return errno;
}
twofish_ecb_encrypt(pt256, tmp[0], &key);
twofish_ecb_decrypt(tmp[0], tmp[1], &key);
if (memcmp(tmp[0], ct256, 16) || memcmp(tmp[1], pt256, 16)) {
return CRYPT_FAIL_TESTVECTOR;
}
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
if ((errno = twofish_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
return errno;
}
twofish_ecb_encrypt(tests[i].pt, tmp[0], &key);
twofish_ecb_decrypt(tmp[0], tmp[1], &key);
if (memcmp(tmp[0], tests[i].ct, 16) || memcmp(tmp[1], tests[i].pt, 16)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
}