| double cpu_speed = 0.0; |
double cpu_speed = 0.0; |
| double test_time = 3.0; |
double test_time = 3.0; |
| |
|
| |
int quiet = 0; |
| int test_packet = 1; |
int test_packet = 1; |
| int test_setup = 1; |
int test_setup = 1; |
| int output_vectors = 0; |
int output_vectors = 0; |
| |
|
| if (errors >= 10) |
if (errors >= 10) |
| { |
{ |
| fprintf(stderr, "Too many errors (%d errors). Aborting test.\n", errors); |
if (!quiet) |
| exit(1); |
fprintf(stderr, |
| |
"Too many errors (%d errors). Aborting test.\n", errors); |
| |
|
| |
exit(3); |
| } |
} |
| |
|
| if (sec > test_time) |
if (sec > test_time) |
| { |
{ |
| fprintf(stderr, "Time out (%.2f seconds). Aborting test.\n", sec); |
if (!quiet) |
| exit(2); |
fprintf(stderr, |
| |
"Time out (%.2f seconds). Aborting test.\n", sec); |
| |
|
| |
exit(1); |
| } |
} |
| } |
} |
| |
|
| fprintf(fd, "Primitive Name: %s\n", ECRYPT_NAME); |
fprintf(fd, "Primitive Name: %s\n", ECRYPT_NAME); |
| fprintf(fd, "================%.*s\n", (int)strlen(ECRYPT_NAME), |
fprintf(fd, "================%.*s\n", (int)strlen(ECRYPT_NAME), |
| "=========================================="); |
"=========================================="); |
| |
fprintf(fd, "Profile: %s\n", ECRYPT_PROFILE); |
| fprintf(fd, "Key size: %d bits\n", keysize); |
fprintf(fd, "Key size: %d bits\n", keysize); |
| fprintf(fd, "IV size: %d bits\n", ivsize); |
fprintf(fd, "IV size: %d bits\n", ivsize); |
| #ifdef ECRYPT_AE |
#ifdef ECRYPT_AE |
| |
|
| typedef struct |
typedef struct |
| { |
{ |
| int keysize; |
ALIGN(u8, key, MAXKEYSIZEB); |
| int ivsize; |
ALIGN(u8, iv, MAXIVSIZEB); |
| int msglen; |
|
| |
|
| CTX ctx; |
ALIGN(u8, plaintext, LONG_TEST_STREAM_SIZEB); |
| |
ALIGN(u8, ciphertext, LONG_TEST_STREAM_SIZEB); |
| |
ALIGN(u8, checktext, LONG_TEST_STREAM_SIZEB); |
| |
|
| |
ALIGN(u8, xored ,TEST_CHUNK); |
| |
|
| |
#ifdef ECRYPT_AE |
| |
ALIGN(u8, aad, TEST_CHUNK); |
| |
ALIGN(u8, mac, MAXMACSIZEB); |
| |
ALIGN(u8, checkmac, MAXMACSIZEB); |
| |
#endif |
| |
|
| u8 key[MAXKEYSIZEB]; |
CTX ctx; |
| u8 iv[MAXIVSIZEB]; |
|
| |
|
| u8 plaintext[LONG_TEST_STREAM_SIZEB]; |
int keysize; |
| u8 ciphertext[LONG_TEST_STREAM_SIZEB]; |
int ivsize; |
| u8 checktext[LONG_TEST_STREAM_SIZEB]; |
int msglen; |
| |
|
| #ifdef ECRYPT_AE |
#ifdef ECRYPT_AE |
| int macsize; |
int macsize; |
| int aadlen; |
int aadlen; |
| |
|
| u8 aad[TEST_CHUNK]; |
|
| u8 mac[MAXMACSIZEB]; |
|
| u8 checkmac[MAXMACSIZEB]; |
|
| #endif |
#endif |
| |
|
| u8 xored[TEST_CHUNK]; |
|
| |
|
| FILE *fd; |
FILE *fd; |
| |
|
| int vector; |
int vector; |
| |
|
| unsigned int i; |
unsigned int i; |
| |
|
| memset(t->ciphertext, 0, sizeof(t->ciphertext)); |
memset(t->ciphertext.b, 0, sizeof(t->ciphertext.b)); |
| #ifdef ECRYPT_AE |
#ifdef ECRYPT_AE |
| memset(t->mac, 0, sizeof(t->mac)); |
memset(t->mac.b, 0, sizeof(t->mac.b)); |
| #endif |
#endif |
| |
|
| KEYSETUP(&t->ctx, t->key, t->keysize, t->ivsize, t->macsize); |
KEYSETUP(&t->ctx, t->key.b, t->keysize, t->ivsize, t->macsize); |
| ENCRYPT_PACKET(&t->ctx, t->iv, |
ENCRYPT_PACKET(&t->ctx, t->iv.b, |
| t->aad, t->aadlen, t->plaintext, t->ciphertext, t->msglen, t->mac); |
t->aad.b, t->aadlen, t->plaintext.b, t->ciphertext.b, t->msglen, t->mac.b); |
| |
|
| print(t, 0); |
print(t, 0); |
| |
|
| #ifdef ECRYPT_AE |
#ifdef ECRYPT_AE |
| memset(t->checkmac, 0, sizeof(t->checkmac)); |
memset(t->checkmac.b, 0, sizeof(t->checkmac.b)); |
| #endif |
#endif |
| memset(t->checktext, 0, sizeof(t->checktext)); |
memset(t->checktext.b, 0, sizeof(t->checktext.b)); |
| |
|
| KEYSETUP(&t->ctx, t->key, t->keysize, t->ivsize, t->macsize); |
KEYSETUP(&t->ctx, t->key.b, t->keysize, t->ivsize, t->macsize); |
| DECRYPT_PACKET(&t->ctx, t->iv, |
DECRYPT_PACKET(&t->ctx, t->iv.b, t->aad.b, t->aadlen, |
| t->aad, t->aadlen, t->ciphertext, t->checktext, t->msglen, t->checkmac); |
t->ciphertext.b, t->checktext.b, t->msglen, t->checkmac.b); |
| |
|
| if (compare_blocks(t->plaintext, t->checktext, t->msglen * 8) != 0) |
if (compare_blocks(t->plaintext.b, t->checktext.b, t->msglen * 8) != 0) |
| { |
{ |
| ++errors; |
++errors; |
| fprintf(t->fd, |
fprintf(t->fd, |
| print(t, 1); |
print(t, 1); |
| } |
} |
| #ifdef ECRYPT_AE |
#ifdef ECRYPT_AE |
| else if (compare_blocks(t->mac, t->checkmac, t->macsize) != 0) |
else if (compare_blocks(t->mac.b, t->checkmac.b, t->macsize) != 0) |
| { |
{ |
| ++errors; |
++errors; |
| fprintf(t->fd, |
fprintf(t->fd, |
| "*** ERROR: encrypt_packet <-> decrypt_packet:\n" |
"*** ERROR: encrypt_packet <-> decrypt_packet:\n" |
| "*** decryption MAC differs from encryption MAC:\n"); |
"*** decryption MAC differs from encryption MAC:\n"); |
| print_data(t->fd, "MAC", t->checkmac, (t->macsize + 7) / 8); |
print_data(t->fd, "MAC", t->checkmac.b, (t->macsize + 7) / 8); |
| } |
} |
| |
|
| memset(t->checkmac, 0, sizeof(t->checkmac)); |
memset(t->checkmac.b, 0, sizeof(t->checkmac.b)); |
| #endif |
#endif |
| memset(t->checktext, 0, sizeof(t->checktext)); |
memset(t->checktext.b, 0, sizeof(t->checktext.b)); |
| |
|
| IVSETUP(&t->ctx, t->iv); |
IVSETUP(&t->ctx, t->iv.b); |
| |
|
| #ifdef ECRYPT_SUPPORTS_AAD |
#ifdef ECRYPT_SUPPORTS_AAD |
| AUTHENTICATE_BYTES(&t->ctx, t->aad, t->aadlen); |
AUTHENTICATE_BYTES(&t->ctx, t->aad.b, t->aadlen); |
| #endif |
#endif |
| |
|
| ENCRYPT_BYTES(&t->ctx, t->plaintext, t->checktext, t->msglen); |
ENCRYPT_BYTES(&t->ctx, t->plaintext.b, t->checktext.b, t->msglen); |
| FINALIZE(&t->ctx, t->checkmac); |
FINALIZE(&t->ctx, t->checkmac.b); |
| |
|
| if (compare_blocks(t->ciphertext, t->checktext, t->msglen * 8) != 0) |
if (compare_blocks(t->ciphertext.b, t->checktext.b, t->msglen * 8) != 0) |
| { |
{ |
| ++errors; |
++errors; |
| fprintf(t->fd, |
fprintf(t->fd, |
| print(t, 2); |
print(t, 2); |
| } |
} |
| #ifdef ECRYPT_AE |
#ifdef ECRYPT_AE |
| else if (compare_blocks(t->mac, t->checkmac, t->macsize) != 0) |
else if (compare_blocks(t->mac.b, t->checkmac.b, t->macsize) != 0) |
| { |
{ |
| ++errors; |
++errors; |
| fprintf(t->fd, |
fprintf(t->fd, |
| "*** ERROR: encrypt_packet <-> encrypt_bytes:\n" |
"*** ERROR: encrypt_packet <-> encrypt_bytes:\n" |
| "*** encrypt_bytes generates different MAC:\n"); |
"*** encrypt_bytes generates different MAC:\n"); |
| print_data(t->fd, "MAC", t->checkmac, (t->macsize + 7) / 8); |
print_data(t->fd, "MAC", t->checkmac.b, (t->macsize + 7) / 8); |
| } |
} |
| |
|
| memset(t->checkmac, 0, sizeof(t->checkmac)); |
memset(t->checkmac.b, 0, sizeof(t->checkmac.b)); |
| #endif |
#endif |
| memset(t->checktext, 0, sizeof(t->checktext)); |
memset(t->checktext.b, 0, sizeof(t->checktext.b)); |
| |
|
| IVSETUP(&t->ctx, t->iv); |
IVSETUP(&t->ctx, t->iv.b); |
| |
|
| #ifdef ECRYPT_SUPPORTS_AAD |
#ifdef ECRYPT_SUPPORTS_AAD |
| AUTHENTICATE_BYTES(&t->ctx, t->aad, t->aadlen); |
AUTHENTICATE_BYTES(&t->ctx, t->aad.b, t->aadlen); |
| #endif |
#endif |
| |
|
| DECRYPT_BYTES(&t->ctx, t->ciphertext, t->checktext, t->msglen); |
DECRYPT_BYTES(&t->ctx, t->ciphertext.b, t->checktext.b, t->msglen); |
| FINALIZE(&t->ctx, t->checkmac); |
FINALIZE(&t->ctx, t->checkmac.b); |
| |
|
| if (compare_blocks(t->plaintext, t->checktext, t->msglen * 8) != 0) |
if (compare_blocks(t->plaintext.b, t->checktext.b, t->msglen * 8) != 0) |
| { |
{ |
| ++errors; |
++errors; |
| fprintf(t->fd, |
fprintf(t->fd, |
| print(t, 2); |
print(t, 2); |
| } |
} |
| #ifdef ECRYPT_AE |
#ifdef ECRYPT_AE |
| else if (compare_blocks(t->mac, t->checkmac, t->macsize) != 0) |
else if (compare_blocks(t->mac.b, t->checkmac.b, t->macsize) != 0) |
| { |
{ |
| ++errors; |
++errors; |
| fprintf(t->fd, |
fprintf(t->fd, |
| "*** ERROR: encrypt_packet <-> decrypt_bytes:\n" |
"*** ERROR: encrypt_packet <-> decrypt_bytes:\n" |
| "*** decrypt_bytes generates different MAC:\n"); |
"*** decrypt_bytes generates different MAC:\n"); |
| print_data(t->fd, "MAC", t->checkmac, (t->macsize + 7) / 8); |
print_data(t->fd, "MAC", t->checkmac.b, (t->macsize + 7) / 8); |
| } |
} |
| |
|
| memset(t->checkmac, 0, sizeof(t->checkmac)); |
memset(t->checkmac.b, 0, sizeof(t->checkmac.b)); |
| #endif |
#endif |
| memset(t->checktext, 0, sizeof(t->checktext)); |
memset(t->checktext.b, 0, sizeof(t->checktext.b)); |
| |
|
| IVSETUP(&t->ctx, t->iv); |
IVSETUP(&t->ctx, t->iv.b); |
| |
|
| #ifdef ECRYPT_SUPPORTS_AAD |
#ifdef ECRYPT_SUPPORTS_AAD |
| AUTHENTICATE_BYTES(&t->ctx, t->aad, t->aadlen); |
AUTHENTICATE_BYTES(&t->ctx, t->aad.b, t->aadlen); |
| #endif |
#endif |
| |
|
| plaintext = t->plaintext; |
plaintext = t->plaintext.b; |
| checktext = t->checktext; |
checktext = t->checktext.b; |
| msglen = t->msglen; |
msglen = t->msglen; |
| |
|
| for (i = (t->vector + 1) * 1381; msglen >= ECRYPT_BLOCKLENGTH; i *= 1487) |
for (i = (t->vector + 1) * 1381; msglen >= ECRYPT_BLOCKLENGTH; i *= 1487) |
| } |
} |
| |
|
| ENCRYPT_BYTES(&t->ctx, plaintext, checktext, msglen); |
ENCRYPT_BYTES(&t->ctx, plaintext, checktext, msglen); |
| FINALIZE(&t->ctx, t->checkmac); |
FINALIZE(&t->ctx, t->checkmac.b); |
| |
|
| if (compare_blocks(t->ciphertext, t->checktext, t->msglen * 8) != 0) |
if (compare_blocks(t->ciphertext.b, t->checktext.b, t->msglen * 8) != 0) |
| { |
{ |
| ++errors; |
++errors; |
| fprintf(t->fd, |
fprintf(t->fd, |
| print(t, 2); |
print(t, 2); |
| } |
} |
| #ifdef ECRYPT_AE |
#ifdef ECRYPT_AE |
| else if (compare_blocks(t->mac, t->checkmac, t->macsize) != 0) |
else if (compare_blocks(t->mac.b, t->checkmac.b, t->macsize) != 0) |
| { |
{ |
| ++errors; |
++errors; |
| fprintf(t->fd, |
fprintf(t->fd, |
| "*** ERROR: encrypt_packet <-> encrypt_blocks/bytes:\n" |
"*** ERROR: encrypt_packet <-> encrypt_blocks/bytes:\n" |
| "*** encrypt_blocks/bytes generates different MAC:\n"); |
"*** encrypt_blocks/bytes generates different MAC:\n"); |
| print_data(t->fd, "MAC", t->checkmac, (t->macsize + 7) / 8); |
print_data(t->fd, "MAC", t->checkmac.b, (t->macsize + 7) / 8); |
| } |
} |
| |
|
| memset(t->checkmac, 0, sizeof(t->checkmac)); |
memset(t->checkmac.b, 0, sizeof(t->checkmac.b)); |
| #endif |
#endif |
| memset(t->checktext, 0, sizeof(t->checktext)); |
memset(t->checktext.b, 0, sizeof(t->checktext.b)); |
| |
|
| IVSETUP(&t->ctx, t->iv); |
IVSETUP(&t->ctx, t->iv.b); |
| |
|
| #ifdef ECRYPT_SUPPORTS_AAD |
#ifdef ECRYPT_SUPPORTS_AAD |
| AUTHENTICATE_BYTES(&t->ctx, t->aad, t->aadlen); |
AUTHENTICATE_BYTES(&t->ctx, t->aad.b, t->aadlen); |
| #endif |
#endif |
| |
|
| ciphertext = t->ciphertext; |
ciphertext = t->ciphertext.b; |
| checktext = t->checktext; |
checktext = t->checktext.b; |
| msglen = t->msglen; |
msglen = t->msglen; |
| |
|
| for (i = (t->vector + 1) * 1381; msglen >= ECRYPT_BLOCKLENGTH; i *= 1487) |
for (i = (t->vector + 1) * 1381; msglen >= ECRYPT_BLOCKLENGTH; i *= 1487) |
| } |
} |
| |
|
| DECRYPT_BYTES(&t->ctx, ciphertext, checktext, msglen); |
DECRYPT_BYTES(&t->ctx, ciphertext, checktext, msglen); |
| FINALIZE(&t->ctx, t->checkmac); |
FINALIZE(&t->ctx, t->checkmac.b); |
| |
|
| if (compare_blocks(t->plaintext, t->checktext, t->msglen * 8) != 0) |
if (compare_blocks(t->plaintext.b, t->checktext.b, t->msglen * 8) != 0) |
| { |
{ |
| ++errors; |
++errors; |
| fprintf(t->fd, |
fprintf(t->fd, |
| print(t, 2); |
print(t, 2); |
| } |
} |
| #ifdef ECRYPT_AE |
#ifdef ECRYPT_AE |
| else if (compare_blocks(t->mac, t->checkmac, t->macsize) != 0) |
else if (compare_blocks(t->mac.b, t->checkmac.b, t->macsize) != 0) |
| { |
{ |
| ++errors; |
++errors; |
| fprintf(t->fd, |
fprintf(t->fd, |
| "*** ERROR: encrypt_packet <-> decrypt_blocks/bytes:\n" |
"*** ERROR: encrypt_packet <-> decrypt_blocks/bytes:\n" |
| "*** decrypt_blocks/bytes generates different MAC:\n"); |
"*** decrypt_blocks/bytes generates different MAC:\n"); |
| print_data(t->fd, "MAC", t->checkmac, (t->macsize + 7) / 8); |
print_data(t->fd, "MAC", t->checkmac.b, (t->macsize + 7) / 8); |
| } |
} |
| #endif |
#endif |
| |
|
| switch (type) |
switch (type) |
| { |
{ |
| case 0: |
case 0: |
| print_data(t->fd, "key", t->key, (t->keysize + 7) / 8); |
print_data(t->fd, "key", t->key.b, (t->keysize + 7) / 8); |
| print_data(t->fd, "IV", t->iv, (t->ivsize + 7) / 8); |
print_data(t->fd, "IV", t->iv.b, (t->ivsize + 7) / 8); |
| |
|
| print_chunk(t->fd, "stream", t->ciphertext, 0, chunk); |
print_chunk(t->fd, "stream", t->ciphertext.b, 0, chunk); |
| print_chunk(t->fd, "stream", t->ciphertext, t->msglen/2-chunk, chunk); |
print_chunk(t->fd, "stream", t->ciphertext.b, t->msglen/2-chunk, chunk); |
| print_chunk(t->fd, "stream", t->ciphertext, t->msglen/2, chunk); |
print_chunk(t->fd, "stream", t->ciphertext.b, t->msglen/2, chunk); |
| print_chunk(t->fd, "stream", t->ciphertext, t->msglen-chunk, chunk); |
print_chunk(t->fd, "stream", t->ciphertext.b, t->msglen-chunk, chunk); |
| |
|
| xor_digest(t->ciphertext, t->msglen, t->xored, chunk); |
xor_digest(t->ciphertext.b, t->msglen, t->xored.b, chunk); |
| print_data(t->fd, "xor-digest", t->xored, chunk); |
print_data(t->fd, "xor-digest", t->xored.b, chunk); |
| |
|
| #ifdef ECRYPT_AE |
#ifdef ECRYPT_AE |
| print_data(t->fd, "MAC", t->mac, (t->macsize + 7) / 8); |
print_data(t->fd, "MAC", t->mac.b, (t->macsize + 7) / 8); |
| #endif |
#endif |
| break; |
break; |
| case 1: |
case 1: |
| print_chunk(t->fd, "decryption", t->checktext, 0, chunk); |
print_chunk(t->fd, "decryption", t->checktext.b, 0, chunk); |
| print_chunk(t->fd, "decryption", t->checktext, t->msglen/2-chunk, chunk); |
print_chunk(t->fd, "decryption", t->checktext.b, |
| print_chunk(t->fd, "decryption", t->checktext, t->msglen/2, chunk); |
t->msglen / 2-chunk, chunk); |
| print_chunk(t->fd, "decryption", t->checktext, t->msglen-chunk, chunk); |
print_chunk(t->fd, "decryption", t->checktext.b, t->msglen / 2, chunk); |
| |
print_chunk(t->fd, "decryption", t->checktext.b, t->msglen-chunk, chunk); |
| |
|
| xor_digest(t->checktext, t->msglen, t->xored, chunk); |
xor_digest(t->checktext.b, t->msglen, t->xored.b, chunk); |
| print_data(t->fd, "xor-digest", t->xored, chunk); |
print_data(t->fd, "xor-digest", t->xored.b, chunk); |
| |
|
| #ifdef ECRYPT_AE |
#ifdef ECRYPT_AE |
| print_data(t->fd, "MAC", t->checkmac, (t->macsize + 7) / 8); |
print_data(t->fd, "MAC", t->checkmac.b, (t->macsize + 7) / 8); |
| #endif |
#endif |
| break; |
break; |
| case 2: |
case 2: |
| print_chunk(t->fd, "stream", t->checktext, 0, chunk); |
print_chunk(t->fd, "stream", t->checktext.b, 0, chunk); |
| print_chunk(t->fd, "stream", t->checktext, t->msglen/2-chunk, chunk); |
print_chunk(t->fd, "stream", t->checktext.b, t->msglen/2-chunk, chunk); |
| print_chunk(t->fd, "stream", t->checktext, t->msglen/2, chunk); |
print_chunk(t->fd, "stream", t->checktext.b, t->msglen/2, chunk); |
| print_chunk(t->fd, "stream", t->checktext, t->msglen-chunk, chunk); |
print_chunk(t->fd, "stream", t->checktext.b, t->msglen-chunk, chunk); |
| |
|
| xor_digest(t->checktext, t->msglen, t->xored, chunk); |
xor_digest(t->checktext.b, t->msglen, t->xored.b, chunk); |
| print_data(t->fd, "xor-digest", t->xored, chunk); |
print_data(t->fd, "xor-digest", t->xored.b, chunk); |
| |
|
| #ifdef ECRYPT_AE |
#ifdef ECRYPT_AE |
| print_data(t->fd, "MAC", t->checkmac, (t->macsize + 7) / 8); |
print_data(t->fd, "MAC", t->checkmac.b, (t->macsize + 7) / 8); |
| #endif |
#endif |
| break; |
break; |
| } |
} |
| switch (type) |
switch (type) |
| { |
{ |
| case 0: |
case 0: |
| print_data(t->fd, "key", t->key, (t->keysize + 7) / 8); |
print_data(t->fd, "key", t->key.b, (t->keysize + 7) / 8); |
| print_data(t->fd, "IV", t->iv, (t->ivsize + 7) / 8); |
print_data(t->fd, "IV", t->iv.b, (t->ivsize + 7) / 8); |
| |
|
| #ifdef ECRYPT_SUPPORTS_AAD |
#ifdef ECRYPT_SUPPORTS_AAD |
| if (t->aadlen) |
if (t->aadlen) |
| print_data(t->fd, "AAD", t->aad, t->aadlen); |
print_data(t->fd, "AAD", t->aad.b, t->aadlen); |
| #endif |
#endif |
| print_data(t->fd, "plaintext", t->plaintext, t->msglen); |
print_data(t->fd, "plaintext", t->plaintext.b, t->msglen); |
| print_data(t->fd, "ciphertext", t->ciphertext, t->msglen); |
print_data(t->fd, "ciphertext", t->ciphertext.b, t->msglen); |
| #ifdef ECRYPT_AE |
#ifdef ECRYPT_AE |
| print_data(t->fd, "MAC", t->mac, (t->macsize + 7) / 8); |
print_data(t->fd, "MAC", t->mac.b, (t->macsize + 7) / 8); |
| #endif |
#endif |
| break; |
break; |
| case 1: |
case 1: |
| print_data(t->fd, "decryption", t->checktext, t->msglen); |
print_data(t->fd, "decryption", t->checktext.b, t->msglen); |
| #ifdef ECRYPT_AE |
#ifdef ECRYPT_AE |
| print_data(t->fd, "MAC", t->checkmac, (t->macsize + 7) / 8); |
print_data(t->fd, "MAC", t->checkmac.b, (t->macsize + 7) / 8); |
| #endif |
#endif |
| break; |
break; |
| case 2: |
case 2: |
| print_data(t->fd, "ciphertext", t->checktext, t->msglen); |
print_data(t->fd, "ciphertext", t->checktext.b, t->msglen); |
| #ifdef ECRYPT_AE |
#ifdef ECRYPT_AE |
| print_data(t->fd, "MAC", t->checkmac, (t->macsize + 7) / 8); |
print_data(t->fd, "MAC", t->checkmac.b, (t->macsize + 7) / 8); |
| #endif |
#endif |
| break; |
break; |
| } |
} |
| |
|
| print_primitive(fd, keysize, ivsize, macsize); |
print_primitive(fd, keysize, ivsize, macsize); |
| |
|
| memset(t.plaintext, 0, sizeof(t.plaintext)); |
memset(t.plaintext.b, 0, sizeof(t.plaintext.b)); |
| memset(t.ciphertext, 0, sizeof(t.ciphertext)); |
memset(t.ciphertext.b, 0, sizeof(t.ciphertext.b)); |
| |
|
| /* check key stream */ |
/* check key stream */ |
| |
|
| fprintf(t.fd, "(stream is generated by encrypting %d zero bytes)\n\n", |
fprintf(t.fd, "(stream is generated by encrypting %d zero bytes)\n\n", |
| t.msglen); |
t.msglen); |
| |
|
| memset(t.iv, 0, sizeof(t.iv)); |
memset(t.iv.b, 0, sizeof(t.iv.b)); |
| |
|
| for (v = 0; v < t.keysize; v += TEST_STEP) |
for (v = 0; v < t.keysize; v += TEST_STEP) |
| { |
{ |
| memset(t.key, 0, sizeof(t.key)); |
memset(t.key.b, 0, sizeof(t.key.b)); |
| t.key[v >> 3] = 1 << (7 - (v & 7)); |
t.key.b[v >> 3] = 1 << (7 - (v & 7)); |
| |
|
| STREAM_VECTOR(1, v); |
STREAM_VECTOR(1, v); |
| } |
} |
| fprintf(t.fd, "Test vectors -- set 2\n"); |
fprintf(t.fd, "Test vectors -- set 2\n"); |
| fprintf(t.fd, "=====================\n\n"); |
fprintf(t.fd, "=====================\n\n"); |
| |
|
| memset(t.iv, 0, sizeof(t.iv)); |
memset(t.iv.b, 0, sizeof(t.iv.b)); |
| |
|
| for (v = 0; v < 256; v += TEST_STEP) |
for (v = 0; v < 256; v += TEST_STEP) |
| { |
{ |
| memset(t.key, v, sizeof(t.key)); |
memset(t.key.b, v, sizeof(t.key.b)); |
| |
|
| STREAM_VECTOR(2, v); |
STREAM_VECTOR(2, v); |
| } |
} |
| fprintf(fd, "Test vectors -- set 3\n"); |
fprintf(fd, "Test vectors -- set 3\n"); |
| fprintf(fd, "=====================\n\n"); |
fprintf(fd, "=====================\n\n"); |
| |
|
| memset(t.iv, 0, sizeof(t.iv)); |
memset(t.iv.b, 0, sizeof(t.iv.b)); |
| |
|
| for (v = 0; v < 256; v += TEST_STEP) |
for (v = 0; v < 256; v += TEST_STEP) |
| { |
{ |
| for (i = 0; i < sizeof(t.key); i++) |
for (i = 0; i < sizeof(t.key.b); i++) |
| t.key[i] = (i + v) & 0xFF; |
t.key.b[i] = (i + v) & 0xFF; |
| |
|
| STREAM_VECTOR(3, v); |
STREAM_VECTOR(3, v); |
| } |
} |
| |
|
| for (v = 0; v < 4; v++) |
for (v = 0; v < 4; v++) |
| { |
{ |
| for (i = 0; i< sizeof(t.key); i++) |
for (i = 0; i< sizeof(t.key.b); i++) |
| t.key[i] = (i * 0x53 + v * 5) & 0xFF; |
t.key.b[i] = (i * 0x53 + v * 5) & 0xFF; |
| |
|
| STREAM_VECTOR(4, v); |
STREAM_VECTOR(4, v); |
| } |
} |
| fprintf(t.fd, "Test vectors -- set 5\n"); |
fprintf(t.fd, "Test vectors -- set 5\n"); |
| fprintf(t.fd, "=====================\n\n"); |
fprintf(t.fd, "=====================\n\n"); |
| |
|
| memset(t.key, 0, sizeof(t.key)); |
memset(t.key.b, 0, sizeof(t.key.b)); |
| |
|
| for (v = 0; v < t.ivsize; v += TEST_STEP) |
for (v = 0; v < t.ivsize; v += TEST_STEP) |
| { |
{ |
| memset(t.iv, 0, sizeof(t.iv)); |
memset(t.iv.b, 0, sizeof(t.iv.b)); |
| t.iv[v >> 3] = 1 << (7 - (v & 7)); |
t.iv.b[v >> 3] = 1 << (7 - (v & 7)); |
| |
|
| STREAM_VECTOR(5, v); |
STREAM_VECTOR(5, v); |
| } |
} |
| |
|
| for (v = 0; v < 4; v++) |
for (v = 0; v < 4; v++) |
| { |
{ |
| for (i = 0; i < sizeof(t.key); i++) |
for (i = 0; i < sizeof(t.key.b); i++) |
| t.key[i] = (i * 0x53 + v * 5) & 0xFF; |
t.key.b[i] = (i * 0x53 + v * 5) & 0xFF; |
| |
|
| for (i = 0; i < sizeof(t.iv); i++) |
for (i = 0; i < sizeof(t.iv.b); i++) |
| t.iv[i] = (i * 0x67 + v * 9 + 13) & 0xFF; |
t.iv.b[i] = (i * 0x67 + v * 9 + 13) & 0xFF; |
| |
|
| STREAM_VECTOR(6, v); |
STREAM_VECTOR(6, v); |
| } |
} |
| fprintf(t.fd, "Test vectors -- set 7\n"); |
fprintf(t.fd, "Test vectors -- set 7\n"); |
| fprintf(t.fd, "=====================\n\n"); |
fprintf(t.fd, "=====================\n\n"); |
| |
|
| memset(t.key, 0, sizeof(t.key)); |
memset(t.key.b, 0, sizeof(t.key.b)); |
| memset(t.iv, 0, sizeof(t.iv)); |
memset(t.iv.b, 0, sizeof(t.iv.b)); |
| memset(t.plaintext, 0, sizeof(t.plaintext)); |
memset(t.plaintext.b, 0, sizeof(t.plaintext.b)); |
| |
|
| for (i = 0; i < sizeof(t.key); i++) |
for (i = 0; i < sizeof(t.key.b); i++) |
| t.key[i] = (i * 0x11) & 0xFF; |
t.key.b[i] = (i * 0x11) & 0xFF; |
| |
|
| for (v = 0; v <= TEST_CHUNK; v += TEST_STEP) |
for (v = 0; v <= TEST_CHUNK; v += TEST_STEP) |
| { |
{ |
| fprintf(t.fd, "Test vectors -- set 8\n"); |
fprintf(t.fd, "Test vectors -- set 8\n"); |
| fprintf(t.fd, "=====================\n\n"); |
fprintf(t.fd, "=====================\n\n"); |
| |
|
| memset(t.key, 0, sizeof(t.key)); |
memset(t.key.b, 0, sizeof(t.key.b)); |
| memset(t.iv, 0, sizeof(t.iv)); |
memset(t.iv.b, 0, sizeof(t.iv.b)); |
| |
|
| for (v = 0; v < t.msglen * 8; v += TEST_STEP) |
for (v = 0; v < t.msglen * 8; v += TEST_STEP) |
| { |
{ |
| memset(t.plaintext, 0, sizeof(t.plaintext)); |
memset(t.plaintext.b, 0, sizeof(t.plaintext.b)); |
| t.plaintext[v >> 3] = 1 << (7 - (v & 7)); |
t.plaintext.b[v >> 3] = 1 << (7 - (v & 7)); |
| |
|
| MAC_VECTOR(8, v); |
MAC_VECTOR(8, v); |
| } |
} |
| |
|
| for (v = 0; v < 4; v++) |
for (v = 0; v < 4; v++) |
| { |
{ |
| for (i = 0; i < sizeof(t.key); i++) |
for (i = 0; i < sizeof(t.key.b); i++) |
| t.key[i] = (i * 0x53 + v * 5) & 0xFF; |
t.key.b[i] = (i * 0x53 + v * 5) & 0xFF; |
| |
|
| for (i = 0; i < sizeof(t.iv); i++) |
for (i = 0; i < sizeof(t.iv.b); i++) |
| t.iv[i] = (i * 0x67 + v * 9 + 13) & 0xFF; |
t.iv.b[i] = (i * 0x67 + v * 9 + 13) & 0xFF; |
| |
|
| for (i = 0; i < t.msglen; i++) |
for (i = 0; i < t.msglen; i++) |
| t.plaintext[i] = (i * 0x61 + v * 7 + 109) & 0xFF; |
t.plaintext.b[i] = (i * 0x61 + v * 7 + 109) & 0xFF; |
| |
|
| MAC_VECTOR(9, v); |
MAC_VECTOR(9, v); |
| } |
} |
| fprintf(t.fd, "Test vectors -- set 10\n"); |
fprintf(t.fd, "Test vectors -- set 10\n"); |
| fprintf(t.fd, "======================\n\n"); |
fprintf(t.fd, "======================\n\n"); |
| |
|
| memset(t.key, 0, sizeof(t.key)); |
memset(t.key.b, 0, sizeof(t.key.b)); |
| memset(t.iv, 0, sizeof(t.iv)); |
memset(t.iv.b, 0, sizeof(t.iv.b)); |
| memset(t.plaintext, 0, sizeof(t.plaintext)); |
memset(t.plaintext.b, 0, sizeof(t.plaintext.b)); |
| memset(t.aad, 0, sizeof(t.aad)); |
memset(t.aad.b, 0, sizeof(t.aad.b)); |
| |
|
| for (i = 0; i < sizeof(t.key); i++) |
for (i = 0; i < sizeof(t.key.b); i++) |
| t.key[i] = (i * 0x11) & 0xFF; |
t.key.b[i] = (i * 0x11) & 0xFF; |
| |
|
| for (v = 0; v <= TEST_CHUNK; v += TEST_STEP) |
for (v = 0; v <= TEST_CHUNK; v += TEST_STEP) |
| { |
{ |
| fprintf(t.fd, "Test vectors -- set 11\n"); |
fprintf(t.fd, "Test vectors -- set 11\n"); |
| fprintf(t.fd, "======================\n\n"); |
fprintf(t.fd, "======================\n\n"); |
| |
|
| memset(t.key, 0, sizeof(t.key)); |
memset(t.key.b, 0, sizeof(t.key.b)); |
| memset(t.iv, 0, sizeof(t.iv)); |
memset(t.iv.b, 0, sizeof(t.iv.b)); |
| memset(t.plaintext, 0, sizeof(t.plaintext)); |
memset(t.plaintext.b, 0, sizeof(t.plaintext.b)); |
| |
|
| for (v = 0; v < t.aadlen * 8; v += TEST_STEP) |
for (v = 0; v < t.aadlen * 8; v += TEST_STEP) |
| { |
{ |
| memset(t.aad, 0, sizeof(t.aad)); |
memset(t.aad.b, 0, sizeof(t.aad.b)); |
| t.aad[v >> 3] = 1 << (7 - (v & 7)); |
t.aad.b[v >> 3] = 1 << (7 - (v & 7)); |
| |
|
| AAD_VECTOR(11, v); |
AAD_VECTOR(11, v); |
| } |
} |
| |
|
| for (v = 0; v < 4; v++) |
for (v = 0; v < 4; v++) |
| { |
{ |
| for (i = 0; i < sizeof(t.key); i++) |
for (i = 0; i < sizeof(t.key.b); i++) |
| t.key[i] = (i * 0x53 + v * 5) & 0xFF; |
t.key.b[i] = (i * 0x53 + v * 5) & 0xFF; |
| |
|
| for (i = 0; i < sizeof(t.iv); i++) |
for (i = 0; i < sizeof(t.iv.b); i++) |
| t.iv[i] = (i * 0x67 + v * 9 + 13) & 0xFF; |
t.iv.b[i] = (i * 0x67 + v * 9 + 13) & 0xFF; |
| |
|
| for (i = 0; i < t.msglen; i++) |
for (i = 0; i < t.msglen; i++) |
| t.plaintext[i] = (i * 0x61 + v * 7 + 109) & 0xFF; |
t.plaintext.b[i] = (i * 0x61 + v * 7 + 109) & 0xFF; |
| |
|
| for (i = 0; i < t.aadlen; i++) |
for (i = 0; i < t.aadlen; i++) |
| t.aad[i] = (i * 0x25 + v * 13 + 11) & 0xFF; |
t.aad.b[i] = (i * 0x25 + v * 13 + 11) & 0xFF; |
| |
|
| AAD_VECTOR(12, v); |
AAD_VECTOR(12, v); |
| } |
} |
| |
|
| void test_if_conform_to_api(FILE *fd, int keysize, int ivsize, int macsize) |
void test_if_conform_to_api(FILE *fd, int keysize, int ivsize, int macsize) |
| { |
{ |
| CTX ctx[2]; |
ALIGN(u8, key[2], MAXKEYSIZEB); |
| |
ALIGN(u8, iv[2], MAXIVSIZEB); |
| |
|
| u8 key[2][MAXKEYSIZEB]; |
ALIGN(u8, plaintext, TEST_CHUNK + ECRYPT_BLOCKLENGTH); |
| u8 iv[2][MAXIVSIZEB]; |
ALIGN(u8, ciphertext[3], TEST_CHUNK + ECRYPT_BLOCKLENGTH); |
| |
|
| u8 plaintext[TEST_CHUNK + ECRYPT_BLOCKLENGTH]; |
|
| u8 ciphertext[3][TEST_CHUNK + ECRYPT_BLOCKLENGTH]; |
|
| #ifdef ECRYPT_AE |
#ifdef ECRYPT_AE |
| u8 mac[3][MAXMACSIZEB]; |
ALIGN(u8, mac[3], MAXMACSIZEB); |
| #endif |
#endif |
| |
|
| |
CTX ctx[2]; |
| |
|
| int msglen = TEST_CHUNK; |
int msglen = TEST_CHUNK; |
| |
|
| int i; |
int i; |
| |
|
| for(i = 0; i < MAXKEYSIZEB; i++) |
for(i = 0; i < MAXKEYSIZEB; i++) |
| { |
{ |
| key[0][i] = 3 * i + 5; |
key[0].b[i] = 3 * i + 5; |
| key[1][i] = 240 - 5 * i; |
key[1].b[i] = 240 - 5 * i; |
| } |
} |
| |
|
| for(i = 0; i < MAXIVSIZEB; i++) |
for(i = 0; i < MAXIVSIZEB; i++) |
| { |
{ |
| iv[0][i] = 9 * i + 25; |
iv[0].b[i] = 9 * i + 25; |
| iv[1][i] = 11 * i + 17; |
iv[1].b[i] = 11 * i + 17; |
| } |
} |
| |
|
| memset(plaintext, 0, sizeof(plaintext)); |
memset(&plaintext, 0, sizeof(plaintext)); |
| memset(ciphertext, 0, sizeof(ciphertext)); |
memset(ciphertext, 0, sizeof(ciphertext)); |
| |
|
| KEYSETUP(&ctx[0], key[0], keysize, ivsize, macsize); |
KEYSETUP(&ctx[0], key[0].b, keysize, ivsize, macsize); |
| |
|
| IVSETUP(&ctx[0], iv[0]); |
IVSETUP(&ctx[0], iv[0].b); |
| ENCRYPT_BYTES(&ctx[0], plaintext, ciphertext[0], msglen); |
ENCRYPT_BYTES(&ctx[0], plaintext.b, ciphertext[0].b, msglen); |
| FINALIZE(&ctx[0], mac[0]); |
FINALIZE(&ctx[0], mac[0].b); |
| |
|
| IVSETUP(&ctx[0], iv[0]); |
IVSETUP(&ctx[0], iv[0].b); |
| ENCRYPT_BYTES(&ctx[0], plaintext, ciphertext[1], msglen); |
ENCRYPT_BYTES(&ctx[0], plaintext.b, ciphertext[1].b, msglen); |
| FINALIZE(&ctx[0], mac[1]); |
FINALIZE(&ctx[0], mac[1].b); |
| |
|
| if (compare_blocks(ciphertext[0], ciphertext[1], msglen * 8) != 0) |
if (compare_blocks(ciphertext[0].b, ciphertext[1].b, msglen * 8) != 0) |
| { |
{ |
| ++errors; |
++errors; |
| fprintf(fd, |
fprintf(fd, |
| "*** ERROR: Code does not conform to ECRYPT API:\n" |
"*** ERROR: Code does not conform to ECRYPT API:\n" |
| "*** Two calls to ivsetup produced different results:\n"); |
"*** Two calls to ivsetup produced different results:\n"); |
| |
|
| print_data(fd, "K", key[0], (keysize + 7) / 8); |
print_data(fd, "K", key[0].b, (keysize + 7) / 8); |
| print_data(fd, "IV", iv[0], (ivsize + 7) / 8); |
print_data(fd, "IV", iv[0].b, (ivsize + 7) / 8); |
| |
|
| print_data(fd, "P", plaintext, msglen); |
print_data(fd, "P", plaintext.b, msglen); |
| print_data(fd, "C after 1st IV setup", ciphertext[0], msglen); |
print_data(fd, "C after 1st IV setup", ciphertext[0].b, msglen); |
| print_data(fd, "C after 2nd IV setup", ciphertext[1], msglen); |
print_data(fd, "C after 2nd IV setup", ciphertext[1].b, msglen); |
| fprintf(fd, "\n"); |
fprintf(fd, "\n"); |
| fflush(fd); |
fflush(fd); |
| } |
} |
| #ifdef ECRYPT_AE |
#ifdef ECRYPT_AE |
| else if (compare_blocks(mac[0], mac[1], macsize) != 0) |
else if (compare_blocks(mac[0].b, mac[1].b, macsize) != 0) |
| { |
{ |
| ++errors; |
++errors; |
| fprintf(fd, |
fprintf(fd, |
| "*** ERROR: Code does not conform to ECRYPT API:\n" |
"*** ERROR: Code does not conform to ECRYPT API:\n" |
| "*** Two calls to ivsetup produced different results:\n"); |
"*** Two calls to ivsetup produced different results:\n"); |
| |
|
| print_data(fd, "K", key[0], (keysize + 7) / 8); |
print_data(fd, "K", key[0].b, (keysize + 7) / 8); |
| print_data(fd, "IV", iv[0], (ivsize + 7) / 8); |
print_data(fd, "IV", iv[0].b, (ivsize + 7) / 8); |
| |
|
| print_data(fd, "P", plaintext, msglen); |
print_data(fd, "P", plaintext.b, msglen); |
| print_data(fd, "MAC after 1st IV setup", mac[0], (macsize + 7) / 8); |
print_data(fd, "MAC after 1st IV setup", mac[0].b, (macsize + 7) / 8); |
| print_data(fd, "MAC after 2nd IV setup", mac[1], (macsize + 7) / 8); |
print_data(fd, "MAC after 2nd IV setup", mac[1].b, (macsize + 7) / 8); |
| fprintf(fd, "\n"); |
fprintf(fd, "\n"); |
| fflush(fd); |
fflush(fd); |
| } |
} |
| |
|
| memset(ciphertext, 0, sizeof(ciphertext)); |
memset(ciphertext, 0, sizeof(ciphertext)); |
| |
|
| KEYSETUP(&ctx[0], key[0], keysize, ivsize, macsize); |
KEYSETUP(&ctx[0], key[0].b, keysize, ivsize, macsize); |
| IVSETUP(&ctx[0], iv[0]); |
IVSETUP(&ctx[0], iv[0].b); |
| ENCRYPT_BYTES(&ctx[0], plaintext, ciphertext[0], msglen); |
ENCRYPT_BYTES(&ctx[0], plaintext.b, ciphertext[0].b, msglen); |
| FINALIZE(&ctx[0], mac[0]); |
FINALIZE(&ctx[0], mac[0].b); |
| |
|
| KEYSETUP(&ctx[1], key[1], keysize, ivsize, macsize); |
KEYSETUP(&ctx[1], key[1].b, keysize, ivsize, macsize); |
| IVSETUP(&ctx[1], iv[1]); |
IVSETUP(&ctx[1], iv[1].b); |
| ENCRYPT_BYTES(&ctx[1], plaintext, ciphertext[1], msglen); |
ENCRYPT_BYTES(&ctx[1], plaintext.b, ciphertext[1].b, msglen); |
| FINALIZE(&ctx[1], mac[1]); |
FINALIZE(&ctx[1], mac[1].b); |
| |
|
| IVSETUP(&ctx[0], iv[0]); |
IVSETUP(&ctx[0], iv[0].b); |
| |
|
| IVSETUP(&ctx[1], iv[1]); |
IVSETUP(&ctx[1], iv[1].b); |
| |
|
| ENCRYPT_BYTES(&ctx[0], plaintext, ciphertext[2], msglen); |
ENCRYPT_BYTES(&ctx[0], plaintext.b, ciphertext[2].b, msglen); |
| FINALIZE(&ctx[0], mac[2]); |
FINALIZE(&ctx[0], mac[2].b); |
| |
|
| if (compare_blocks(ciphertext[0], ciphertext[2], msglen * 8) != 0) |
if (compare_blocks(ciphertext[0].b, ciphertext[2].b, msglen * 8) != 0) |
| { |
{ |
| ++errors; |
++errors; |
| fprintf(fd, |
fprintf(fd, |
| "*** code produces inconsistent results when calls with different\n" |
"*** code produces inconsistent results when calls with different\n" |
| "*** contexts are interleaved:\n"); |
"*** contexts are interleaved:\n"); |
| |
|
| if (compare_blocks(ciphertext[1], ciphertext[2], msglen * 8) == 0) |
if (compare_blocks(ciphertext[1].b, ciphertext[2].b, msglen * 8) == 0) |
| fprintf(fd, |
fprintf(fd, |
| "*** (this is probably due to the use of static state variables)\n"); |
"*** (this is probably due to the use of static state variables)\n"); |
| |
|
| print_data(fd, "K1", key[0], (keysize + 7) / 8); |
print_data(fd, "K1", key[0].b, (keysize + 7) / 8); |
| print_data(fd, "K2", key[1], (keysize + 7) / 8); |
print_data(fd, "K2", key[1].b, (keysize + 7) / 8); |
| print_data(fd, "IV1", iv[0], (ivsize + 7) / 8); |
print_data(fd, "IV1", iv[0].b, (ivsize + 7) / 8); |
| print_data(fd, "IV2", iv[0], (ivsize + 7) / 8); |
print_data(fd, "IV2", iv[0].b, (ivsize + 7) / 8); |
| |
|
| print_data(fd, "P", plaintext, msglen); |
print_data(fd, "P", plaintext.b, msglen); |
| print_data(fd, "C by K1", ciphertext[0], msglen); |
print_data(fd, "C by K1", ciphertext[0].b, msglen); |
| print_data(fd, "C by K2", ciphertext[1], msglen); |
print_data(fd, "C by K2", ciphertext[1].b, msglen); |
| print_data(fd, "C by K1 after IV2 setup", ciphertext[2], msglen); |
print_data(fd, "C by K1 after IV2 setup", ciphertext[2].b, msglen); |
| fprintf(fd, "\n"); |
fprintf(fd, "\n"); |
| fflush(fd); |
fflush(fd); |
| } |
} |
| #ifdef ECRYPT_AE |
#ifdef ECRYPT_AE |
| else if (compare_blocks(mac[0], mac[2], macsize) != 0) |
else if (compare_blocks(mac[0].b, mac[2].b, macsize) != 0) |
| { |
{ |
| ++errors; |
++errors; |
| fprintf(fd, |
fprintf(fd, |
| "*** code produces inconsistent results when calls with different\n" |
"*** code produces inconsistent results when calls with different\n" |
| "*** contexts are interleaved:\n"); |
"*** contexts are interleaved:\n"); |
| |
|
| if (compare_blocks(mac[1], mac[2], macsize) == 0) |
if (compare_blocks(mac[1].b, mac[2].b, macsize) == 0) |
| fprintf(fd, |
fprintf(fd, |
| "*** (this is probably due to the use of static state variables)\n"); |
"*** (this is probably due to the use of static state variables)\n"); |
| |
|
| print_data(fd, "K1", key[0], (keysize + 7) / 8); |
print_data(fd, "K1", key[0].b, (keysize + 7) / 8); |
| print_data(fd, "K2", key[1], (keysize + 7) / 8); |
print_data(fd, "K2", key[1].b, (keysize + 7) / 8); |
| print_data(fd, "IV1", iv[0], (ivsize + 7) / 8); |
print_data(fd, "IV1", iv[0].b, (ivsize + 7) / 8); |
| print_data(fd, "IV2", iv[0], (ivsize + 7) / 8); |
print_data(fd, "IV2", iv[0].b, (ivsize + 7) / 8); |
| |
|
| print_data(fd, "P", plaintext, msglen); |
print_data(fd, "P", plaintext.b, msglen); |
| print_data(fd, "MAC by K1", mac[0], (macsize + 7) / 8); |
print_data(fd, "MAC by K1", mac[0].b, (macsize + 7) / 8); |
| print_data(fd, "MAC by K2", mac[1], (macsize + 7) / 8); |
print_data(fd, "MAC by K2", mac[1].b, (macsize + 7) / 8); |
| print_data(fd, "MAC by K1 after IV2 setup", mac[2], (macsize + 7) / 8); |
print_data(fd, "MAC by K1 after IV2 setup", mac[2].b, (macsize + 7) / 8); |
| fprintf(fd, "\n"); |
fprintf(fd, "\n"); |
| fflush(fd); |
fflush(fd); |
| } |
} |
| |
|
| memset(ciphertext, 0, sizeof(ciphertext)); |
memset(ciphertext, 0, sizeof(ciphertext)); |
| |
|
| KEYSETUP(&ctx[0], key[0], keysize, ivsize, macsize); |
KEYSETUP(&ctx[0], key[0].b, keysize, ivsize, macsize); |
| IVSETUP(&ctx[0], iv[0]); |
IVSETUP(&ctx[0], iv[0].b); |
| ENCRYPT_BYTES(&ctx[0], plaintext + B, ciphertext[0] + B, msglen); |
ENCRYPT_BYTES(&ctx[0], plaintext.b + B, ciphertext[0].b + B, msglen); |
| FINALIZE(&ctx[0], mac[0]); |
FINALIZE(&ctx[0], mac[0].b); |
| |
|
| KEYSETUP(&ctx[1], key[1], keysize, ivsize, macsize); |
KEYSETUP(&ctx[1], key[1].b, keysize, ivsize, macsize); |
| IVSETUP(&ctx[1], iv[1]); |
IVSETUP(&ctx[1], iv[1].b); |
| ENCRYPT_BLOCKS(&ctx[1], plaintext, ciphertext[1], 1); |
ENCRYPT_BLOCKS(&ctx[1], plaintext.b, ciphertext[1].b, 1); |
| ENCRYPT_BYTES(&ctx[1], plaintext + B, ciphertext[1] + B, msglen); |
ENCRYPT_BYTES(&ctx[1], plaintext.b + B, ciphertext[1].b + B, msglen); |
| FINALIZE(&ctx[1], mac[1]); |
FINALIZE(&ctx[1], mac[1].b); |
| |
|
| IVSETUP(&ctx[0], iv[0]); |
IVSETUP(&ctx[0], iv[0].b); |
| |
|
| IVSETUP(&ctx[1], iv[1]); |
IVSETUP(&ctx[1], iv[1].b); |
| ENCRYPT_BLOCKS(&ctx[1], plaintext, ciphertext[2], 1); |
ENCRYPT_BLOCKS(&ctx[1], plaintext.b, ciphertext[2].b, 1); |
| |
|
| ENCRYPT_BYTES(&ctx[0], plaintext + B, ciphertext[2] + B, msglen); |
ENCRYPT_BYTES(&ctx[0], plaintext.b + B, ciphertext[2].b + B, msglen); |
| FINALIZE(&ctx[0], mac[2]); |
FINALIZE(&ctx[0], mac[2].b); |
| |
|
| if (compare_blocks(ciphertext[0] + B, ciphertext[2] + B, msglen * 8) != 0) |
if (compare_blocks(ciphertext[0].b + B, ciphertext[2].b + B, |
| |
msglen * 8) != 0) |
| { |
{ |
| ++errors; |
++errors; |
| fprintf(fd, |
fprintf(fd, |
| "*** code produces inconsistent results when calls with different\n" |
"*** code produces inconsistent results when calls with different\n" |
| "*** contexts are interleaved:\n"); |
"*** contexts are interleaved:\n"); |
| |
|
| if (compare_blocks(ciphertext[1], ciphertext[2], (msglen + B) * 8) == 0) |
if (compare_blocks(ciphertext[1].b, ciphertext[2].b, |
| |
(msglen + B) * 8) == 0) |
| fprintf(fd, |
fprintf(fd, |
| "*** (this is probably due to the use of static state variables)\n"); |
"*** (this is probably due to the use of static state variables)\n"); |
| |
|
| print_data(fd, "K1", key[0], (keysize + 7) / 8); |
print_data(fd, "K1", key[0].b, (keysize + 7) / 8); |
| print_data(fd, "K2", key[1], (keysize + 7) / 8); |
print_data(fd, "K2", key[1].b, (keysize + 7) / 8); |
| print_data(fd, "IV1", iv[0], (ivsize + 7) / 8); |
print_data(fd, "IV1", iv[0].b, (ivsize + 7) / 8); |
| print_data(fd, "IV2", iv[1], (ivsize + 7) / 8); |
print_data(fd, "IV2", iv[1].b, (ivsize + 7) / 8); |
| |
|
| print_data(fd, "(last part of) P", plaintext + B, msglen); |
print_data(fd, "(last part of) P", plaintext.b + B, msglen); |
| print_data(fd, "C by K1", ciphertext[0] + B, msglen); |
print_data(fd, "C by K1", ciphertext[0].b + B, msglen); |
| print_data(fd, "last part of C by K2", ciphertext[1] + B, msglen); |
print_data(fd, "last part of C by K2", ciphertext[1].b + B, msglen); |
| print_data(fd, "C by K1 after calls K2", ciphertext[2] + B, msglen); |
print_data(fd, "C by K1 after calls K2", ciphertext[2].b + B, msglen); |
| fprintf(fd, "\n"); |
fprintf(fd, "\n"); |
| fflush(fd); |
fflush(fd); |
| } |
} |
| #ifdef ECRYPT_AE |
#ifdef ECRYPT_AE |
| else if (compare_blocks(mac[0], mac[2], macsize) != 0) |
else if (compare_blocks(mac[0].b, mac[2].b, macsize) != 0) |
| { |
{ |
| ++errors; |
++errors; |
| fprintf(fd, |
fprintf(fd, |
| "*** code produces inconsistent results when calls with different\n" |
"*** code produces inconsistent results when calls with different\n" |
| "*** contexts are interleaved:\n"); |
"*** contexts are interleaved:\n"); |
| |
|
| if (compare_blocks(mac[1], mac[2], macsize) == 0) |
if (compare_blocks(mac[1].b, mac[2].b, macsize) == 0) |
| fprintf(fd, |
fprintf(fd, |
| "*** (this is probably due to the use of static state variables)\n"); |
"*** (this is probably due to the use of static state variables)\n"); |
| |
|
| print_data(fd, "K1", key[0], (keysize + 7) / 8); |
print_data(fd, "K1", key[0].b, (keysize + 7) / 8); |
| print_data(fd, "K2", key[1], (keysize + 7) / 8); |
print_data(fd, "K2", key[1].b, (keysize + 7) / 8); |
| print_data(fd, "IV1", iv[0], (ivsize + 7) / 8); |
print_data(fd, "IV1", iv[0].b, (ivsize + 7) / 8); |
| print_data(fd, "IV2", iv[1], (ivsize + 7) / 8); |
print_data(fd, "IV2", iv[1].b, (ivsize + 7) / 8); |
| |
|
| print_data(fd, "(last part of) P", plaintext, msglen); |
print_data(fd, "(last part of) P", plaintext.b, msglen); |
| print_data(fd, "MAC by K1", mac[0], (macsize + 7) / 8); |
print_data(fd, "MAC by K1", mac[0].b, (macsize + 7) / 8); |
| print_data(fd, "MAC by K2", mac[1], (macsize + 7) / 8); |
print_data(fd, "MAC by K2", mac[1].b, (macsize + 7) / 8); |
| print_data(fd, "MAC by K1 after K2 calls", mac[2], (macsize + 7) / 8); |
print_data(fd, "MAC by K1 after K2 calls", mac[2].b, (macsize + 7) / 8); |
| fprintf(fd, "\n"); |
fprintf(fd, "\n"); |
| fflush(fd); |
fflush(fd); |
| } |
} |
| |
|
| #ifdef ECRYPT_SUPPORTS_AAD |
#ifdef ECRYPT_SUPPORTS_AAD |
| |
|
| KEYSETUP(&ctx[0], key[0], keysize, ivsize, macsize); |
KEYSETUP(&ctx[0], key[0].b, keysize, ivsize, macsize); |
| IVSETUP(&ctx[0], iv[0]); |
IVSETUP(&ctx[0], iv[0].b); |
| AUTHENTICATE_BYTES(&ctx[0], plaintext, msglen); |
AUTHENTICATE_BYTES(&ctx[0], plaintext.b, msglen); |
| FINALIZE(&ctx[0], mac[0]); |
FINALIZE(&ctx[0], mac[0].b); |
| |
|
| KEYSETUP(&ctx[1], key[1], keysize, ivsize, macsize); |
KEYSETUP(&ctx[1], key[1].b, keysize, ivsize, macsize); |
| IVSETUP(&ctx[1], iv[1]); |
IVSETUP(&ctx[1], iv[1].b); |
| AUTHENTICATE_BYTES(&ctx[1], plaintext, msglen); |
AUTHENTICATE_BYTES(&ctx[1], plaintext.b, msglen); |
| FINALIZE(&ctx[1], mac[1]); |
FINALIZE(&ctx[1], mac[1].b); |
| |
|
| IVSETUP(&ctx[0], iv[0]); |
IVSETUP(&ctx[0], iv[0].b); |
| AUTHENTICATE_BYTES(&ctx[0], plaintext, msglen); |
AUTHENTICATE_BYTES(&ctx[0], plaintext.b, msglen); |
| |
|
| IVSETUP(&ctx[1], iv[1]); |
IVSETUP(&ctx[1], iv[1].b); |
| AUTHENTICATE_BYTES(&ctx[1], plaintext, msglen); |
AUTHENTICATE_BYTES(&ctx[1], plaintext.b, msglen); |
| FINALIZE(&ctx[1], mac[2]); |
FINALIZE(&ctx[1], mac[2].b); |
| |
|
| FINALIZE(&ctx[0], mac[2]); |
FINALIZE(&ctx[0], mac[2].b); |
| |
|
| if (compare_blocks(mac[0], mac[2], macsize) != 0) |
if (compare_blocks(mac[0].b, mac[2].b, macsize) != 0) |
| { |
{ |
| ++errors; |
++errors; |
| fprintf(fd, |
fprintf(fd, |
| "*** code produces inconsistent results when calls with different\n" |
"*** code produces inconsistent results when calls with different\n" |
| "*** contexts are interleaved:\n"); |
"*** contexts are interleaved:\n"); |
| |
|
| if (compare_blocks(mac[1], mac[2], macsize) == 0) |
if (compare_blocks(mac[1].b, mac[2].b, macsize) == 0) |
| fprintf(fd, |
fprintf(fd, |
| "*** (this is probably due to the use of static state variables)\n"); |
"*** (this is probably due to the use of static state variables)\n"); |
| |
|
| print_data(fd, "K1", key[0], (keysize + 7) / 8); |
print_data(fd, "K1", key[0].b, (keysize + 7) / 8); |
| print_data(fd, "K2", key[1], (keysize + 7) / 8); |
print_data(fd, "K2", key[1].b, (keysize + 7) / 8); |
| print_data(fd, "IV1", iv[0], (ivsize + 7) / 8); |
print_data(fd, "IV1", iv[0].b, (ivsize + 7) / 8); |
| print_data(fd, "IV2", iv[1], (ivsize + 7) / 8); |
print_data(fd, "IV2", iv[1].b, (ivsize + 7) / 8); |
| |
|
| print_data(fd, "AAD", plaintext, msglen); |
print_data(fd, "AAD", plaintext.b, msglen); |
| print_data(fd, "MAC by K1", mac[0], (macsize + 7) / 8); |
print_data(fd, "MAC by K1", mac[0].b, (macsize + 7) / 8); |
| print_data(fd, "MAC by K2", mac[1], (macsize + 7) / 8); |
print_data(fd, "MAC by K2", mac[1].b, (macsize + 7) / 8); |
| print_data(fd, "MAC by K1 after K2 calls", mac[2], (macsize + 7) / 8); |
print_data(fd, "MAC by K1 after K2 calls", mac[2].b, (macsize + 7) / 8); |
| fprintf(fd, "\n"); |
fprintf(fd, "\n"); |
| fflush(fd); |
fflush(fd); |
| } |
} |
| |
|
| void test_speed(FILE *fd, int keysize, int ivsize, int macsize) |
void test_speed(FILE *fd, int keysize, int ivsize, int macsize) |
| { |
{ |
| CTX ctx[KEYS_TO_TEST]; |
ALIGN(u8, key[KEYS_TO_TEST], MAXKEYSIZEB); |
| |
ALIGN(u8, iv[KEYS_TO_TEST], MAXIVSIZEB); |
| u8 key[KEYS_TO_TEST][MAXKEYSIZEB]; |
ALIGN(u8, text[2], TEST_BLOCKS * ECRYPT_BLOCKLENGTH); |
| u8 iv[KEYS_TO_TEST][MAXIVSIZEB]; |
|
| u8 text[2][TEST_BLOCKS * ECRYPT_BLOCKLENGTH]; |
|
| #ifdef ECRYPT_AE |
#ifdef ECRYPT_AE |
| u8 mac[MAXMACSIZEB]; |
ALIGN(u8, mac, MAXMACSIZEB); |
| #endif |
#endif |
| |
|
| |
CTX ctx[KEYS_TO_TEST]; |
| |
|
| int tests, tests_per_key, keys_to_test; |
int tests, tests_per_key, keys_to_test; |
| clock_t start, finish; |
clock_t start, finish; |
| int clocks; |
int clocks; |
| for(i = 0; i < KEYS_TO_TEST; i++) |
for(i = 0; i < KEYS_TO_TEST; i++) |
| { |
{ |
| for(j = 0; j < MAXKEYSIZEB; j++) |
for(j = 0; j < MAXKEYSIZEB; j++) |
| key[i][j] = U8V(rand()); |
key[i].b[j] = U8V(rand()); |
| |
|
| for(j = 0; j < MAXIVSIZEB; j++) |
for(j = 0; j < MAXIVSIZEB; j++) |
| iv[i][j] = U8V(rand()); |
iv[i].b[j] = U8V(rand()); |
| |
|
| KEYSETUP(&ctx[i], key[i], keysize, ivsize, macsize); |
KEYSETUP(&ctx[i], key[i].b, keysize, ivsize, macsize); |
| IVSETUP(&ctx[i], iv[i]); |
IVSETUP(&ctx[i], iv[i].b); |
| } |
} |
| |
|
| for(i = 0; i < TEST_BLOCKS * ECRYPT_BLOCKLENGTH; i++) |
for(i = 0; i < TEST_BLOCKS * ECRYPT_BLOCKLENGTH; i++) |
| text[0][i] = U8V(rand()); |
text[0].b[i] = U8V(rand()); |
| |
|
| fprintf(fd, "Testing stream encryption speed:\n\n"); |
fprintf(fd, "Testing stream encryption speed:\n\n"); |
| fflush(fd); |
fflush(fd); |
| TEST_SPEED(FOR_I_FOR_J, do |
TEST_SPEED(FOR_I_FOR_J, do |
| { |
{ |
| ENCRYPT_BLOCKS(&ctx[i % KEYS_TO_TEST], |
ENCRYPT_BLOCKS(&ctx[i % KEYS_TO_TEST], |
| text[i % 2], text[(i + 1) % 2], TEST_BLOCKS); |
text[i % 2].b, text[(i + 1) % 2].b, TEST_BLOCKS); |
| |
|
| } while (0)); |
} while (0)); |
| |
|
| fprintf(fd, "\n"); |
fprintf(fd, "\n"); |
| |
|
| for(i = 0; i < KEYS_TO_TEST; i++) |
for(i = 0; i < KEYS_TO_TEST; i++) |
| FINALIZE(&ctx[i], mac); |
FINALIZE(&ctx[i], mac.b); |
| |
|
| if (test_packet) |
if (test_packet) |
| { |
{ |
| { |
{ |
| TEST_SPEED(FOR_I_FOR_J, do |
TEST_SPEED(FOR_I_FOR_J, do |
| { |
{ |
| ENCRYPT_PACKET(&ctx[i % KEYS_TO_TEST], iv[j % KEYS_TO_TEST], |
ENCRYPT_PACKET(&ctx[i % KEYS_TO_TEST], iv[j % KEYS_TO_TEST].b, |
| NULL, 0, text[i % 2], text[(i + 1) % 2], sizes[k], mac); |
NULL, 0, text[i % 2].b, text[(i + 1) % 2].b, sizes[k], mac.b); |
| |
|
| } while (0)); |
} while (0)); |
| |
|
| |
|
| TEST_SPEED(FOR_J_FOR_I, do |
TEST_SPEED(FOR_J_FOR_I, do |
| { |
{ |
| KEYSETUP(&ctx[0], key[i % KEYS_TO_TEST], keysize, ivsize, macsize); |
KEYSETUP(&ctx[0], key[i % KEYS_TO_TEST].b, keysize, ivsize, macsize); |
| |
|
| } while (0)); |
} while (0)); |
| |
|
| |
|
| TEST_SPEED(FOR_I_FOR_J, do |
TEST_SPEED(FOR_I_FOR_J, do |
| { |
{ |
| IVSETUP(&ctx[i % KEYS_TO_TEST], iv[j % KEYS_TO_TEST]); |
IVSETUP(&ctx[i % KEYS_TO_TEST], iv[j % KEYS_TO_TEST].b); |
| FINALIZE(&ctx[i % KEYS_TO_TEST], mac); |
FINALIZE(&ctx[i % KEYS_TO_TEST], mac.b); |
| |
|
| } while (0)); |
} while (0)); |
| |
|
| |
|
| int main(int argc, char *argv[]) |
int main(int argc, char *argv[]) |
| { |
{ |
| int keysize = 0; |
int keysize = ECRYPT_KEYSIZE(0); |
| int ivsize = 0; |
int ivsize = ECRYPT_IVSIZE(0); |
| int macsize = 0; |
int macsize = ECRYPT_MACSIZE(0); |
| |
|
| int k, i, m; |
int k, i, m; |
| |
|
| case 's': |
case 's': |
| single_key = 1; |
single_key = 1; |
| break; |
break; |
| |
case 'q': |
| |
quiet = 1; |
| |
break; |
| } |
} |
| |
|
| argc--; |
argc--; |
| " -t SEC limit the duration of the tests (default: 3 seconds)\n" |
" -t SEC limit the duration of the tests (default: 3 seconds)\n" |
| " -p do not test packet encryption speed\n" |
" -p do not test packet encryption speed\n" |
| " -k do not test key and IV setup speed\n" |
" -k do not test key and IV setup speed\n" |
| " -s perform tests for a single key and IV length\n"); |
" -s perform tests for a single key and IV length\n" |
| |
" -q be quiet\n"); |
| |
|
| exit(1); |
exit(2); |
| } |
} |
| |
|
| print_header(stdout); |
print_header(stdout); |
| } |
} |
| } |
} |
| |
|
| |
if (!quiet) |
| |
{ |
| fprintf(stderr, "Elapsed time: %.2f seconds.\n", |
fprintf(stderr, "Elapsed time: %.2f seconds.\n", |
| (double)clock() / (double)CLOCKS_PER_SEC); |
(double)clock() / (double)CLOCKS_PER_SEC); |
| fprintf(stderr, "There were %d errors.\n", errors); |
fprintf(stderr, "There were %d errors.\n", errors); |
| |
} |
| |
|
| if (errors) |
if (errors) |
| return 1; |
return 3; |
| else |
else |
| return 0; |
return 0; |
| } |
} |