diff --git a/Makefile b/Makefile index 42a79bd..3761ed5 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ PRG = serpent-test #PRG = tdes-test # camellia # cryptotest -SERPENT_OBJ = main-serpent-test.o debug.o uart.o serial-tools.o serpent.o +SERPENT_OBJ = main-serpent-test.o debug.o uart.o serial-tools.o serpent.o nessie_bc_test.o CAMELLIA_OBJ = main-camellia-test.o debug.o uart.o serial-tools.o camellia.o camellia-asm.o SKIPJACK_OBJ = main-skipjack-test.o debug.o uart.o serial-tools.o skipjack.o SHA1_OBJ = main-sha1-test.o debug.o uart.o serial-tools.o sha1-asm.o diff --git a/main-serpent-test.c b/main-serpent-test.c index 120d402..6e2ce8c 100644 --- a/main-serpent-test.c +++ b/main-serpent-test.c @@ -9,109 +9,37 @@ #include "debug.h" #include "serpent.h" +#include "nessie_bc_test.h" #include #include +char* cipher_name = "Serpent"; /***************************************************************************** * additional validation-functions * *****************************************************************************/ - -/***************************************************************************** - * self tests * - *****************************************************************************/ - -void dumpctx(serpent_ctx_t * ctx){ - uint8_t i; - uart_putstr("\r\n --ctx dump--\r\n"); - for(i=0; i<33; ++i){ - uart_putstr(" K["); uart_putc('0'+i/10); uart_putc('0'+i%10); uart_putstr("] = "); - uart_hexdump(ctx->k[i],16); - uart_putstr("\r\n"); - } +void serpent_genctx_dummy(uint8_t* key, uint16_t keysize, void* ctx){ + serpent_genctx(key, keysize&0xff, ctx); } -void testencrypt(uint8_t* block, uint8_t* key){ - serpent_ctx_t ctx; - uart_putstr("\r\n==testy-encrypt==\r\n key: "); - uart_hexdump(key,32); - serpent_genctx(key, &ctx); -// dumpctx(&ctx); - uart_putstr("\r\n plain: "); - uart_hexdump(block,16); - serpent_enc(block, &ctx); - uart_putstr("\r\n crypt: "); - uart_hexdump(block,16); -} - -void testdecrypt(uint8_t* block, uint8_t* key){ - serpent_ctx_t ctx; - uart_putstr("\r\n==testy-decrypt==\r\n key: "); - uart_hexdump(key,32); - serpent_genctx(key, &ctx); -// dumpctx(&ctx); - uart_putstr("\r\n crypt: "); - uart_hexdump(block,16); - serpent_dec(block, &ctx); - uart_putstr("\r\n plain: "); - uart_hexdump(block,16); -} - -/** - Test vectors -- set 4 -===================== - -Set 4, vector# 0: - key=000102030405060708090A0B0C0D0E0F - 101112131415161718191A1B1C1D1E1F - plain=00112233445566778899AABBCCDDEEFF - cipher=2868B7A2D28ECD5E4FDEFAC3C4330074 - decrypted=00112233445566778899AABBCCDDEEFF - Iterated 100 times=8BF56992354F3F1A0F4E49DCBA82CBC0 - Iterated 1000 times=9B1D8B34845DF9BFD36AAAD0CDA1C8FE - -Set 4, vector# 1: - key=2BD6459F82C5B300952C49104881FF48 - 2BD6459F82C5B300952C49104881FF48 - plain=EA024714AD5C4D84EA024714AD5C4D84 - cipher=3E507730776B93FDEA661235E1DD99F0 - decrypted=EA024714AD5C4D84EA024714AD5C4D84 - Iterated 100 times=3B5462E5D87A40C4BE745E3994D5E373 - Iterated 1000 times=99D5D067EF7C787E6A764EB47DAC59AD - - -Set 1, vector# 0: - key=80000000000000000000000000000000 - 00000000000000000000000000000000 - plain=00000000000000000000000000000000 - cipher=A223AA1288463C0E2BE38EBD825616C0 - decrypted=00000000000000000000000000000000 - Iterated 100 times=739E0148971FD975B585EAFDBD659E2C - Iterated 1000 times=BEFD00E0D6E27E56951DC6614440D286 - -*/ - void testrun_serpent(void){ + nessie_ctx.blocksize_B = 16; + nessie_ctx.keysize = 128; + nessie_ctx.name = cipher_name; + nessie_ctx.ctx_size_B = sizeof(serpent_ctx_t); + nessie_ctx.cipher_enc = serpent_enc; + nessie_ctx.cipher_dec = serpent_dec; + nessie_ctx.cipher_genctx = serpent_genctx_dummy; + + nessie_run(); + + nessie_ctx.keysize = 192; + nessie_run(); + + nessie_ctx.keysize = 256; + nessie_run(); - uint8_t key[]={ 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 }; - - uint8_t data[]={ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}; -/* * / - uint8_t key[]={ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - uint8_t data[]={ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -*/ - testencrypt(data,key); - testdecrypt(data,key); } @@ -121,12 +49,13 @@ void testrun_serpent(void){ *****************************************************************************/ int main (void){ - char str[20]; - + char str[20]; DEBUG_INIT(); uart_putstr("\r\n"); - uart_putstr("\r\n\r\nCrypto-VS (serpent)\r\nloaded and running\r\n"); + uart_putstr_P(PSTR("\r\n\r\nCrypto-VS (")); + uart_putstr(cipher_name); + uart_putstr_P(PSTR(")\r\nloaded and running\r\n")); restart: while(1){ diff --git a/nessie_bc_test.c b/nessie_bc_test.c new file mode 100644 index 0000000..6614735 --- /dev/null +++ b/nessie_bc_test.c @@ -0,0 +1,295 @@ +/** + * + * author: Daniel Otte + * email: daniel.otte@rub.de + * license: GPLv3 + * + * a suit for running the nessie-tests for blockciphers + * + * */ +#include +#include +#include "nessie_bc_test.h" +#include "uart.h" + + + +nessie_ctx_t nessie_ctx; + +static void printblock(uint8_t* block, uint16_t blocksize_bit){ + char tab [] = {'0', '1', '2', '3', + '4', '5', '6', '7', + '8', '9', 'A', 'B', + 'C', 'D', 'E', 'F'}; + uint16_t i; + for(i=0; i<(blocksize_bit+7)/8; ++i){ + uart_putc(tab[(block[i])>>4]); + uart_putc(tab[(block[i])&0xf]); + } +} + +#define SPACES 31 +#define BYTESPERLINE 16 + +static void printitem(char* name, uint8_t* buffer, uint16_t size_B){ + uint8_t name_len; + uint8_t i; + name_len=strlen(name); + if(name_len>SPACES-1){ + uart_putstr_P(PSTR("\r\n!!! formatting error !!!\r\n")); + return; + } + uart_putstr_P(PSTR("\r\n")); + for(i=0; iBYTESPERLINE)?BYTESPERLINE:toprint)*8); + buffer += BYTESPERLINE; + toprint -= BYTESPERLINE; + } + } +} + +void nessie_enc(uint8_t* key, uint8_t* pt){ + uint8_t ctx[nessie_ctx.ctx_size_B]; + uint8_t buffer[nessie_ctx.blocksize_B]; + uint16_t i; + + /* single test */ + printitem("key", key, (nessie_ctx.keysize+7)/8); + nessie_ctx.cipher_genctx(key, nessie_ctx.keysize, ctx); + memcpy(buffer, pt, nessie_ctx.blocksize_B); + printitem("plain", buffer, nessie_ctx.blocksize_B); + nessie_ctx.cipher_enc(buffer, ctx); + printitem("cipher", buffer, nessie_ctx.blocksize_B); + nessie_ctx.cipher_dec(buffer, ctx); + printitem("decrypted", buffer, nessie_ctx.blocksize_B); + + /* 100 times test */ + memcpy(buffer, pt, nessie_ctx.blocksize_B); + for(i=0; i<100; ++i){ + nessie_ctx.cipher_enc(buffer, ctx); + } + printitem("Iterated 100 times", buffer, nessie_ctx.blocksize_B); +#ifndef NESSIE_NO1KTEST + /* 1000 times test, we use the 100 precedig steps to fasten things a bit */ + for(; i<1000; ++i){ + nessie_ctx.cipher_enc(buffer, ctx); + } + printitem("Iterated 1000 times", buffer, nessie_ctx.blocksize_B); +#endif +} + +void nessie_dec(uint8_t* key, uint8_t* ct){ + uint8_t ctx[nessie_ctx.ctx_size_B]; + uint8_t buffer[nessie_ctx.blocksize_B]; + + /* single test */ + printitem("key", key, (nessie_ctx.keysize+7)/8); + nessie_ctx.cipher_genctx(key, nessie_ctx.keysize, ctx); + memcpy(buffer, ct, nessie_ctx.blocksize_B); + printitem("cipher", buffer, nessie_ctx.blocksize_B); + nessie_ctx.cipher_dec(buffer, ctx); + printitem("plain", buffer, nessie_ctx.blocksize_B); + nessie_ctx.cipher_enc(buffer, ctx); + printitem("encrypted", buffer, nessie_ctx.blocksize_B); + +} + +static void print_set_vector(uint8_t set, uint16_t vector){ + uart_putstr_P(PSTR("\r\n\r\nSet ")); + uart_putc('0'+set%10); + uart_putstr_P(PSTR(", vector#")); + uart_putc((vector<100)?' ':'0'+vector/100); + uart_putc((vector<100)?' ':'0'+(vector/10)%10); + uart_putc('0'+vector%10); + uart_putc(':'); +} + +/* example: +Test vectors -- set 3 +===================== + */ +static void print_setheader(uint8_t set){ + uart_putstr_P(PSTR("\r\n\r\nTest vectors -- set ")); + uart_putc('0'+set%10); + uart_putstr_P(PSTR("\r\n=====================")); +} + +/* example: +******************************************************************************** +*Project NESSIE - New European Schemes for Signature, Integrity, and Encryption* +******************************************************************************** + +Primitive Name: Serpent +======================= +Key size: 256 bits +Block size: 128 bits +*/ + +static void print_header(void){ + uint16_t i; + uart_putstr_P(PSTR("\r\n\r\n" + "********************************************************************************\r\n" + "* micro-cryt - crypto primitives for microcontrolles by Daniel Otte *\r\n" + "********************************************************************************\r\n" + "\r\n")); + uart_putstr_P(PSTR("Primitive Name: ")); + uart_putstr(nessie_ctx.name); + uart_putstr_P(PSTR("\r\n")); + for(i=0; i<16+strlen(nessie_ctx.name); ++i){ + uart_putc('='); + } + uart_putstr_P(PSTR("\r\nKey size: ")); + if(nessie_ctx.keysize>100){ + uart_putc('0'+nessie_ctx.keysize/100); + } + if(nessie_ctx.keysize>10){ + uart_putc('0'+(nessie_ctx.keysize/10)%10); + } + uart_putc('0'+nessie_ctx.keysize%10); + uart_putstr_P(PSTR(" bits\r\nBlock size: ")); + if(nessie_ctx.blocksize_B*8>100){ + uart_putc('0'+(nessie_ctx.blocksize_B*8)/100); + } + if(nessie_ctx.blocksize_B*8>10){ + uart_putc('0'+((nessie_ctx.blocksize_B*8)/10)%10); + } + uart_putc('0'+(nessie_ctx.blocksize_B*8)%10); + uart_putstr_P(PSTR(" bits")); +} + +static void print_footer(void){ + uart_putstr_P(PSTR("\r\n\r\n\r\n\r\nEnd of test vectors")); +} + +void nessie_run(void){ + uint16_t i; + uint8_t set; + uint8_t key[(nessie_ctx.keysize+7)/8]; + uint8_t buffer[nessie_ctx.blocksize_B]; + + print_header(); + /* test set 1 */ + set=1; + print_setheader(set); + for(i=0; i>(i%8); + memset(buffer, 0, nessie_ctx.blocksize_B); + nessie_enc(key, buffer); + } + /* test set 2 */ + set=2; + print_setheader(set); + for(i=0; i>(i%8); + nessie_enc(key, buffer); + } + /* test set 3 */ + set=3; + print_setheader(set); + for(i=0; i<256; ++i){ + print_set_vector(set, i); + memset(key, i, (nessie_ctx.keysize+7)/8); + memset(buffer, i, nessie_ctx.blocksize_B); + nessie_enc(key, buffer); + } + /* test set 4 */ + set=4; + print_setheader(set); + /* 4 - 0*/ + print_set_vector(set, 0); + for(i=0; i<(nessie_ctx.keysize+7)/8; ++i){ + key[i]=i; + } + for(i=0; i>(i%8); + memset(buffer, 0, nessie_ctx.blocksize_B); + nessie_dec(key, buffer); + } + /* test set 6 */ + set=6; + print_setheader(set); + for(i=0; i>(i%8); + nessie_dec(key, buffer); + } + /* test set 7 */ + set=7; + print_setheader(set); + for(i=0; i<256; ++i){ + print_set_vector(set, i); + memset(key, i, (nessie_ctx.keysize+7)/8); + memset(buffer, i, nessie_ctx.blocksize_B); + nessie_dec(key, buffer); + } + /* test set 8 */ + set=8; + print_setheader(set); + /* 8 - 0*/ + print_set_vector(set, 0); + for(i=0; i<(nessie_ctx.keysize+7)/8; ++i){ + key[i]=i; + } + for(i=0; i + +typedef struct nessie_ctx_st{ + uint16_t keysize; + uint16_t blocksize_B; + uint16_t ctx_size_B; + char* name; + void (*cipher_genctx)(uint8_t* key, uint16_t keysize, void* ctx); + void (*cipher_enc)(void* buffer, void* ctx); + void (*cipher_dec)(void* buffer, void* ctx); +} nessie_ctx_t; + + +extern nessie_ctx_t nessie_ctx; + +void nessie_enc(uint8_t* key, uint8_t* pt); +void nessie_dec(uint8_t* key, uint8_t* ct); +void nessie_run(void); + +#endif /*NESSIE_BC_TEST_H_*/ diff --git a/serpent.c b/serpent.c index b2773fc..85cf4a8 100644 --- a/serpent.c +++ b/serpent.c @@ -170,10 +170,18 @@ static uint32_t gen_w(uint32_t * b, uint8_t i){ } /* key must be 256bit (32 byte) large! */ -void serpent_genctx(void * key, serpent_ctx_t * ctx){ +void serpent_genctx(void * key, uint8_t keysize, serpent_ctx_t * ctx){ uint32_t buffer[8]; uint8_t i,j; - memcpy(buffer, key, 32); + if(keysize){ + /* keysize is less than 256 bit, padding needed */ + memset(buffer, 0, 32); + memcpy(buffer, key, (keysize+7)/8); + ((uint8_t*)buffer)[keysize/8] |= 1<<(keysize%8); + } else { + /* keysize is 256 bit */ + memcpy(buffer, key, 32); + } for(i=0; i<33; ++i){ for(j=0; j<4; ++j){ ctx->k[i][j] = gen_w(buffer, i*4+j); diff --git a/serpent.h b/serpent.h index ab95f7e..41e3d43 100644 --- a/serpent.h +++ b/serpent.h @@ -15,8 +15,13 @@ typedef struct serpent_ctx_st { serpent_subkey_t k[33]; } serpent_ctx_t; +#define SERPENT_KEY128 128 +#define SERPENT_KEY192 192 +#define SERPENT_KEY256 0 + + /* key must be 256bit (32 byte) large! */ -void serpent_genctx(void * key, serpent_ctx_t * ctx); +void serpent_genctx(void * key, uint8_t keysize, serpent_ctx_t * ctx); void serpent_enc(void * buffer, serpent_ctx_t * ctx); void serpent_dec(void * buffer, serpent_ctx_t * ctx);