From 9e7453525f32441ea49ef1d9b3248e94d9554eec Mon Sep 17 00:00:00 2001 From: bg Date: Fri, 11 Apr 2008 17:54:24 +0000 Subject: [PATCH] + noekeon --- Makefile | 25 ++++- avr-makefile.inc | 8 +- config.h | 2 + main-noekeon-test.c | 226 ++++++++++++++++++++++++++++++++++++++++++++ noekeon.c | 160 +++++++++++++++++++++++++++++++ noekeon.h | 21 ++++ performance_test.c | 18 +++- uart.c | 169 ++++++++++++++++++++++++++++----- 8 files changed, 596 insertions(+), 33 deletions(-) create mode 100644 main-noekeon-test.c create mode 100644 noekeon.c create mode 100644 noekeon.h diff --git a/Makefile b/Makefile index 169eb66..79b3338 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,8 @@ HASHES := MACS := PRNGS := - +# we use the gnu make standard library +include gmsl include avr-makefile.inc include *.mk @@ -23,6 +24,9 @@ ALGORITHMS_TEST_BIN_IMM = $(foreach a, $(ALGORITHMS_TEST_BIN), $($(a))) ALGORITHMS_NESSIE_TEST = $(patsubst %,%_NESSIE_TEST, $(ALGORITHMS)) ALGORITHMS_PERFORMANCE_TEST = $(patsubst %,%_PERORMANCE_TEST, $(ALGORITHMS)) +#ALGORITHMS_LC = #algorithm names in lowercase +#ALGORITHMS_LC = $(foreach a, $(ALGORITHMS), $$(lc Text)) +ALGORITHMS_LC = $(call lc,$(ALGORITHMS)) PRG = remove_me DEFS = @@ -53,6 +57,9 @@ info: @echo " $(MACS)" @echo " PRNG functions:" @echo " $(PRNGS)" + @echo " LC functions:" + @echo " $(ALGORITHMS_LC)" + # echo $(ALGORITHMS_TEST_BIN_MAIN) # echo $(ALGORITHMS) # echo $(firstword $(XTEA_TEST_BIN)) @@ -110,6 +117,18 @@ $(PRNGS_OBJ): $(patsubst %,%_OBJ, $(PRNGS)) $(MACS_OBJ): $(patsubst %,%_OBJ, $(MACS)) $(ALGORITHMS_TEST_BIN): $(ALGORITHMS_TEST_BIN_IMM) + + +define SIZE_TEMPLATE +$(1)_size.txt: $(2) + @echo " ALGO: $(1)" + @echo " REQ: $(2)" + $(SIZE) $(2) > $(1)_size.txt +endef + +$(foreach algo, $(ALGORITHMS), $(eval $(call SIZE_TEMPLATE, $(call lc,$(algo)), $($(algo)_OBJ)))) + + .PHONY: all all: $(PRG).elf lst text eeprom @@ -163,8 +182,8 @@ esrec: $(PRG)_eeprom.srec %_eeprom.bin: %.elf $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@ -%_size.txt: %.o - $(SIZE) $< > $@ +#%_size.txt: %.o +# $(SIZE) $< > $@ diff --git a/avr-makefile.inc b/avr-makefile.inc index 4db2606..dfc3474 100644 --- a/avr-makefile.inc +++ b/avr-makefile.inc @@ -1,8 +1,8 @@ OBJ = $(SERPENT_OBJ) -MCU_TARGET = atmega32 +MCU_TARGET = atmega644 OPTIMIZE = -Os - +DEFS = -DATMEGA644 FLASHCMD = avrdude -p $(MCU_TARGET) -P /dev/ttyUSB0 -c avr911 -U flash:w:$(PRG).hex # -U eeprom:w:$(PRG)_eeprom.hex #uisp -dprog=bsd -dlpt=/dev/parport1 --upload if=$(PRG).hex @@ -10,8 +10,8 @@ ERASECMD = CC = avr-gcc -override CFLAGS = -pedantic -std=c99 -Wall -Wstrict-prototypes $(OPTIMIZE) -mmcu=$(MCU_TARGET) -$(DEFS) +override CFLAGS = -pedantic -std=c99 -Wall -Wstrict-prototypes $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS) + override LDFLAGS = -Wl,-Map, override ASFLAGS = -mmcu=$(MCU_TARGET) diff --git a/config.h b/config.h index 5586a32..09cbf61 100644 --- a/config.h +++ b/config.h @@ -23,5 +23,7 @@ #define UART_CTS_BIT 1 */ +#define ATMEGA644 + #endif diff --git a/main-noekeon-test.c b/main-noekeon-test.c new file mode 100644 index 0000000..43eb3a9 --- /dev/null +++ b/main-noekeon-test.c @@ -0,0 +1,226 @@ +/* + * serpent test-suit + * +*/ + +#include "config.h" +#include "serial-tools.h" +#include "uart.h" +#include "debug.h" + +#include "noekeon.h" +#include "nessie_bc_test.h" +#include "cli.h" +#include "performance_test.h" + +#include +#include +#include + +char* cipher_name = "Noekeon"; + +/***************************************************************************** + * additional validation-functions * + *****************************************************************************/ +void noekeon_genctx_dummy(uint8_t* key, uint16_t keysize, void* ctx){ + noekeon_init(key, ctx); +} + +void testrun_nessie_noekeon_indirect(void){ + char str[strlen(cipher_name)+10]; + strcpy(str, cipher_name); + strcat(str, "-indirect"); + + nessie_bc_ctx.blocksize_B = 16; + nessie_bc_ctx.keysize_b = 128; + nessie_bc_ctx.name = str; + nessie_bc_ctx.ctx_size_B = sizeof(noekeon_ctx_t); + nessie_bc_ctx.cipher_enc = (nessie_bc_enc_fpt)noekeon_enc; + nessie_bc_ctx.cipher_dec = (nessie_bc_dec_fpt)noekeon_dec; + nessie_bc_ctx.cipher_genctx = (nessie_bc_gen_fpt)noekeon_genctx_dummy; + + nessie_bc_run(); +} + +void noekeon_genctx_dummy_direct(uint8_t* key, uint16_t keysize, void* ctx){ + memcpy(ctx, key, 16); +} + +void testrun_nessie_noekeon_direct(void){ + char str[strlen(cipher_name)+10]; + strcpy(str, cipher_name); + strcat(str, "-Direct"); + + nessie_bc_ctx.blocksize_B = 16; + nessie_bc_ctx.keysize_b = 128; + nessie_bc_ctx.name = str; + nessie_bc_ctx.ctx_size_B = sizeof(noekeon_ctx_t); + nessie_bc_ctx.cipher_enc = (nessie_bc_enc_fpt)noekeon_enc; + nessie_bc_ctx.cipher_dec = (nessie_bc_dec_fpt)noekeon_dec; + nessie_bc_ctx.cipher_genctx = (nessie_bc_gen_fpt)noekeon_genctx_dummy_direct; + + nessie_bc_run(); +} + +void testrun_stdtest_rundirect(void* data, void* key){ + uart_putstr_P(PSTR("\r\n ")); + uart_putstr_P(PSTR("k = ")); + uart_hexdump(key,16); + + uart_putstr_P(PSTR("\r\n ")); + uart_putstr_P(PSTR("a = ")); + uart_hexdump(data,16); + + noekeon_enc(data, key); + uart_putstr_P(PSTR("\r\nafter NESSIEencrypt, b = ")); + uart_hexdump(data,16); + + noekeon_dec(data, key); + uart_putstr_P(PSTR("\r\nafter NESSIEdecrypt, a?= ")); + uart_hexdump(data,16); + uart_putstr_P(PSTR("\r\n")); +} + +void testrun_stdtest_runindirect(void* data, void* key){ + noekeon_ctx_t ctx; + uart_putstr_P(PSTR("\r\n ")); + uart_putstr_P(PSTR("k = ")); + uart_hexdump(key,16); + + uart_putstr_P(PSTR("\r\n ")); + uart_putstr_P(PSTR("a = ")); + uart_hexdump(data,16); + noekeon_init(key, &ctx); + noekeon_enc(data, &ctx); + uart_putstr_P(PSTR("\r\nafter NESSIEencrypt, b = ")); + uart_hexdump(data,16); + + noekeon_dec(data, &ctx); + uart_putstr_P(PSTR("\r\nafter NESSIEdecrypt, a?= ")); + uart_hexdump(data,16); + uart_putstr_P(PSTR("\r\n")); +} + +void testrun_stdtest_noekeon(void){ + uint8_t key[16], data[16]; + uint8_t key3[16]; + noekeon_ctx_t ctx; + + uart_putstr_P(PSTR("\r\nTest vectors for block cipher Noekeon in Indirect-Key Mode:\r\n")); + + memset(key, 0, 16); + memset(data, 0, 16); + testrun_stdtest_runindirect(data, key); + + memset(key, 0xFF, 16); + memset(data, 0xFF, 16); + testrun_stdtest_runindirect(data, key); + + memset(key, 0, 16); + memset(data, 0, 16); + noekeon_init(key, &ctx); + noekeon_enc(data, &ctx); + memcpy(key3, data, 16); + memset(key, 0xFF, 16); + memset(data, 0xFF, 16); + noekeon_init(key, &ctx); + noekeon_enc(data, &ctx); + testrun_stdtest_runindirect(data, key3); + + + uart_putstr_P(PSTR("\r\nTest vectors for block cipher Noekeon in Direct-Key Mode:\r\n")); + + memset(key, 0, 16); + memset(data, 0, 16); + testrun_stdtest_rundirect(data, key); + + memset(key, 0xFF, 16); + memset(data, 0xFF, 16); + testrun_stdtest_rundirect(data, key); + + memset(key, 0, 16); + memset(data, 0, 16); + noekeon_enc(data, key); + memcpy(key3, data, 16); + memset(key, 0xFF, 16); + memset(data, 0xFF, 16); + noekeon_enc(data, key); + testrun_stdtest_rundirect(data, key3); + +} + +void testrun_performance_noekeon(void){ + uint16_t i,c; + uint64_t t; + char str[6]; + uint8_t key[16], data[16]; + noekeon_ctx_t ctx; + + calibrateTimer(); + getOverhead(&c, &i); + uart_putstr_P(PSTR("\r\n\r\n=== benchmark ===")); + utoa(c, str, 10); + uart_putstr_P(PSTR("\r\n\tconst overhead: ")); + uart_putstr(str); + utoa(i, str, 10); + uart_putstr_P(PSTR("\r\n\tinterrupt overhead: ")); + uart_putstr(str); + + memset(key, 0, 16); + memset(data, 0, 16); + + startTimer(1); + noekeon_init(key, &ctx); + t = stopTimer(); + uart_putstr_P(PSTR("\r\n\tctx-gen time: ")); + uart_hexdump(&t, 8); + + + startTimer(1); + noekeon_enc(data, ctx); + t = stopTimer(); + uart_putstr_P(PSTR("\r\n\tencrypt time: ")); + uart_hexdump(&t, 8); + + + startTimer(1); + noekeon_dec(data, ctx); + t = stopTimer(); + uart_putstr_P(PSTR("\r\n\tdecrypt time: ")); + uart_hexdump(&t, 8); + uart_putstr_P(PSTR("\r\n")); +} +/***************************************************************************** + * main * + *****************************************************************************/ + +typedef void(*void_fpt)(void); + +int main (void){ + char str[20]; + DEBUG_INIT(); + uart_putstr("\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")); + + PGM_P u = PSTR("nessie\0test\0direct\0indirect\0performance\0"); + void_fpt v[] = {testrun_nessie_noekeon_direct, + testrun_stdtest_noekeon, + testrun_nessie_noekeon_direct, + testrun_nessie_noekeon_indirect, + testrun_performance_noekeon}; + + while(1){ + if (!getnextwordn(str,20)){DEBUG_S("DBG: W1\r\n"); goto error;} + if(execcommand_d0_P(str, u, v)<0){ + uart_putstr_P(PSTR("\r\nunknown command\r\n")); + } + continue; + error: + uart_putstr("ERROR\r\n"); + } + +} + diff --git a/noekeon.c b/noekeon.c new file mode 100644 index 0000000..dd68b65 --- /dev/null +++ b/noekeon.c @@ -0,0 +1,160 @@ +/* + * author: Daniel Otte + * email: daniel.otte@rub.de + * license: GPLv3 + * + * + * + */ + +#include +#include +#include +#include "noekeon.h" + +#define ROUND_NR 16 + +#define RC_POS 0 + +static +void gamma(uint32_t* a){ + uint32_t tmp; + + a[1] ^= ~((a[3]) | (a[2])); + a[0] ^= a[2] & a[1]; + + tmp=a[3]; a[3]=a[0]; a[0]=tmp; + a[2] ^= a[0] ^ a[1] ^ a[3]; + + a[1] ^= ~((a[3]) | (a[2])); + a[0] ^= a[2] & a[1]; +} + +#define ROTL32(a,n) (((a)<>(32-n))) +#define ROTR32(a,n) (((a)>>n)|((a)<<(32-n))) + +static +void pi1(uint32_t* a){ + a[1] = ROTL32(a[1], 1); + a[2] = ROTL32(a[2], 5); + a[3] = ROTL32(a[3], 2); +} + +static +void pi2(uint32_t* a){ + a[1] = ROTR32(a[1], 1); + a[2] = ROTR32(a[2], 5); + a[3] = ROTR32(a[3], 2); +} + +static +void theta(uint32_t* k, uint32_t* a){ + uint32_t temp; + temp = a[0] ^ a[2]; temp ^= ROTR32(temp, 8) ^ ROTL32(temp, 8); + a[1] ^= temp; + a[3] ^= temp; + + a[0] ^= k[0]; + a[1] ^= k[1]; + a[2] ^= k[2]; + a[3] ^= k[3]; + + temp = a[1] ^ a[3]; temp ^= ROTR32(temp, 8) ^ ROTL32(temp, 8); + a[0] ^= temp; + a[2] ^= temp; +} + +static +void noekeon_round(uint32_t* key, uint32_t* state, uint8_t const1, uint8_t const2){ + ((uint8_t*)state)[RC_POS] ^= const1; + theta(key, state); + ((uint8_t*)state)[RC_POS] ^= const2; + pi1(state); + gamma(state); + pi2(state); +} + +uint8_t rc_tab[] PROGMEM = { +/* 0x80, */ + 0x1B, 0x36, 0x6C, 0xD8, 0xAB, 0x4D, 0x9A, + 0x2F, 0x5E, 0xBC, 0x63, 0xC6, 0x97, 0x35, 0x6A, + 0xD4 +}; +/* for more rounds + 0xD4, 0xB3, 0x7D, 0xFA, 0xEF, 0xC5, 0x91, 0x39, + 0x72, 0xE4, 0xD3, 0xBD, 0x61, 0xC2, 0x9F, 0x25, +*/ + +static +void changendian32(void* a){ + ((uint8_t*)a)[0] ^= ((uint8_t*)a)[3]; + ((uint8_t*)a)[3] ^= ((uint8_t*)a)[0]; + ((uint8_t*)a)[0] ^= ((uint8_t*)a)[3]; + + ((uint8_t*)a)[1] ^= ((uint8_t*)a)[2]; + ((uint8_t*)a)[2] ^= ((uint8_t*)a)[1]; + ((uint8_t*)a)[1] ^= ((uint8_t*)a)[2]; +} + +static +void changendian(void* a){ + changendian32((uint32_t*)(&(((uint32_t*)a)[0]))); + changendian32((uint32_t*)(&(((uint32_t*)a)[1]))); + changendian32((uint32_t*)(&(((uint32_t*)a)[2]))); + changendian32((uint32_t*)(&(((uint32_t*)a)[3]))); +} + +/******************************************************************************/ + +void noekeon_enc(void* buffer, void* key){ + uint8_t rc=0x80; + int8_t i; + + changendian(buffer); + changendian(key); + + for(i=0; i=0; --i){ + rc = pgm_read_byte(rc_tab+i); + noekeon_round((uint32_t*)dkey, (uint32_t*)buffer, 0, rc); + } + theta((uint32_t*)dkey, (uint32_t*)buffer); + ((uint8_t*)buffer)[RC_POS] ^= 0x80; + + changendian(buffer); + changendian(key); +} + +void noekeon_init(void* key, noekeon_ctx_t* ctx){ + uint8_t nullv[16]; + + memset(nullv, 0, 16); + memcpy(ctx, key, 16); + noekeon_enc(ctx, nullv); +} + diff --git a/noekeon.h b/noekeon.h new file mode 100644 index 0000000..14714ff --- /dev/null +++ b/noekeon.h @@ -0,0 +1,21 @@ +#ifndef NOEKEON_H_ +#define NOEKEON_H_ + +/* + * author: Daniel Otte + * email: daniel.otte@rub.de + * license: GPLv3 + * + * + * + */ + +#include + +typedef uint8_t noekeon_ctx_t[16]; + +void noekeon_enc(void* buffer, void* key); +void noekeon_dec(void* buffer, void* key); +void noekeon_init(void* key, noekeon_ctx_t* ctx); + +#endif /*NOEKEON_H_*/ diff --git a/performance_test.c b/performance_test.c index 91d4f1c..0728827 100644 --- a/performance_test.c +++ b/performance_test.c @@ -1,15 +1,25 @@ /* + * author: Daniel Otte + * email: daniel.otte@rub.de + * license: GPLv3 * * - * - */ - + **/ + +#include "config.h" #include #include #include #include #include "performance_test.h" + +#ifdef ATMEGA644 + #define TIMSK TIMSK1 +#endif + + + uint32_t ovfcounter; uint16_t const_overhead=0; @@ -37,7 +47,7 @@ void startTimer(uint8_t granularity){ ovfcounter = 0; TCCR1A = 0x00; TIMSK &= 0xC3; - TIMSK |= _BV(2); /* enable TOIE1 */ + TIMSK |= _BV(TOIE1); /* enable TOIE1 */ TCCR1B = granularity & 0x7; /* start timer */ } diff --git a/uart.c b/uart.c index 68aaac4..94de47e 100644 --- a/uart.c +++ b/uart.c @@ -3,7 +3,6 @@ #include "config.h" #include -//#include #include #include @@ -18,9 +17,42 @@ #define URSEL UMSEL #endif +#ifdef ATMEGA644 +#define UCSRB UCSR0B +#define UCSRC UCSR0C +#define UDR UDR0 +#define UBRRH UBRR0H +#define UBRRL UBRR0L +#define URSEL UMSEL00 +#define USART_UDRE_vect USART0_UDRE_vect +#define USART_RXC_vect USART0_RX_vect +#define UDRIE UDRIE0 +#define TXEN TXEN0 +#define UMSEL UMSEL0 +#define RXEN RXEN0 +#define RXCIE RXCIE0 +#define UCSZ0 UCSZ00 +#define UCSRA UCSR0A +#define UDRE UDRE0 +#define RXC RXC0 +#endif + + +#ifdef UART_XON_XOFF + #ifdef UART_INTERRUPT + void uart_insertc(char c); + #else + #define uart_insertc uart_putc + #endif /* UART_INTERRUPT */ +#endif #define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_OSC)/((UART_BAUD_RATE)*16L)-1) +#ifdef UART_XON_XOFF + typedef enum{go=1,nogo=0} gonogo; + static gonogo txon=go; + static gonogo rxon=go; +#endif #ifdef UART_INTERRUPT volatile static char rxbuf[UART_RXBUFSIZE]; @@ -28,8 +60,11 @@ volatile static char txbuf[UART_TXBUFSIZE]; volatile static char *volatile rxhead, *volatile rxtail; volatile static char *volatile txhead, *volatile txtail; +#ifdef UART_HOOK + void (*uart_hook) (uint8_t) = (void*)0; /* this is a pointer to a function ;-) */ +#endif -SIGNAL(SIG_UART_DATA) { +ISR(USART_UDRE_vect) { #ifdef UART_LEDS PORTC ^= 0x01; #endif @@ -37,39 +72,89 @@ SIGNAL(SIG_UART_DATA) { if ( txhead == txtail ) { UCSRB &= ~(1 << UDRIE); /* disable data register empty IRQ */ } else { + #ifdef UART_XON_XOFF + while(txon==nogo) + ; + #endif UDR = *txtail; /* schreibt das Zeichen x auf die Schnittstelle */ if (++txtail == (txbuf + UART_TXBUFSIZE)) txtail = txbuf; } } -SIGNAL(SIG_UART_RECV) { +ISR(USART_RXC_vect) { int diff; - + char c; +#ifdef UART_HOOK + static volatile uint8_t hook_running=0; +#endif #ifdef UART_LEDS PORTC ^= 0x02; #endif - + c=UDR; + #ifdef UART_XON_XOFF + if (c==XON){ + txon=go; + return; + } + if (c==XOFF){ + txon=nogo; + return; + } + #endif /* buffer full? */ diff = rxhead - rxtail; - if ( diff < 0 ) diff += UART_RXBUFSIZE; + if (diff < 0) diff += UART_RXBUFSIZE; /* diff is the amount of bytes in buffer */ if (diff < UART_RXBUFSIZE -1) { // buffer NOT full - *rxhead = UDR; - if (++rxhead == (rxbuf + UART_RXBUFSIZE)) rxhead = rxbuf; +#ifdef UART_HOOK + if(!hook_running && uart_hook){ + uint8_t t=c; + hook_running = 1; + sei(); /* reenable interrupts, avoid recursion!!! */ + do { + uart_hook(t); + } while(uart_getc_nb((char*)&t)); + hook_running = 0; + } else { + *rxhead = c; + ++rxhead; + if (rxhead == (rxbuf + UART_RXBUFSIZE)) rxhead = rxbuf; + } +#else + *rxhead = c; + ++rxhead; + if (rxhead == (rxbuf + UART_RXBUFSIZE)) + rxhead = rxbuf; +#endif } else { - UDR; //reads the buffer to clear the interrupt condition + //reads the buffer to clear the interrupt condition } +#ifdef UART_XON_XOFF + if((diff > UART_XON_XOFF_THRESHOLD_1) && (rxon==go)){ + rxon=nogo; + uart_insertc(XOFF); + } + if((diff < UART_XON_XOFF_THRESHOLD_2) && (rxon==nogo)){ + rxon=go; + uart_insertc(XON); + } +#endif } #endif // UART_INTERRUPT -void uart_init(void) { +void uart_init() { PORTD |= 0x01; //Pullup an RXD an - + UCSRB |= (1<>8); @@ -81,11 +166,32 @@ void uart_init(void) { txhead = txtail = txbuf; // activate rx IRQ - UCSRB |= (1 << RXCIE); + UCSRB |= _BV(RXCIE) | _BV(UDRIE); + sei(); +// #ifdef ATMEGA644 +// UCSRB |= _BV(UDRIE); +// #endif #endif // UART_INTERRUPT } #ifdef UART_INTERRUPT +#ifdef UART_XON_XOFF + +void uart_insertc(char c){ + volatile int diff; + do { + diff = txhead - txtail; + if ( diff < 0 ) diff += UART_TXBUFSIZE; + } while ( diff >= UART_TXBUFSIZE -1 ); + + cli(); + if (--txtail == (txbuf-1)) txtail += UART_TXBUFSIZE; + *txtail = c; + + UCSRB |= (1 << UDRIE); /* enable data register empty IRQ */ + sei(); +} +#endif /* UART_XON_XOFF */ void uart_putc(char c) { volatile int diff; @@ -104,8 +210,13 @@ void uart_putc(char c) { } #else // WITHOUT INTERRUPT void uart_putc(char c) { - while (!(UCSRA & (1<>4)&0xf]); uart_putc(table[(*((char*)buf))&0xf]); uart_putc(' '); - buf=(char*)buf+1; + buf=(uint8_t*)buf+1; } } @@ -142,18 +253,28 @@ char uart_getc(void) { char val; - while(rxhead==rxtail) ; + while(rxhead==rxtail) + ; val = *rxtail; - if (++rxtail == (rxbuf + UART_RXBUFSIZE)) rxtail = rxbuf; + ++rxtail; + if (rxtail == (rxbuf + UART_RXBUFSIZE)) + rxtail = rxbuf; return val; } #else // WITHOUT INTERRUPT char uart_getc(void) { - while (!(UCSRA & (1<