avr-crypto-lib/test_src/main-picipher-test.c

319 lines
11 KiB
C
Raw Permalink Normal View History

2015-10-02 12:34:20 +00:00
/* main-picipher-test.c */
/*
This file is part of the AVR-Crypto-Lib.
Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
This program is free software: 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 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but 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, see <http://www.gnu.org/licenses/>.
*/
#include "main-test-common.h"
#include <pi16cipher.h>
#include <pi32cipher.h>
#include <pi64cipher.h>
#include <arcfour.h>
#include "performance_test.h"
char *algo_name = "pi16cipher";
/*****************************************************************************
* additional validation-functions *
*****************************************************************************/
#define DUMP_LEN(x, s) do { \
printf("%s", "\n\n" #x ":"); \
cli_hexdump_block((x), (s), 4, 16); \
uart0_flush(); \
} while (0)
#define DUMP(x) DUMP_LEN((x), (sizeof(x)))
arcfour_ctx_t prng;
static
void fill_random(void *buf, size_t length) {
while (length--) {
*(uint8_t *)buf = arcfour_gen(&prng);
buf = (uint8_t *)buf + 1;
}
}
void testrun_performance_pi16cipher(void){
pi16_ctx_t ctx;
uint32_t t;
const uint8_t key[16] = { 15, 14, 13, 12 , 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
uint8_t msg[19] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 };
const uint8_t ad[17] = { 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34 };
uint8_t nsec[16] = { 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
const uint8_t npub[4] = { 10, 11, 12, 13 };
uint8_t crypt[16 + 19 + 16];
uint8_t *tag = &crypt[16 + 19];
// size_t crypt_len, tag_len, msg_len = sizeof(msg);
// int v;
calibrateTimer();
print_overhead();
uart0_flush();
startTimer(1);
pi16_init(&ctx, key, sizeof(key), npub, sizeof(npub));
t = stopTimer();
printf_P(PSTR("\tinit time (16 + 4) : %10"PRIu32"\n"), t);
uart0_flush();
startTimer(1);
pi16_process_ad_block(&ctx, ad, 1);
t = stopTimer();
printf_P(PSTR("\tprocess ad(16) : %10"PRIu32"\n"), t);
uart0_flush();
startTimer(1);
pi16_process_ad_last_block(&ctx, &ad[16], 1, 2);
t = stopTimer();
printf_P(PSTR("\tprocess last ad(1) : %10"PRIu32"\n"), t);
uart0_flush();
startTimer(1);
pi16_encrypt_smn(&ctx, crypt, nsec);
t = stopTimer();
printf_P(PSTR("\tprocess smn(16) : %10"PRIu32"\n"), t);
uart0_flush();
startTimer(1);
pi16_encrypt_block(&ctx, &crypt[16], msg, 1);
t = stopTimer();
printf_P(PSTR("\tprocess encrypt block(16) : %10"PRIu32"\n"), t);
uart0_flush();
startTimer(1);
pi16_encrypt_last_block(&ctx, &crypt[32], &msg[16], 3, 2);
t = stopTimer();
printf_P(PSTR("\tprocess encrypt last block(3): %10"PRIu32"\n"), t);
uart0_flush();
startTimer(1);
pi16_extract_tag(&ctx, tag);
t = stopTimer();
printf_P(PSTR("\tprocess extract tag(16) : %10"PRIu32"\n"), t);
}
void testrun_pi16(void)
{
const uint8_t key[16] = { 15, 14, 13, 12 , 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
uint8_t msg[19] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 };
const uint8_t ad[17] = { 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34 };
uint8_t nsec[16] = { 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
const uint8_t npub[4] = { 10, 11, 12, 13 };
uint8_t crypt[16 + 19 + 16];
size_t crypt_len, msg_len = sizeof(msg);
int v;
// printf("crypt = %p, crypt_len = %d, tag = %p, tag_len = %d\n", crypt, crypt_len, tag, tag_len);
pi16_encrypt_simple(crypt, &crypt_len, msg, sizeof(msg), ad, sizeof(ad), nsec, npub, sizeof(npub), key, sizeof(key));
// printf("crypt = %p, crypt_len = %d, tag = %p, tag_len = %d\n", crypt, crypt_len, tag, tag_len);
DUMP(key);
DUMP(msg);
DUMP(ad);
DUMP(nsec);
DUMP(npub);
DUMP_LEN(crypt, crypt_len);
puts("");
crypt[0] ^= 0;
v = pi16_decrypt_simple(msg, &msg_len, nsec, crypt, crypt_len, ad, sizeof(ad), npub, sizeof(npub), key, sizeof(key));
DUMP(key);
DUMP(msg);
DUMP(ad);
DUMP(nsec);
DUMP(npub);
DUMP_LEN(crypt, crypt_len);
printf("\nverification: >> %s (%d) <<\n", v ? "FAILED!" : "ok", v);
puts("");
}
void testrun_pi32(void)
{
const uint8_t key[16] = { 0 };
const uint8_t msg[1] = { 0xf };
const uint8_t ad[1] = { 0 };
const uint8_t nsec[PI32_SMN_LENGTH_BYTES] = { 0 };
const uint8_t npub[16] = { 0 };
uint8_t crypt[sizeof(nsec) + sizeof(msg) + 32];
uint16_t crypt_len;
pi32_encrypt_simple(crypt, &crypt_len, msg, sizeof(msg), ad, sizeof(ad), nsec, npub, sizeof(npub), key, sizeof(key));
DUMP(key);
DUMP(msg);
DUMP(ad);
DUMP(nsec);
DUMP(npub);
DUMP(crypt);
}
void testrun_pi64(void)
{
const uint8_t key[16] = { 0 };
const uint8_t msg[1] = { 0xf };
const uint8_t ad[1] = { 0 };
const uint8_t nsec[PI64_SMN_LENGTH_BYTES] = { 0 };
const uint8_t npub[16] = { 0 };
uint8_t crypt[sizeof(nsec) + sizeof(msg) + 64];
uint16_t crypt_len;
pi64_encrypt_simple(crypt, &crypt_len, msg, sizeof(msg), ad, sizeof(ad), nsec, npub, sizeof(npub), key, sizeof(key));
DUMP(key);
DUMP(msg);
DUMP(ad);
DUMP(nsec);
DUMP(npub);
DUMP(crypt);
}
void testrun(void) {
testrun_pi16();
testrun_pi32();
testrun_pi64();
}
static
void print_item(const char *label, const void* data, size_t length) {
printf("%s (%u) = ", label, length);
while (length--) {
printf("%02X", *(uint8_t*)data);
data = (uint8_t*)data + 1;
}
putchar('\n');
}
void generate_single_testvector(
const uint8_t *m, size_t mlen,
const uint8_t *ad, size_t adlen,
const uint8_t *nsec,
const uint8_t *npub, size_t npub_len,
const uint8_t *key, size_t key_len,
void(*encrypt)(void*, size_t*, const void*, size_t, const void*, size_t, const void*, const void*, size_t, const void*, size_t),
int(*decrypt)(void*, size_t*, void*, const void*, size_t, const void*, size_t, const void*, size_t, const void*, size_t),
size_t block_length
) {
uint8_t c[block_length + mlen + block_length];
uint8_t m_check[mlen];
uint8_t nsec_check[block_length];
size_t clen, mlen_check;
int v;
print_item("KEY", key, key_len);
print_item("NPUB", npub, npub_len);
print_item("NSEC", nsec, block_length);
print_item("MSG", m, mlen);
print_item("AD", ad, adlen);
fflush(stdout);
encrypt(c, &clen, m, mlen, ad, adlen, nsec, npub, npub_len, key, key_len);
print_item("CIPHER", c, clen);
fflush(stdout);
v = decrypt(m_check, &mlen_check, nsec_check, c, clen, ad, adlen, npub, npub_len, key, key_len);
if (v) {
printf("!verification failed (%d)\n", v);
}
if (mlen != mlen_check || memcmp(m, m_check, mlen)) {
print_item("!ERROR MSG", m_check, mlen_check);
}
if (memcmp(nsec, nsec_check, block_length)) {
print_item("!ERROR MSG", m_check, mlen_check);
}
putchar('\n');
fflush(stdout);
}
void generate_testvectors(
size_t key_len, size_t npub_len,
void(*encrypt)(void*, size_t*, const void*, size_t, const void*, size_t, const void*, const void*, size_t, const void*, size_t),
int(*decrypt)(void*, size_t*, void*, const void*, size_t, const void*, size_t, const void*, size_t, const void*, size_t),
size_t block_length, const char *cipher_name) {
size_t ad_len, msg_len, i, c = 1;
uint8_t ad[3 * block_length / 2];
uint8_t msg[3 * block_length / 2];
uint8_t key[key_len];
uint8_t npub[npub_len];
uint8_t nsec[block_length];
{
char seed[64];
snprintf(seed, sizeof(seed), "%s%03uv2 (%u byte nonce)", cipher_name, key_len * 8, npub_len);
arcfour_init(seed, strlen(seed) * 8, &prng);
}
for (msg_len = 0; msg_len <= sizeof(msg); ++msg_len) {
for (ad_len = 0; ad_len <= sizeof(ad); ++ad_len) {
printf("[msg_len = %u]\n", msg_len);
printf("[ad_len = %u]\n\n", ad_len);
for (i = 0; i < 8; ++i) {
printf("[vector #%u (%u)]\n", c, i + 1);
++c;
fill_random(key, sizeof(key));
fill_random(npub, sizeof(npub));
fill_random(nsec, sizeof(nsec));
fill_random(ad, ad_len);
fill_random(msg, msg_len);
generate_single_testvector(msg, msg_len, ad, ad_len, nsec, npub, npub_len, key, key_len, encrypt, decrypt, block_length);
}
}
}
}
void tv16(void) {
puts("\n=====\n");
printf("# Testvectors for %s\n", pi16_cipher_name);
printf("# key size: %u bits\n", 128);
printf("# nonce size: %u bits\n\n", 32);
generate_testvectors(16, 4, pi16_encrypt_simple, pi16_decrypt_simple, PI16_PT_BLOCK_LENGTH_BYTES, pi16_cipher_name);
puts("\n=====\n");
}
/*****************************************************************************
* main *
*****************************************************************************/
const char nessie_str[] PROGMEM = "nessie";
const char test_str[] PROGMEM = "test";
const char tv16_str[] PROGMEM = "tv16";
const char test16_str[] PROGMEM = "test16";
const char test32_str[] PROGMEM = "test32";
const char test64_str[] PROGMEM = "test64";
const char ftest_str[] PROGMEM = "ftest";
const char gtest_str[] PROGMEM = "gtest";
const char performance_str[] PROGMEM = "performance";
const char echo_str[] PROGMEM = "echo";
const cmdlist_entry_t cmdlist[] PROGMEM = {
// { nessie_str, NULL, NULL },
{ test_str, NULL, testrun},
{ tv16_str, NULL, tv16},
{ test16_str, NULL, testrun_pi16},
{ test32_str, NULL, testrun_pi32},
{ test64_str, NULL, testrun_pi64},
// { ftest_str, NULL, testrun_f32},
// { gtest_str, NULL, testrun_g32},
{ performance_str, NULL, testrun_performance_pi16cipher},
{ echo_str, (void*)1, (void_fpt)echo_ctrl},
{ NULL, NULL, NULL}
};
int main(void) {
main_setup();
for(;;){
welcome_msg(algo_name);
cmd_interface(cmdlist);
}
}