]> git.cryptolib.org Git - arm-crypto-lib.git/commitdiff
initial commit of a bunch of code
authorbg <bg@cypex>
Sat, 8 May 2010 01:17:34 +0000 (03:17 +0200)
committerbg <bg@cypex>
Sat, 8 May 2010 01:17:34 +0000 (03:17 +0200)
192 files changed:
blake/blake_common.c [new file with mode: 0644]
blake/blake_common.h [new file with mode: 0644]
blake/blake_large.c [new file with mode: 0644]
blake/blake_large.h [new file with mode: 0644]
blake/blake_small.c [new file with mode: 0644]
blake/blake_small.h [new file with mode: 0644]
blake/memxor.c [new file with mode: 0644]
blake/memxor.h [new file with mode: 0644]
bmw/bmw_large.c [new file with mode: 0644]
bmw/bmw_large.h [new file with mode: 0644]
bmw/bmw_small-tinyasm.ps [new file with mode: 0644]
bmw/bmw_small.c [new file with mode: 0644]
bmw/bmw_small.h [new file with mode: 0644]
bmw/bmw_small_speed.c [new file with mode: 0644]
bmw/f0-opt-table.txt [new file with mode: 0644]
bmw/f0-opt-table2.txt [new file with mode: 0644]
bmw/memxor.c [new file with mode: 0644]
bmw/memxor.h [new file with mode: 0644]
cubehash/cubehash.c [new file with mode: 0644]
cubehash/cubehash.h [new file with mode: 0644]
cubehash/memxor.c [new file with mode: 0644]
cubehash/memxor.h [new file with mode: 0644]
echo/aes_enc_round.c [new file with mode: 0644]
echo/aes_enc_round.h [new file with mode: 0644]
echo/aes_sbox.c [new file with mode: 0644]
echo/aes_sbox.h [new file with mode: 0644]
echo/echo.c [new file with mode: 0644]
echo/echo.h [new file with mode: 0644]
echo/gf256mul.c [new file with mode: 0644]
echo/gf256mul.h [new file with mode: 0644]
echo/memxor.c [new file with mode: 0644]
echo/memxor.h [new file with mode: 0644]
gdb-debug [new file with mode: 0644]
gdb-flash [new file with mode: 0644]
groestl/aes_sbox.c [new file with mode: 0644]
groestl/aes_sbox.h [new file with mode: 0644]
groestl/gf256mul.c [new file with mode: 0644]
groestl/gf256mul.h [new file with mode: 0644]
groestl/groestl_large.c [new file with mode: 0644]
groestl/groestl_large.h [new file with mode: 0644]
groestl/groestl_small.c [new file with mode: 0644]
groestl/groestl_small.h [new file with mode: 0644]
groestl/memxor.c [new file with mode: 0644]
groestl/memxor.h [new file with mode: 0644]
hfal-basic.c [new file with mode: 0644]
hfal-basic.h [new file with mode: 0644]
hfal_blake_large.c [new file with mode: 0644]
hfal_blake_large.h [new file with mode: 0644]
hfal_blake_small.c [new file with mode: 0644]
hfal_blake_small.h [new file with mode: 0644]
hfal_bmw_large.c [new file with mode: 0644]
hfal_bmw_large.h [new file with mode: 0644]
hfal_bmw_small.c [new file with mode: 0644]
hfal_bmw_small.h [new file with mode: 0644]
hfal_cubehash.c [new file with mode: 0644]
hfal_cubehash.h [new file with mode: 0644]
hfal_echo.c [new file with mode: 0644]
hfal_echo.h [new file with mode: 0644]
hfal_groestl_large.c [new file with mode: 0644]
hfal_groestl_large.h [new file with mode: 0644]
hfal_groestl_small.c [new file with mode: 0644]
hfal_groestl_small.h [new file with mode: 0644]
hfal_keccak.c [new file with mode: 0644]
hfal_keccak.h [new file with mode: 0644]
hfal_md5.c [new file with mode: 0644]
hfal_md5.h [new file with mode: 0644]
hfal_sha1.c [new file with mode: 0644]
hfal_sha1.h [new file with mode: 0644]
hfal_sha256.c [new file with mode: 0644]
hfal_sha256.h [new file with mode: 0644]
hfal_shabal.c [new file with mode: 0644]
hfal_shabal.h [new file with mode: 0644]
hfal_skein1024.c [new file with mode: 0644]
hfal_skein1024.h [new file with mode: 0644]
hfal_skein256.c [new file with mode: 0644]
hfal_skein256.h [new file with mode: 0644]
hfal_skein512.c [new file with mode: 0644]
hfal_skein512.h [new file with mode: 0644]
host/bigint_test.rb [new file with mode: 0644]
host/bitslice2asm.rb [new file with mode: 0644]
host/cmacvs_test.rb [new file with mode: 0644]
host/create-algo-impl-relation.rb [new file with mode: 0644]
host/data2wiki.rb [new file with mode: 0644]
host/find_tv.rb [new file with mode: 0644]
host/fix-wiki-size.rb [new file with mode: 0644]
host/gcdext-test.rb [new file with mode: 0644]
host/get_performance.rb [new file with mode: 0644]
host/get_primes.rb [new file with mode: 0644]
host/get_test.rb [new file with mode: 0644]
host/karatsuba.rb [new file with mode: 0644]
host/nessie_check.rb [new file with mode: 0644]
host/optimize_shift.rb [new file with mode: 0644]
host/shavs_test2.rb [new file with mode: 0644]
host/test.rb [new file with mode: 0644]
host/threefish_helper.rb [new file with mode: 0644]
host/threefish_helper_rc.rb [new file with mode: 0644]
keccak/keccak.c [new file with mode: 0644]
keccak/keccak.h [new file with mode: 0644]
keccak/memxor.c [new file with mode: 0644]
keccak/memxor.h [new file with mode: 0644]
md5/md5.c [new file with mode: 0644]
md5/md5.h [new file with mode: 0644]
md5/md5_sbox.h [new file with mode: 0644]
mkfiles/001_bcal_std.mk [new file with mode: 0644]
mkfiles/001_cli_std.mk [new file with mode: 0644]
mkfiles/001_hfal_std.mk [new file with mode: 0644]
mkfiles/blake_c.mk [new file with mode: 0644]
mkfiles/bmw_c.mk [new file with mode: 0644]
mkfiles/bmw_c_speed.mk [new file with mode: 0644]
mkfiles/cubehash_c.mk [new file with mode: 0644]
mkfiles/echo_c.mk [new file with mode: 0644]
mkfiles/groestl_c.mk [new file with mode: 0644]
mkfiles/keccak_c.mk [new file with mode: 0644]
mkfiles/sha1_c.mk [new file with mode: 0644]
mkfiles/sha256_c.mk [new file with mode: 0644]
mkfiles/shabal_c.mk [new file with mode: 0644]
mkfiles/skein_c.mk [new file with mode: 0644]
openocd.cfg [new file with mode: 0644]
sha1/sha1.c [new file with mode: 0644]
sha1/sha1.h [new file with mode: 0644]
sha256/sha256.c [new file with mode: 0644]
sha256/sha256.h [new file with mode: 0644]
shabal/shabal.c [new file with mode: 0644]
shabal/shabal.h [new file with mode: 0644]
shabal/shabal192.c [new file with mode: 0644]
shabal/shabal224.c [new file with mode: 0644]
shabal/shabal256.c [new file with mode: 0644]
shabal/shabal384.c [new file with mode: 0644]
shabal/shabal512.c [new file with mode: 0644]
shabal/shabal_shorttest.log.ps [new file with mode: 0644]
skein/memxor.c [new file with mode: 0644]
skein/memxor.h [new file with mode: 0644]
skein/skein.h [new file with mode: 0644]
skein/skein1024.c [new file with mode: 0644]
skein/skein256.c [new file with mode: 0644]
skein/skein512.c [new file with mode: 0644]
skein/skein_algo_list.txt [new file with mode: 0644]
skein/threefish.h [new file with mode: 0644]
skein/threefish1024_dec.c [new file with mode: 0644]
skein/threefish1024_enc.c [new file with mode: 0644]
skein/threefish256_dec.c [new file with mode: 0644]
skein/threefish256_enc.c [new file with mode: 0644]
skein/threefish512_dec.c [new file with mode: 0644]
skein/threefish512_enc.c [new file with mode: 0644]
skein/threefish_invmix_c.c [new file with mode: 0644]
skein/threefish_mix_c.c [new file with mode: 0644]
skein/ubi.h [new file with mode: 0644]
skein/ubi1024.c [new file with mode: 0644]
skein/ubi256.c [new file with mode: 0644]
skein/ubi512.c [new file with mode: 0644]
test_src/circularbytebuffer.c [new file with mode: 0644]
test_src/circularbytebuffer.h [new file with mode: 0644]
test_src/cli-basics.o [new file with mode: 0644]
test_src/cli-core.o [new file with mode: 0644]
test_src/cli-hexdump.o [new file with mode: 0644]
test_src/cli.c [new file with mode: 0644]
test_src/cli.h [new file with mode: 0644]
test_src/config.h [new file with mode: 0644]
test_src/dbz_strings.c [new file with mode: 0644]
test_src/dbz_strings.h [new file with mode: 0644]
test_src/dump-decl.c [new file with mode: 0644]
test_src/dump.c [new file with mode: 0644]
test_src/dump.h [new file with mode: 0644]
test_src/hexdigit_tab.S [new file with mode: 0644]
test_src/hexdigit_tab.h [new file with mode: 0644]
test_src/hexdigit_tab_c.c [new file with mode: 0644]
test_src/hw_gptm.c [new file with mode: 0644]
test_src/hw_gptm.h [new file with mode: 0644]
test_src/hw_regs.h [new file with mode: 0644]
test_src/hw_uart.h [new file with mode: 0644]
test_src/hw_uart_regs.h [new file with mode: 0644]
test_src/nessie_common.c [new file with mode: 0644]
test_src/nessie_common.h [new file with mode: 0644]
test_src/nessie_hash_test.c [new file with mode: 0644]
test_src/nessie_hash_test.h [new file with mode: 0644]
test_src/performance_test.c [new file with mode: 0644]
test_src/performance_test.h [new file with mode: 0644]
test_src/setbaud_asm.inc [new file with mode: 0644]
test_src/shavs.c [new file with mode: 0644]
test_src/shavs.h [new file with mode: 0644]
test_src/startup.c [new file with mode: 0644]
test_src/string-extras.c [new file with mode: 0644]
test_src/string-extras.h [new file with mode: 0644]
test_src/sysclock.c [new file with mode: 0644]
test_src/sysclock.h [new file with mode: 0644]
test_src/sysclock.o [new file with mode: 0644]
test_src/testport.conf [new file with mode: 0644]
test_src/uart_defines.h [new file with mode: 0644]
test_src/uart_i.c [new file with mode: 0644]
test_src/uart_i.h [new file with mode: 0644]
test_src/uart_lowlevel.c [new file with mode: 0644]
test_src/uart_lowlevel.h [new file with mode: 0644]

diff --git a/blake/blake_common.c b/blake/blake_common.c
new file mode 100644 (file)
index 0000000..6e0d6de
--- /dev/null
@@ -0,0 +1,61 @@
+/* blake_common.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    blake_common.c
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-05-08
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+
+const
+uint8_t blake_sigma[] = {
+   0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF,
+   0xE, 0xA, 0x4, 0x8, 0x9, 0xF, 0xD, 0x6, 0x1, 0xC, 0x0, 0x2, 0xB, 0x7, 0x5, 0x3,
+   0xB, 0x8, 0xC, 0x0, 0x5, 0x2, 0xF, 0xD, 0xA, 0xE, 0x3, 0x6, 0x7, 0x1, 0x9, 0x4,
+   0x7, 0x9, 0x3, 0x1, 0xD, 0xC, 0xB, 0xE, 0x2, 0x6, 0x5, 0xA, 0x4, 0x0, 0xF, 0x8,
+   0x9, 0x0, 0x5, 0x7, 0x2, 0x4, 0xA, 0xF, 0xE, 0x1, 0xB, 0xC, 0x6, 0x8, 0x3, 0xD,
+   0x2, 0xC, 0x6, 0xA, 0x0, 0xB, 0x8, 0x3, 0x4, 0xD, 0x7, 0x5, 0xF, 0xE, 0x1, 0x9,
+   0xC, 0x5, 0x1, 0xF, 0xE, 0xD, 0x4, 0xA, 0x0, 0x7, 0x6, 0x3, 0x9, 0x2, 0x8, 0xB,
+   0xD, 0xB, 0x7, 0xE, 0xC, 0x1, 0x3, 0x9, 0x5, 0x0, 0xF, 0x4, 0x8, 0x6, 0x2, 0xA,
+   0x6, 0xF, 0xE, 0x9, 0xB, 0x3, 0x0, 0x8, 0xC, 0x2, 0xD, 0x7, 0x1, 0x4, 0xA, 0x5,
+   0xA, 0x2, 0x8, 0x4, 0x7, 0x6, 0x1, 0x5, 0xF, 0xB, 0x9, 0xE, 0x3, 0xC, 0xD, 0x0,
+/* the following lines are for large blake (blake48 & blake64) */
+   0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF,
+   0xE, 0xA, 0x4, 0x8, 0x9, 0xF, 0xD, 0x6, 0x1, 0xC, 0x0, 0x2, 0xB, 0x7, 0x5, 0x3,
+   0xB, 0x8, 0xC, 0x0, 0x5, 0x2, 0xF, 0xD, 0xA, 0xE, 0x3, 0x6, 0x7, 0x1, 0x9, 0x4,
+   0x7, 0x9, 0x3, 0x1, 0xD, 0xC, 0xB, 0xE, 0x2, 0x6, 0x5, 0xA, 0x4, 0x0, 0xF, 0x8
+};
+
+const
+uint8_t blake_index_lut[] = {
+       0x0, 0x4, 0x8, 0xC,
+       0x1, 0x5, 0x9, 0xD,
+       0x2, 0x6, 0xA, 0xE,
+       0x3, 0x7, 0xB, 0xF,
+       0x0, 0x5, 0xA, 0xF,
+       0x1, 0x6, 0xB, 0xC,
+       0x2, 0x7, 0x8, 0xD,
+       0x3, 0x4, 0x9, 0xE
+};
+
+
diff --git a/blake/blake_common.h b/blake/blake_common.h
new file mode 100644 (file)
index 0000000..0623d1b
--- /dev/null
@@ -0,0 +1,37 @@
+/* blake_common.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    blake_common.h
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-05-08
+ * \license GPLv3 or later
+ * 
+ */
+
+
+#ifndef BLAKE_COMMON_H_
+#define BLAKE_COMMON_H_
+
+#include <stdint.h>
+
+extern const uint8_t blake_sigma[];
+extern const uint8_t blake_index_lut[];
+
+#endif /* BLAKE_COMMON_H_ */
diff --git a/blake/blake_large.c b/blake/blake_large.c
new file mode 100644 (file)
index 0000000..15eb680
--- /dev/null
@@ -0,0 +1,258 @@
+/* blake_large.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    blake_large.c
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-05-08
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "memxor.h"
+#include "blake_large.h"
+#include "blake_common.h"
+
+static const
+uint64_t blake_c[]  = {
+   0x243F6A8885A308D3LL, 0x13198A2E03707344LL,
+   0xA4093822299F31D0LL, 0x082EFA98EC4E6C89LL,
+   0x452821E638D01377LL, 0xBE5466CF34E90C6CLL,
+   0xC0AC29B7C97C50DDLL, 0x3F84D5B5B5470917LL,
+   0x9216D5D98979FB1BLL, 0xD1310BA698DFB5ACLL,
+   0x2FFD72DBD01ADFB7LL, 0xB8E1AFED6A267E96LL,
+   0xBA7C9045F12C7F99LL, 0x24A19947B3916CF7LL,
+   0x0801F2E2858EFC16LL, 0x636920D871574E69LL
+};
+
+
+
+#define ROTL64(a, n) (((a)<<(n))|((a)>>(64-(n))))
+#define ROTR64(a, n) (((a)>>(n))|((a)<<(64-(n))))
+#define CHANGE_ENDIAN32(a) (((a)<<24)| \
+                            ((0x0000ff00&(a))<<8)| \
+                                                   ((0x00ff0000&(a))>>8)| \
+                                                   (a)>>24 )
+
+static
+void blake_large_expand(uint64_t* v, const blake_large_ctx_t* ctx){
+       uint8_t i;
+       memcpy(v, ctx->h, 8*8);
+       for(i=0; i<8; ++i){
+               v[8+i] = blake_c[i];
+       }
+       memxor((uint8_t*)v+8, ctx->s, 4*8);
+
+}
+
+static
+void blake_large_changeendian(void* dest, const void* src){
+       uint8_t i;
+       uint32_t tmp;
+       for(i=0; i<32; i+=2){
+               tmp = CHANGE_ENDIAN32(((uint32_t*)src)[i]);
+               ((uint32_t*)dest)[i] = CHANGE_ENDIAN32(((uint32_t*)src)[i+1]);
+               ((uint32_t*)dest)[i+1] = tmp;
+       }
+}
+
+#define A (v[idx.v8[0]])
+#define B (v[idx.v8[1]])
+#define C (v[idx.v8[2]])
+#define D (v[idx.v8[3]])
+
+static
+void blake_large_compress(uint64_t* v,const void* m){
+       uint8_t r,i;
+       uint8_t s0, s1;
+       union {
+               uint32_t v32;
+               uint8_t v8[4];
+       }idx;
+       for(r=0; r<14; ++r){
+               for(i=0; i<8; ++i){
+                       idx.v32 = ((uint32_t*)blake_index_lut)[i];
+                       s0 = blake_sigma[16*r+2*i+0];
+                       s1 = blake_sigma[16*r+2*i+1];
+                       A += B + (((uint64_t*)m)[s0] ^ blake_c[s1]);
+                       D  = ROTR64(D^A, 32);
+                       C += D;
+                       B  = ROTR64(B^C, 25);
+                       A += B + (((uint64_t*)m)[s1] ^ blake_c[s0]);
+                       D  = ROTR64(D^A, 16);
+                       C += D;
+                       B  = ROTR64(B^C, 11);
+               }
+       }
+}
+
+static
+void blake_large_collapse(blake_large_ctx_t* ctx, uint64_t* v){
+       uint8_t i;
+       for(i=0; i<8; ++i){
+               ctx->h[i] ^= ctx->s[i%4] ^ v[i] ^ v[8+i];
+       }
+}
+
+void blake_large_nextBlock(blake_large_ctx_t* ctx, const void* msg){
+       uint64_t v[16];
+       uint64_t m[16];
+       union {
+               uint64_t v64;
+               uint32_t v32[2];
+       }ctr;
+       blake_large_expand(v,ctx);
+       ctx->counter++;
+       ctr.v64 = ctx->counter*1024;
+       v[12] ^= ctr.v64;
+       v[13] ^= ctr.v64;
+       blake_large_changeendian(m, msg);
+       blake_large_compress(v, m);
+       blake_large_collapse(ctx, v);
+}
+
+void blake_large_lastBlock(blake_large_ctx_t* ctx, const void* msg, uint16_t length_b){
+       while(length_b>=BLAKE_LARGE_BLOCKSIZE){
+               blake_large_nextBlock(ctx, msg);
+               msg = (uint8_t*)msg + BLAKE_LARGE_BLOCKSIZE_B;
+               length_b -= BLAKE_LARGE_BLOCKSIZE;
+       }
+       uint8_t buffer[128];
+       uint64_t v[16];
+       uint64_t ctr;
+       ctr = ctx->counter*1024+length_b;
+       memset(buffer, 0, 128);
+       memcpy(buffer, msg, (length_b+7)/8);
+       buffer[length_b/8] |= 0x80 >> (length_b&0x7);
+       blake_large_changeendian(buffer, buffer);
+       blake_large_expand(v, ctx);
+       if(length_b>1024-128-2){
+               v[12] ^= ctr;
+               v[13] ^= ctr;
+               blake_large_compress(v, buffer);
+               blake_large_collapse(ctx, v);
+               memset(buffer, 0, 128-8);
+               blake_large_expand(v, ctx);
+       } else {
+               if(length_b){
+                       v[12] ^= ctr;
+                       v[13] ^= ctr;
+               }
+       }
+       if(ctx->appendone)
+               buffer[128-16-8] |= 0x01;
+       *((uint64_t*)(&(buffer[128-8]))) = ctr;
+       blake_large_compress(v, buffer);
+       blake_large_collapse(ctx, v);
+
+}
+
+static const
+uint64_t blake64_iv[] = {
+    0x6A09E667F3BCC908LL, 0xBB67AE8584CAA73BLL,
+    0x3C6EF372FE94F82BLL, 0xA54FF53A5F1D36F1LL,
+    0x510E527FADE682D1LL, 0x9B05688C2B3E6C1FLL,
+    0x1F83D9ABFB41BD6BLL, 0x5BE0CD19137E2179LL
+};
+
+void blake64_init(blake64_ctx_t* ctx){
+       uint8_t i;
+       for(i=0; i<8; ++i){
+               ctx->h[i] = blake64_iv[i];
+       }
+       memset(ctx->s, 0, 4*8);
+       ctx->counter = 0;
+       ctx->appendone = 1;
+}
+
+static const
+uint64_t blake48_iv[] = {
+    0xCBBB9D5DC1059ED8LL, 0x629A292A367CD507LL,
+    0x9159015A3070DD17LL, 0x152FECD8F70E5939LL,
+    0x67332667FFC00B31LL, 0x8EB44A8768581511LL,
+    0xDB0C2E0D64F98FA7LL, 0x47B5481DBEFA4FA4LL
+};
+
+void blake48_init(blake48_ctx_t* ctx){
+       uint8_t i;
+       for(i=0; i<8; ++i){
+               ctx->h[i] = blake48_iv[i];
+       }
+       memset(ctx->s, 0, 4*8);
+       ctx->counter = 0;
+       ctx->appendone = 0;
+}
+
+void blake64_ctx2hash(void* dest, const blake64_ctx_t* ctx){
+       uint8_t i;
+       for(i=0; i<8; ++i){
+               ((uint32_t*)dest)[2*i+0] = CHANGE_ENDIAN32((ctx->h[i])>>32);
+               ((uint32_t*)dest)[2*i+1] = CHANGE_ENDIAN32((uint32_t)ctx->h[i]);
+       }
+}
+
+void blake48_ctx2hash(void* dest, const blake48_ctx_t* ctx){
+       uint8_t i;
+       for(i=0; i<6; ++i){
+               ((uint32_t*)dest)[2*i+0] = CHANGE_ENDIAN32((ctx->h[i])>>32);
+               ((uint32_t*)dest)[2*i+1] = CHANGE_ENDIAN32((uint32_t)ctx->h[i]);
+       }
+}
+
+void blake64_nextBlock(blake64_ctx_t* ctx, const void* block){
+       blake_large_nextBlock(ctx, block);
+}
+
+void blake48_nextBlock(blake48_ctx_t* ctx, const void* block){
+       blake_large_nextBlock(ctx, block);
+}
+
+void blake64_lastBlock(blake64_ctx_t* ctx, const void* block, uint16_t length_b){
+       blake_large_lastBlock(ctx, block, length_b);
+}
+
+void blake48_lastBlock(blake48_ctx_t* ctx, const void* block, uint16_t length_b){
+       blake_large_lastBlock(ctx, block, length_b);
+}
+
+void blake64(void* dest, const void* msg, uint32_t length_b){
+       blake_large_ctx_t ctx;
+       blake64_init(&ctx);
+       while(length_b>=BLAKE_LARGE_BLOCKSIZE){
+               blake_large_nextBlock(&ctx, msg);
+               msg = (uint8_t*)msg + BLAKE_LARGE_BLOCKSIZE_B;
+               length_b -= BLAKE_LARGE_BLOCKSIZE;
+       }
+       blake_large_lastBlock(&ctx, msg, length_b);
+       blake64_ctx2hash(dest, &ctx);
+}
+
+void blake48(void* dest, const void* msg, uint32_t length_b){
+       blake_large_ctx_t ctx;
+       blake48_init(&ctx);
+       while(length_b>=BLAKE_LARGE_BLOCKSIZE){
+               blake_large_nextBlock(&ctx, msg);
+               msg = (uint8_t*)msg + BLAKE_LARGE_BLOCKSIZE_B;
+               length_b -= BLAKE_LARGE_BLOCKSIZE;
+       }
+       blake_large_lastBlock(&ctx, msg, length_b);
+       blake48_ctx2hash(dest, &ctx);
+}
diff --git a/blake/blake_large.h b/blake/blake_large.h
new file mode 100644 (file)
index 0000000..3556f2c
--- /dev/null
@@ -0,0 +1,67 @@
+/* blake_large.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    blake_large.h
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-05-08
+ * \license GPLv3 or later
+ * 
+ */
+#ifndef BLAKE_LARGE_H_
+#define BLAKE_LARGE_H_
+
+#include <stdint.h>
+
+#define BLAKE_LARGE_BLOCKSIZE   1024
+#define BLAKE_LARGE_BLOCKSIZE_B ((BLAKE_LARGE_BLOCKSIZE+7)/8)
+#define BLAKE48_BLOCKSIZE      BLAKE_LARGE_BLOCKSIZE
+#define BLAKE48_BLOCKSIZE_B    BLAKE_LARGE_BLOCKSIZE_B
+#define BLAKE64_BLOCKSIZE      BLAKE_LARGE_BLOCKSIZE
+#define BLAKE64_BLOCKSIZE_B    BLAKE_LARGE_BLOCKSIZE_B
+
+typedef struct {
+       uint64_t h[8];
+       uint64_t s[4];
+       uint32_t counter;
+       uint8_t  appendone;
+} blake_large_ctx_t;
+
+typedef blake_large_ctx_t blake48_ctx_t;
+typedef blake_large_ctx_t blake64_ctx_t;
+
+void blake48_init(blake48_ctx_t* ctx);
+void blake64_init(blake64_ctx_t* ctx);
+
+void blake_large_nextBlock(blake_large_ctx_t* ctx, const void* block);
+void blake_large_lastBlock(blake_large_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void blake48_nextBlock(blake48_ctx_t* ctx, const void* block);
+void blake48_lastBlock(blake48_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void blake64_nextBlock(blake64_ctx_t* ctx, const void* block);
+void blake64_lastBlock(blake64_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void blake48_ctx2hash(void* dest, const blake48_ctx_t* ctx);
+void blake64_ctx2hash(void* dest, const blake64_ctx_t* ctx);
+
+void blake48(void* dest, const void* msg, uint32_t length_b);
+void blake64(void* dest, const void* msg, uint32_t length_b);
+
+#endif /* BLAKE_LARGE_H_ */
diff --git a/blake/blake_small.c b/blake/blake_small.c
new file mode 100644 (file)
index 0000000..bdf70cb
--- /dev/null
@@ -0,0 +1,260 @@
+/* blake_small.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    blake_small.c
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-05-04
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "memxor.h"
+#include "blake_small.h"
+#include "blake_common.h"
+
+static const
+uint32_t blake_c[] = {
+   0x243F6A88, 0x85A308D3,
+   0x13198A2E, 0x03707344,
+   0xA4093822, 0x299F31D0,
+   0x082EFA98, 0xEC4E6C89,
+   0x452821E6, 0x38D01377,
+   0xBE5466CF, 0x34E90C6C,
+   0xC0AC29B7, 0xC97C50DD,
+   0x3F84D5B5, 0xB5470917
+};
+
+#define ROTL32(a, n) (((a)<<(n))|((a)>>(32-(n))))
+#define ROTR32(a, n) (((a)>>(n))|((a)<<(32-(n))))
+#define CHANGE_ENDIAN32(a) (((a)<<24)| \
+                            ((0x0000ff00&(a))<<8)| \
+                                                   ((0x00ff0000&(a))>>8)| \
+                                                   (a)>>24 )
+static
+void blake_small_expand(uint32_t* v, const blake_small_ctx_t* ctx){
+       uint8_t i;
+       memcpy(v, ctx->h, 8*4);
+       for(i=0; i<8; ++i){
+               v[8+i] = blake_c[i];
+       }
+       memxor((uint8_t*)v+8, ctx->s, 4*4);
+
+}
+
+static
+void blake_small_changeendian(void* dest, const void* src){
+       uint8_t i;
+       for(i=0; i<16; ++i){
+               ((uint32_t*)dest)[i] = CHANGE_ENDIAN32(((uint32_t*)src)[i]);
+       }
+}
+
+#define A (v[idx.v8[0]])
+#define B (v[idx.v8[1]])
+#define C (v[idx.v8[2]])
+#define D (v[idx.v8[3]])
+
+static
+void blake_small_compress(uint32_t* v,const void* m){
+       uint8_t r,i;
+       uint8_t s0, s1;
+       union {
+               uint32_t v32;
+               uint8_t v8[4];
+       } idx;
+       for(r=0; r<10; ++r){
+               for(i=0; i<8; ++i){
+                       idx.v32 = ((uint32_t*)blake_index_lut)[i];
+                       s0 = blake_sigma[16*r+2*i+0];
+                       s1 = blake_sigma[16*r+2*i+1];
+                       A += B + (((uint32_t*)m)[s0] ^ blake_c[s1]);
+                       D  = ROTR32(A^D, 16);
+                       C += D;
+                       B  = ROTR32(B^C, 12);
+                       A += B + (((uint32_t*)m)[s1] ^ blake_c[s0]);
+                       D  = ROTR32(A^D, 8);
+                       C += D;
+                       B  = ROTR32(B^C, 7);
+               }
+       }
+}
+
+static
+void blake_small_collapse(blake_small_ctx_t* ctx, uint32_t* v){
+       uint8_t i;
+       for(i=0; i<8; ++i){
+               ctx->h[i] ^= ctx->s[i%4] ^ v[i] ^ v[8+i];
+       }
+}
+
+void blake_small_nextBlock(blake_small_ctx_t* ctx, const void* msg){
+       uint32_t v[16];
+       uint32_t m[16];
+       union {
+               uint64_t v64;
+               uint32_t v32[2];
+       }ctr;
+       blake_small_expand(v,ctx);
+       ctx->counter++;
+       ctr.v64 = ctx->counter*512;
+       v[12] ^= ctr.v32[0];
+       v[13] ^= ctr.v32[0];
+       v[14] ^= ctr.v32[1];
+       v[15] ^= ctr.v32[1];
+       blake_small_changeendian(m, msg);
+       blake_small_compress(v, m);
+       blake_small_collapse(ctx, v);
+}
+
+void blake_small_lastBlock(blake_small_ctx_t* ctx, const void* msg, uint16_t length_b){
+       while(length_b>=BLAKE_SMALL_BLOCKSIZE){
+               blake_small_nextBlock(ctx, msg);
+               msg = (uint8_t*)msg + BLAKE_SMALL_BLOCKSIZE_B;
+               length_b -= BLAKE_SMALL_BLOCKSIZE;
+       }
+       uint8_t buffer[64];
+       uint32_t v[16];
+       union {
+               uint64_t v64;
+               uint32_t v32[2];
+       }ctr;
+       ctr.v64 = ctx->counter*512+length_b;
+       memset(buffer, 0, 64);
+       memcpy(buffer, msg, (length_b+7)/8);
+       buffer[length_b/8] |= 0x80 >> (length_b&0x7);
+       blake_small_changeendian(buffer, buffer);
+       blake_small_expand(v, ctx);
+       if(length_b>512-64-2){
+               v[12] ^= ctr.v32[0];
+               v[13] ^= ctr.v32[0];
+               v[14] ^= ctr.v32[1];
+               v[15] ^= ctr.v32[1];
+               blake_small_compress(v, buffer);
+               blake_small_collapse(ctx, v);
+               memset(buffer, 0, 64-8);
+               blake_small_expand(v, ctx);
+       }else{
+               if(length_b){
+                       v[12] ^= ctr.v32[0];
+                       v[13] ^= ctr.v32[0];
+                       v[14] ^= ctr.v32[1];
+                       v[15] ^= ctr.v32[1];
+               }
+       }
+       if(ctx->appendone)
+               buffer[64-8-4] |= 0x01;
+       *((uint32_t*)(&(buffer[64-8]))) = ctr.v32[1];
+       *((uint32_t*)(&(buffer[64-4]))) = ctr.v32[0];
+       blake_small_compress(v, buffer);
+       blake_small_collapse(ctx, v);
+
+}
+
+static const
+uint32_t blake32_iv[] = {
+       0x6A09E667L, 0xBB67AE85,
+       0x3C6EF372L, 0xA54FF53A,
+       0x510E527FL, 0x9B05688C,
+       0x1F83D9ABL, 0x5BE0CD19
+};
+
+void blake32_init(blake32_ctx_t* ctx){
+       uint8_t i;
+       for(i=0; i<8; ++i){
+               ctx->h[i] = blake32_iv[i];
+       }
+       memset(ctx->s, 0, 4*4);
+       ctx->counter = 0;
+       ctx->appendone = 1;
+}
+
+static const
+uint32_t blake28_iv[] = {
+       0xC1059ED8, 0x367CD507,
+       0x3070DD17, 0xF70E5939,
+       0xFFC00B31, 0x68581511,
+       0x64F98FA7, 0xBEFA4FA4
+};
+
+void blake28_init(blake28_ctx_t* ctx){
+       uint8_t i;
+       for(i=0; i<8; ++i){
+               ctx->h[i] = blake28_iv[i];
+       }
+       memset(ctx->s, 0, 4*4);
+       ctx->counter = 0;
+       ctx->appendone = 0;
+}
+
+void blake32_ctx2hash(void* dest, const blake32_ctx_t* ctx){
+       uint8_t i;
+       for(i=0; i<8; ++i){
+               ((uint32_t*)dest)[i] = CHANGE_ENDIAN32(ctx->h[i]);
+       }
+}
+
+void blake28_ctx2hash(void* dest, const blake28_ctx_t* ctx){
+       uint8_t i;
+       for(i=0; i<7; ++i){
+               ((uint32_t*)dest)[i] = CHANGE_ENDIAN32(ctx->h[i]);
+       }
+}
+
+void blake32_nextBlock(blake32_ctx_t* ctx, const void* block){
+       blake_small_nextBlock(ctx, block);
+}
+
+void blake28_nextBlock(blake28_ctx_t* ctx, const void* block){
+       blake_small_nextBlock(ctx, block);
+}
+
+void blake32_lastBlock(blake32_ctx_t* ctx, const void* block, uint16_t length_b){
+       blake_small_lastBlock(ctx, block, length_b);
+}
+
+void blake28_lastBlock(blake28_ctx_t* ctx, const void* block, uint16_t length_b){
+       blake_small_lastBlock(ctx, block, length_b);
+}
+
+void blake32(void* dest, const void* msg, uint32_t length_b){
+       blake_small_ctx_t ctx;
+       blake32_init(&ctx);
+       while(length_b>=BLAKE_SMALL_BLOCKSIZE){
+               blake_small_nextBlock(&ctx, msg);
+               msg = (uint8_t*)msg + BLAKE_SMALL_BLOCKSIZE_B;
+               length_b -= BLAKE_SMALL_BLOCKSIZE;
+       }
+       blake_small_lastBlock(&ctx, msg, length_b);
+       blake32_ctx2hash(dest, &ctx);
+}
+
+void blake28(void* dest, const void* msg, uint32_t length_b){
+       blake_small_ctx_t ctx;
+       blake28_init(&ctx);
+       while(length_b>=BLAKE_SMALL_BLOCKSIZE){
+               blake_small_nextBlock(&ctx, msg);
+               msg = (uint8_t*)msg + BLAKE_SMALL_BLOCKSIZE_B;
+               length_b -= BLAKE_SMALL_BLOCKSIZE;
+       }
+       blake_small_lastBlock(&ctx, msg, length_b);
+       blake28_ctx2hash(dest, &ctx);
+}
diff --git a/blake/blake_small.h b/blake/blake_small.h
new file mode 100644 (file)
index 0000000..9502344
--- /dev/null
@@ -0,0 +1,67 @@
+/* blake_small.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    blake_small.h
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-04-27
+ * \license GPLv3 or later
+ * 
+ */
+#ifndef BLAKE_SMALL_H_
+#define BLAKE_SMALL_H_
+
+#include <stdint.h>
+
+#define BLAKE_SMALL_BLOCKSIZE   512
+#define BLAKE_SMALL_BLOCKSIZE_B ((BLAKE_SMALL_BLOCKSIZE+7)/8)
+#define BLAKE28_BLOCKSIZE      BLAKE_SMALL_BLOCKSIZE
+#define BLAKE28_BLOCKSIZE_B    BLAKE_SMALL_BLOCKSIZE_B
+#define BLAKE32_BLOCKSIZE      BLAKE_SMALL_BLOCKSIZE
+#define BLAKE32_BLOCKSIZE_B    BLAKE_SMALL_BLOCKSIZE_B
+
+typedef struct {
+       uint32_t h[8];
+       uint32_t s[4];
+       uint32_t counter;
+       uint8_t  appendone;
+} blake_small_ctx_t;
+
+typedef blake_small_ctx_t blake28_ctx_t;
+typedef blake_small_ctx_t blake32_ctx_t;
+
+void blake28_init(blake28_ctx_t* ctx);
+void blake32_init(blake32_ctx_t* ctx);
+
+void blake_small_nextBlock(blake_small_ctx_t* ctx, const void* block);
+void blake_small_lastBlock(blake_small_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void blake28_nextBlock(blake28_ctx_t* ctx, const void* block);
+void blake28_lastBlock(blake28_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void blake32_nextBlock(blake32_ctx_t* ctx, const void* block);
+void blake32_lastBlock(blake32_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void blake28_ctx2hash(void* dest, const blake28_ctx_t* ctx);
+void blake32_ctx2hash(void* dest, const blake32_ctx_t* ctx);
+
+void blake28(void* dest, const void* msg, uint32_t length_b);
+void blake32(void* dest, const void* msg, uint32_t length_b);
+
+#endif /* BLAKE_SMALL_H_ */
diff --git a/blake/memxor.c b/blake/memxor.c
new file mode 100644 (file)
index 0000000..7485b3e
--- /dev/null
@@ -0,0 +1,12 @@
+#include <stdint.h>
+
+#include "memxor.h"
+
+void memxor(void* dest, const void* src, uint16_t n){
+  while(n--){
+    *((uint8_t*)dest) ^= *((uint8_t*)src);
+    dest = (uint8_t*)dest +1;
+    src  = (uint8_t*)src  +1;
+  }
+}
+
diff --git a/blake/memxor.h b/blake/memxor.h
new file mode 100644 (file)
index 0000000..a62a616
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef MEMXOR_H_
+#define MEMXOR_H_
+#include <stdint.h>
+
+void memxor(void* dest, const void* src, uint16_t n);
+
+#endif
diff --git a/bmw/bmw_large.c b/bmw/bmw_large.c
new file mode 100644 (file)
index 0000000..85a5dee
--- /dev/null
@@ -0,0 +1,623 @@
+/* bmw_large.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    bmw_large.c
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-04-27
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "bmw_large.h"
+
+#define SHL64(a,n)  shiftl64(a,n)
+#define SHR64(a,n)  shiftr64(a,n)
+#define ROTL64(a,n) rotl64(a,n)
+#define ROTR64(a,n) rotr64(a,n)
+
+#define TWEAK   1
+#define BUG24   0
+#define F0_HACK 2
+#define DEBUG   0
+
+#if DEBUG
+ #include "cli.h"
+
+ void ctx_dump(const bmw_large_ctx_t* ctx){
+       uint8_t i;
+       cli_putstr("\r\n==== ctx dump ====");
+       for(i=0; i<16;++i){
+               cli_putstr("\r\n h[");
+               cli_hexdump(&i, 1);
+               cli_putstr("] = ");
+               cli_hexdump_rev(&(ctx->h[i]), 8);
+       }
+       cli_putstr("\r\n counter = ");
+       cli_hexdump(&(ctx->counter), 4);
+ }
+
+ void dump_x(const uint64_t* q, uint8_t elements, char x){
+       uint8_t i;
+       cli_putstr("\r\n==== ");
+       cli_putc(x);
+       cli_putstr(" dump ====");
+       for(i=0; i<elements;++i){
+               cli_putstr("\r\n ");
+               cli_putc(x);
+               cli_putstr("[");
+               cli_hexdump(&i, 1);
+               cli_putstr("] = ");
+               cli_hexdump_rev(&(q[i]), 8);
+       }
+ }
+#else
+ #define ctx_dump(x)
+ #define dump_x(a,b,c)
+#endif
+
+static
+uint64_t rotl64(uint64_t a, uint8_t r){
+       return (a<<r)|(a>>(64-r));
+}
+
+static
+uint64_t rotr64(uint64_t a, uint8_t r){
+       return (a>>r)|(a<<(64-r));
+}
+
+static
+uint64_t shiftl64(uint64_t a, uint8_t r){
+       return (a<<r);
+}
+
+static
+uint64_t shiftr64(uint64_t a, uint8_t r){
+       return (a>>r);
+}
+
+static
+uint64_t bmw_large_s0(uint64_t x){
+       uint64_t r;
+       r =   SHR64(x, 1)
+               ^ SHL64(x, 3)
+               ^ ROTL64(x, 4)
+               ^ ROTR64(x, 64-37);
+       return r;
+}
+
+static
+uint64_t bmw_large_s1(uint64_t x){
+       uint64_t r;
+       r =   SHR64(x, 1)
+               ^ SHL64(x, 2)
+               ^ ROTL64(x,13)
+               ^ ROTR64(x,64-43);
+       return r;
+}
+
+static
+uint64_t bmw_large_s2(uint64_t x){
+       uint64_t r;
+       r =   SHR64(x, 2)
+               ^ SHL64(x, 1)
+               ^ ROTL64(x, 19)
+               ^ ROTR64(x, 64-53);
+       return r;
+}
+
+static
+uint64_t bmw_large_s3(uint64_t x){
+       uint64_t r;
+       r =   SHR64(x, 2)
+               ^ SHL64(x, 2)
+               ^ ROTL64(x, 28)
+               ^ ROTR64(x, 64-59);
+       return r;
+}
+
+static
+uint64_t bmw_large_s4(uint64_t x){
+       uint64_t r;
+       r =   SHR64(x, 1)
+               ^ x;
+       return r;
+}
+
+static
+uint64_t bmw_large_s5(uint64_t x){
+       uint64_t r;
+       r =   SHR64(x, 2)
+               ^ x;
+       return r;
+}
+
+static
+uint64_t bmw_large_r1(uint64_t x){
+       uint64_t r;
+       r =   ROTL64(x, 5);
+       return r;
+}
+
+static
+uint64_t bmw_large_r2(uint64_t x){
+       uint64_t r;
+       r =   ROTL64(x, 11);
+       return r;
+}
+
+static
+uint64_t bmw_large_r3(uint64_t x){
+       uint64_t r;
+       r =   ROTL64(x, 27);
+       return r;
+}
+
+static
+uint64_t bmw_large_r4(uint64_t x){
+       uint64_t r;
+       r =   ROTL64(x, 32);
+       return r;
+}
+
+static
+uint64_t bmw_large_r5(uint64_t x){
+       uint64_t r;
+       r =   ROTR64(x, 64-37);
+       return r;
+}
+
+static
+uint64_t bmw_large_r6(uint64_t x){
+       uint64_t r;
+       r =   ROTR64(x, 64-43);
+       return r;
+}
+
+static
+uint64_t bmw_large_r7(uint64_t x){
+       uint64_t r;
+       r =   ROTR64(x, 64-53);
+       return r;
+}
+/*
+#define K    0x0555555555555555LL
+#define MASK 0xFFFFFFFFFFFFFFFFLL
+static
+uint64_t k_lut[] PROGMEM = {
+       16LL*K, 17LL*K, 18LL*K, 19LL*K,
+       20LL*K, 21LL*K, 22LL*K, 23LL*K,
+       24LL*K, 25LL*K, 26LL*K, 27LL*K,
+       28LL*K, 29LL*K, 30LL*K, 31LL*K };
+*/
+/* the same as above but precomputed to avoid compiler warnings */
+static const
+uint64_t k_lut[] = {
+       0x5555555555555550LL, 0x5aaaaaaaaaaaaaa5LL, 0x5ffffffffffffffaLL,
+       0x655555555555554fLL, 0x6aaaaaaaaaaaaaa4LL, 0x6ffffffffffffff9LL,
+       0x755555555555554eLL, 0x7aaaaaaaaaaaaaa3LL, 0x7ffffffffffffff8LL,
+       0x855555555555554dLL, 0x8aaaaaaaaaaaaaa2LL, 0x8ffffffffffffff7LL,
+       0x955555555555554cLL, 0x9aaaaaaaaaaaaaa1LL, 0x9ffffffffffffff6LL,
+       0xa55555555555554bLL };
+
+static
+uint64_t bmw_large_expand1(uint8_t j, const uint64_t* q, const void* m, const void* h){
+       uint64_t(*s[])(uint64_t) = {bmw_large_s1, bmw_large_s2, bmw_large_s3, bmw_large_s0};
+       uint64_t a = 0;
+       union{
+               uint64_t v64;
+               uint32_t v32[2];
+       } r;
+       uint8_t i;
+       /* r = 0x0555555555555555LL*(j+16); */
+       r.v64 = k_lut[j];
+       for(i=0; i<16; ++i){
+               a += s[i%4](q[j+i]);
+       }
+#if TWEAK
+       a += (   ROTL64(((uint64_t*)m)[(j)&0xf],   ((j+ 0)&0xf)+1)
+              + ROTL64(((uint64_t*)m)[(j+3)&0xf], ((j+ 3)&0xf)+1)
+              + r.v64
+              - ROTL64(((uint64_t*)m)[(j+10)&0xf],((j+10)&0xf)+1)
+            ) ^ ((uint64_t*)h)[(j+7)&0xf];
+#else
+       a += ((uint64_t*)m)[j&0xf];
+       a += ((uint64_t*)m)[(j+3)&0xf];
+       a -= ((uint64_t*)m)[(j+10)&0xf];
+       a += r.v64;
+#endif
+       return a;
+}
+
+static
+uint64_t bmw_large_expand2(uint8_t j, const uint64_t* q, const void* m, const void* h){
+       uint64_t(*rf[])(uint64_t) = {bmw_large_r1, bmw_large_r2, bmw_large_r3,
+                                    bmw_large_r4, bmw_large_r5, bmw_large_r6,
+                                                            bmw_large_r7};
+       uint64_t a=0;
+       union{
+               uint64_t v64;
+               uint32_t v32[2];
+       } r;
+       uint8_t i;
+       /* r = 0x0555555555555555LL*(j+16); */
+       r.v64 = k_lut[j];
+       for(i=0; i<14; i+=2){
+               a += q[j+i];
+       }
+       for(i=0; i<14; i+=2){
+               a += rf[i/2](q[j+i+1]);
+       }
+#if TWEAK
+       a += bmw_large_s4(q[j+14]);
+       a += bmw_large_s5(q[j+15]);
+#else
+       a += bmw_large_s5(q[j+14]);
+       a += bmw_large_s4(q[j+15]);
+#endif
+#if TWEAK
+       /*
+       if(j==(22-16)){
+               uint64_t t;
+               cli_putstr("\n+++++++++ expand_2 ++++++++++++");
+               dump_x(&a, 1, 'a');
+               dump_x(&r, 1, 'r');
+               t=ROTL64(((uint64_t*)m)[j],   ((j+ 0)&0xf)+1);
+               dump_x(&t, 1, '0');
+               t=ROTL64(((uint64_t*)m)[j],   ((j+ 3)&0xf)+1);
+               dump_x(&t, 1, '0');
+               t=ROTL64(((uint64_t*)m)[j],   ((j+ 0)&0xf)+1);
+               dump_x(&t, 1, '0');
+
+       }
+       */
+       a += (   ROTL64(((uint64_t*)m)[(j)&0xf],   ((j+ 0)&0xf)+1)
+              + ROTL64(((uint64_t*)m)[(j+3)&0xf], ((j+ 3)&0xf)+1)
+              + r.v64
+              - ROTL64(((uint64_t*)m)[(j+10)&0xf],((j+10)&0xf)+1)
+            ) ^ ((uint64_t*)h)[(j+7)&0xf];
+#else
+       a += ((uint64_t*)m)[j&0xf];
+       a += ((uint64_t*)m)[(j+3)&0xf];
+       a -= ((uint64_t*)m)[(j+10)&0xf];
+       a += r.v64;
+#endif
+       return a;
+}
+
+#if F0_HACK==2
+/* to understand this implementation take a look at f0-opt-table.txt */
+static uint16_t hack_table[5] = { 0x0311, 0xDDB3, 0x2A79, 0x07AA, 0x51C2 };
+static uint8_t  offset_table[5]  = { 4+16, 6+16, 9+16, 12+16, 13+16 };
+
+
+static
+void bmw_large_f0(uint64_t* q, const uint64_t* h, const void* m){
+       uint16_t hack_reg;
+       uint8_t i,j,c;
+       uint64_t(*s[])(uint64_t)={ bmw_large_s0, bmw_large_s1, bmw_large_s2,
+                                  bmw_large_s3, bmw_large_s4 };
+       for(i=0; i<16; ++i){
+               ((uint64_t*)h)[i] ^= ((uint64_t*)m)[i];
+       }
+       dump_x(h, 16, 'T');
+       memset(q, 0, 8*16);
+       c=4;
+       do{
+               i=15;
+               j = offset_table[c];
+               hack_reg = hack_table[c];
+               do{
+                       if(hack_reg&1){
+                               q[i]-= h[j&15];
+                       }else{
+                               q[i]+= h[j&15];
+                       }
+                       --j;
+                       hack_reg>>= 1;
+               }while(i--!=0);
+       }while(c--!=0);
+       dump_x(q, 16, 'W');
+       for(i=0; i<16; ++i){
+               q[i] = s[i%5](q[i]);
+       }
+#if TWEAK
+       for(i=0; i<16; ++i){
+               ((uint64_t*)h)[i] ^= ((uint64_t*)m)[i];
+       }
+       for(i=0; i<16; ++i){
+               q[i] += h[(i+1)&0xf];
+       }
+#endif /* TWEAK */
+}
+#endif /* F0_HACK==2 */
+
+#if F0_HACK==1
+static
+uint8_t f0_lut[] PROGMEM ={
+        5<<1, ( 7<<1)+1, (10<<1)+0, (13<<1)+0, (14<<1)+0,
+        6<<1, ( 8<<1)+1, (11<<1)+0, (14<<1)+0, (15<<1)+1,
+        0<<1, ( 7<<1)+0, ( 9<<1)+0, (12<<1)+1, (15<<1)+0,
+        0<<1, ( 1<<1)+1, ( 8<<1)+0, (10<<1)+1, (13<<1)+0,
+        1<<1, ( 2<<1)+0, ( 9<<1)+0, (11<<1)+1, (14<<1)+1,
+        3<<1, ( 2<<1)+1, (10<<1)+0, (12<<1)+1, (15<<1)+0,
+        4<<1, ( 0<<1)+1, ( 3<<1)+1, (11<<1)+1, (13<<1)+0,
+        1<<1, ( 4<<1)+1, ( 5<<1)+1, (12<<1)+1, (14<<1)+1,
+        2<<1, ( 5<<1)+1, ( 6<<1)+1, (13<<1)+0, (15<<1)+1,
+        0<<1, ( 3<<1)+1, ( 6<<1)+0, ( 7<<1)+1, (14<<1)+0,
+        8<<1, ( 1<<1)+1, ( 4<<1)+1, ( 7<<1)+1, (15<<1)+0,
+        8<<1, ( 0<<1)+1, ( 2<<1)+1, ( 5<<1)+1, ( 9<<1)+0,
+        1<<1, ( 3<<1)+0, ( 6<<1)+1, ( 9<<1)+1, (10<<1)+0,
+        2<<1, ( 4<<1)+0, ( 7<<1)+0, (10<<1)+0, (11<<1)+0,
+        3<<1, ( 5<<1)+1, ( 8<<1)+0, (11<<1)+1, (12<<1)+1,
+       12<<1, ( 4<<1)+1, ( 6<<1)+1, ( 9<<1)+1, (13<<1)+0
+};
+
+static
+void bmw_large_f0(uint64_t* q, const uint64_t* h, const void* m){
+       uint8_t i,j=-1,v,sign,l=0;
+       uint64_t(*s[])(uint64_t)={ bmw_large_s0, bmw_large_s1, bmw_large_s2,
+                                  bmw_large_s3, bmw_large_s4 };
+       for(i=0; i<16; ++i){
+               ((uint64_t*)h)[i] ^= ((uint64_t*)m)[i];
+       }
+       dump_x(h, 16, 'T');
+//     memset(q, 0, 4*16);
+       for(i=0; i<5*16; ++i){
+               v = pgm_read_byte(f0_lut+i);
+               sign = v&1;
+               v >>=1;
+               if(i==l){
+                       j++;
+                       l+=5;
+                       q[j] = h[v];
+                       continue;
+               }
+               if(sign){
+                       q[j] -= h[v];
+               }else{
+                       q[j] += h[v];
+               }
+       }
+       dump_x(q, 16, 'W');
+       for(i=0; i<16; ++i){
+               q[i] = s[i%5](q[i]);
+       }
+#if TWEAK
+       for(i=0; i<16; ++i){
+               ((uint64_t*)h)[i] ^= ((uint64_t*)m)[i];
+       }
+       for(i=0; i<16; ++i){
+               q[i] += h[(i+1)&0xf];
+       }
+#endif /* TWEAK */
+}
+#endif /* F0_HACK==1 */
+
+#if F0_HACK==0
+static
+void bmw_large_f0(uint64_t* q, const uint64_t* h, const void* m){
+       uint8_t i;
+       uint64_t(*s[])(uint64_t)={ bmw_large_s0, bmw_large_s1, bmw_large_s2,
+                                  bmw_large_s3, bmw_large_s4 };
+       for(i=0; i<16; ++i){
+               ((uint64_t*)h)[i] ^= ((uint64_t*)m)[i];
+       }
+//     dump_x(t, 16, 'T');
+       q[ 0] = (h[ 5] - h[ 7] + h[10] + h[13] + h[14]);
+       q[ 1] = (h[ 6] - h[ 8] + h[11] + h[14] - h[15]);
+       q[ 2] = (h[ 0] + h[ 7] + h[ 9] - h[12] + h[15]);
+       q[ 3] = (h[ 0] - h[ 1] + h[ 8] - h[10] + h[13]);
+       q[ 4] = (h[ 1] + h[ 2] + h[ 9] - h[11] - h[14]);
+       q[ 5] = (h[ 3] - h[ 2] + h[10] - h[12] + h[15]);
+       q[ 6] = (h[ 4] - h[ 0] - h[ 3] - h[11] + h[13]);
+       q[ 7] = (h[ 1] - h[ 4] - h[ 5] - h[12] - h[14]);
+       q[ 8] = (h[ 2] - h[ 5] - h[ 6] + h[13] - h[15]);
+       q[ 9] = (h[ 0] - h[ 3] + h[ 6] - h[ 7] + h[14]);
+       q[10] = (h[ 8] - h[ 1] - h[ 4] - h[ 7] + h[15]);
+       q[11] = (h[ 8] - h[ 0] - h[ 2] - h[ 5] + h[ 9]);
+       q[12] = (h[ 1] + h[ 3] - h[ 6] - h[ 9] + h[10]);
+       q[13] = (h[ 2] + h[ 4] + h[ 7] + h[10] + h[11]);
+       q[14] = (h[ 3] - h[ 5] + h[ 8] - h[11] - h[12]);
+       q[15] = (h[12] - h[ 4] - h[ 6] - h[ 9] + h[13]);
+       dump_x(q, 16, 'W');
+       for(i=0; i<16; ++i){
+               q[i] = s[i%5](q[i]);
+       }
+#if TWEAK
+       for(i=0; i<16; ++i){
+               ((uint64_t*)h)[i] ^= ((uint64_t*)m)[i];
+       }
+       for(i=0; i<16; ++i){
+               q[i] += h[(i+1)&0xf];
+       }
+#endif /* TWEAK */
+
+}
+#endif /* F0_HACK==0 */
+
+static
+void bmw_large_f1(uint64_t* q, const void* m, const uint64_t* h){
+       uint8_t i;
+       q[16] = bmw_large_expand1(0, q, m, h);
+       q[17] = bmw_large_expand1(1, q, m, h);
+       for(i=2; i<16; ++i){
+               q[16+i] = bmw_large_expand2(i, q, m, h);
+       }
+}
+
+static
+void bmw_large_f2(uint64_t* h, const uint64_t* q, const void* m){
+       uint64_t xl=0, xh;
+       uint8_t i;
+       for(i=16;i<24;++i){
+               xl ^= q[i];
+       }
+       xh = xl;
+       for(i=24;i<32;++i){
+               xh ^= q[i];
+       }
+#if DEBUG
+       cli_putstr("\r\n XL = ");
+       cli_hexdump_rev(&xl, 4);
+       cli_putstr("\r\n XH = ");
+       cli_hexdump_rev(&xh, 4);
+#endif
+       memcpy(h, m, 16*8);
+       h[0] ^= SHL64(xh, 5) ^ SHR64(q[16], 5);
+       h[1] ^= SHR64(xh, 7) ^ SHL64(q[17], 8);
+       h[2] ^= SHR64(xh, 5) ^ SHL64(q[18], 5);
+       h[3] ^= SHR64(xh, 1) ^ SHL64(q[19], 5);
+       h[4] ^= SHR64(xh, 3) ^ q[20];
+       h[5] ^= SHL64(xh, 6) ^ SHR64(q[21], 6);
+       h[6] ^= SHR64(xh, 4) ^ SHL64(q[22], 6);
+       h[7] ^= SHR64(xh,11) ^ SHL64(q[23], 2);
+       for(i=0; i<8; ++i){
+               h[i] += xl ^ q[24+i] ^ q[i];
+       }
+       for(i=0; i<8; ++i){
+               h[8+i] ^= xh ^ q[24+i];
+               h[8+i] += ROTL64(h[(4+i)%8],i+9);
+       }
+       h[ 8] += SHL64(xl, 8) ^ q[23] ^ q[ 8];
+       h[ 9] += SHR64(xl, 6) ^ q[16] ^ q[ 9];
+       h[10] += SHL64(xl, 6) ^ q[17] ^ q[10];
+       h[11] += SHL64(xl, 4) ^ q[18] ^ q[11];
+       h[12] += SHR64(xl, 3) ^ q[19] ^ q[12];
+       h[13] += SHR64(xl, 4) ^ q[20] ^ q[13];
+       h[14] += SHR64(xl, 7) ^ q[21] ^ q[14];
+       h[15] += SHR64(xl, 2) ^ q[22] ^ q[15];
+}
+
+void bmw_large_nextBlock(bmw_large_ctx_t* ctx, const void* block){
+       uint64_t q[32];
+       dump_x(block, 16, 'M');
+       bmw_large_f0(q, ctx->h, block);
+       dump_x(q, 16, 'Q');
+       bmw_large_f1(q, block, ctx->h);
+       dump_x(q, 32, 'Q');
+       bmw_large_f2(ctx->h, q, block);
+       ctx->counter += 1;
+       ctx_dump(ctx);
+}
+
+void bmw_large_lastBlock(bmw_large_ctx_t* ctx, const void* block, uint16_t length_b){
+       uint8_t buffer[128];
+       while(length_b >= BMW_LARGE_BLOCKSIZE){
+               bmw_large_nextBlock(ctx, block);
+               length_b -= BMW_LARGE_BLOCKSIZE;
+               block = (uint8_t*)block + BMW_LARGE_BLOCKSIZE_B;
+       }
+       memset(buffer, 0, 128);
+       memcpy(buffer, block, (length_b+7)/8);
+       buffer[length_b>>3] |= 0x80 >> (length_b&0x07);
+       if(length_b+1>128*8-64){
+               bmw_large_nextBlock(ctx, buffer);
+               memset(buffer, 0, 128-8);
+               ctx->counter -= 1;
+       }
+       *((uint64_t*)&(buffer[128-8])) = (uint64_t)(ctx->counter*1024LL)+(uint64_t)length_b;
+       bmw_large_nextBlock(ctx, buffer);
+#if TWEAK
+       uint8_t i;
+       uint64_t q[32];
+       memset(buffer, 0xaa, 128);
+       for(i=0; i<16; ++i){
+               buffer[8*i] = i + 0xa0;
+       }
+       bmw_large_f0(q, (uint64_t*)buffer, ctx->h);
+       bmw_large_f1(q, ctx->h, (uint64_t*)buffer);
+       bmw_large_f2((uint64_t*)buffer, q, ctx->h);
+       memcpy(ctx->h, buffer, 128);
+#endif
+}
+
+void bmw384_init(bmw384_ctx_t* ctx){
+       uint8_t i;
+       ctx->h[0] = 0x0001020304050607LL;
+       for(i=1; i<16; ++i){
+               ctx->h[i] = ctx->h[i-1]+ 0x0808080808080808LL;
+       }
+#if BUG24
+       ctx->h[6] = 0x3031323324353637LL;
+#endif
+       ctx->counter=0;
+       ctx_dump(ctx);
+}
+
+void bmw512_init(bmw512_ctx_t* ctx){
+       uint8_t i;
+       ctx->h[0] = 0x8081828384858687LL;
+       for(i=1; i<16; ++i){
+               ctx->h[i] = ctx->h[i-1]+ 0x0808080808080808LL;
+       }
+       ctx->counter=0;
+       ctx_dump(ctx);
+}
+
+void bmw384_nextBlock(bmw384_ctx_t* ctx, const void* block){
+       bmw_large_nextBlock(ctx, block);
+}
+
+void bmw512_nextBlock(bmw512_ctx_t* ctx, const void* block){
+       bmw_large_nextBlock(ctx, block);
+}
+
+void bmw384_lastBlock(bmw384_ctx_t* ctx, const void* block, uint16_t length_b){
+       bmw_large_lastBlock(ctx, block, length_b);
+}
+
+void bmw512_lastBlock(bmw512_ctx_t* ctx, const void* block, uint16_t length_b){
+       bmw_large_lastBlock(ctx, block, length_b);
+}
+
+void bmw384_ctx2hash(void* dest, const bmw384_ctx_t* ctx){
+       memcpy(dest, &(ctx->h[10]), 384/8);
+}
+
+void bmw512_ctx2hash(void* dest, const bmw512_ctx_t* ctx){
+       memcpy(dest, &(ctx->h[8]), 512/8);
+}
+
+void bmw384(void* dest, const void* msg, uint32_t length_b){
+       bmw_large_ctx_t ctx;
+       bmw384_init(&ctx);
+       while(length_b>=BMW_LARGE_BLOCKSIZE){
+               bmw_large_nextBlock(&ctx, msg);
+               length_b -= BMW_LARGE_BLOCKSIZE;
+               msg = (uint8_t*)msg + BMW_LARGE_BLOCKSIZE_B;
+       }
+       bmw_large_lastBlock(&ctx, msg, length_b);
+       bmw384_ctx2hash(dest, &ctx);
+}
+
+void bmw512(void* dest, const void* msg, uint32_t length_b){
+       bmw_large_ctx_t ctx;
+       bmw512_init(&ctx);
+       while(length_b>=BMW_LARGE_BLOCKSIZE){
+               bmw_large_nextBlock(&ctx, msg);
+               length_b -= BMW_LARGE_BLOCKSIZE;
+               msg = (uint8_t*)msg + BMW_LARGE_BLOCKSIZE_B;
+       }
+       bmw_large_lastBlock(&ctx, msg, length_b);
+       bmw512_ctx2hash(dest, &ctx);
+}
+
diff --git a/bmw/bmw_large.h b/bmw/bmw_large.h
new file mode 100644 (file)
index 0000000..fba01fb
--- /dev/null
@@ -0,0 +1,65 @@
+/* bmw_large.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    bmw_large.h
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-04-27
+ * \license GPLv3 or later
+ * 
+ */
+#ifndef BMW_LARGE_H_
+#define BMW_LARGE_H_
+
+#include <stdint.h>
+
+#define BMW_LARGE_BLOCKSIZE   1024
+#define BMW_LARGE_BLOCKSIZE_B ((BMW_LARGE_BLOCKSIZE+7)/8)
+#define BMW384_BLOCKSIZE      BMW_LARGE_BLOCKSIZE
+#define BMW384_BLOCKSIZE_B    BMW_LARGE_BLOCKSIZE_B
+#define BMW512_BLOCKSIZE      BMW_LARGE_BLOCKSIZE
+#define BMW512_BLOCKSIZE_B    BMW_LARGE_BLOCKSIZE_B
+
+typedef struct {
+       uint64_t h[16];
+       uint32_t counter;
+} bmw_large_ctx_t;
+
+typedef bmw_large_ctx_t bmw384_ctx_t;
+typedef bmw_large_ctx_t bmw512_ctx_t;
+
+void bmw384_init(bmw384_ctx_t* ctx);
+void bmw512_init(bmw512_ctx_t* ctx);
+
+void bmw_large_nextBlock(bmw_large_ctx_t* ctx, const void* block);
+void bmw_large_lastBlock(bmw_large_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void bmw384_nextBlock(bmw384_ctx_t* ctx, const void* block);
+void bmw384_lastBlock(bmw384_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void bmw512_nextBlock(bmw512_ctx_t* ctx, const void* block);
+void bmw512_lastBlock(bmw512_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void bmw384_ctx2hash(void* dest, const bmw384_ctx_t* ctx);
+void bmw512_ctx2hash(void* dest, const bmw512_ctx_t* ctx);
+
+void bmw384(void* dest, const void* msg, uint32_t length_b);
+void bmw512(void* dest, const void* msg, uint32_t length_b);
+
+#endif /* BMW_LARGE_H_ */
diff --git a/bmw/bmw_small-tinyasm.ps b/bmw/bmw_small-tinyasm.ps
new file mode 100644 (file)
index 0000000..56409c5
--- /dev/null
@@ -0,0 +1,3456 @@
+%!PS-Adobe-3.0
+%%BoundingBox: 18 36 577 806
+%%Title: Enscript Output
+%%Creator: GNU enscript 1.6.4
+%%CreationDate: Tue Apr  6 12:07:47 2010
+%%Orientation: Landscape
+%%Pages: (atend)
+%%DocumentMedia: A4 595 842 0 () ()
+%%DocumentNeededResources: (atend)
+%%EndComments
+%%BeginProlog
+%%BeginResource: procset Enscript-Prolog 1.6 4
+%
+% Procedures.
+%
+
+/_S {  % save current state
+  /_s save def
+} def
+/_R {  % restore from saved state
+  _s restore
+} def
+
+/S {   % showpage protecting gstate
+  gsave
+  showpage
+  grestore
+} bind def
+
+/MF {  % fontname newfontname -> -     make a new encoded font
+  /newfontname exch def
+  /fontname exch def
+
+  /fontdict fontname findfont def
+  /newfont fontdict maxlength dict def
+
+  fontdict {
+    exch
+    dup /FID eq {
+      % skip FID pair
+      pop pop
+    } {
+      % copy to the new font dictionary
+      exch newfont 3 1 roll put
+    } ifelse
+  } forall
+
+  newfont /FontName newfontname put
+
+  % insert only valid encoding vectors
+  encoding_vector length 256 eq {
+    newfont /Encoding encoding_vector put
+  } if
+
+  newfontname newfont definefont pop
+} def
+
+/MF_PS { % fontname newfontname -> -   make a new font preserving its enc
+  /newfontname exch def
+  /fontname exch def
+
+  /fontdict fontname findfont def
+  /newfont fontdict maxlength dict def
+
+  fontdict {
+    exch
+    dup /FID eq {
+      % skip FID pair
+      pop pop
+    } {
+      % copy to the new font dictionary
+      exch newfont 3 1 roll put
+    } ifelse
+  } forall
+
+  newfont /FontName newfontname put
+
+  newfontname newfont definefont pop
+} def
+
+/SF { % fontname width height -> -     set a new font
+  /height exch def
+  /width exch def
+
+  findfont
+  [width 0 0 height 0 0] makefont setfont
+} def
+
+/SUF { % fontname width height -> -    set a new user font
+  /height exch def
+  /width exch def
+
+  /F-gs-user-font MF
+  /F-gs-user-font width height SF
+} def
+
+/SUF_PS { % fontname width height -> - set a new user font preserving its enc
+  /height exch def
+  /width exch def
+
+  /F-gs-user-font MF_PS
+  /F-gs-user-font width height SF
+} def
+
+/M {moveto} bind def
+/s {show} bind def
+
+/Box { % x y w h -> -                  define box path
+  /d_h exch def /d_w exch def /d_y exch def /d_x exch def
+  d_x d_y  moveto
+  d_w 0 rlineto
+  0 d_h rlineto
+  d_w neg 0 rlineto
+  closepath
+} def
+
+/bgs { % x y height blskip gray str -> -       show string with bg color
+  /str exch def
+  /gray exch def
+  /blskip exch def
+  /height exch def
+  /y exch def
+  /x exch def
+
+  gsave
+    x y blskip sub str stringwidth pop height Box
+    gray setgray
+    fill
+  grestore
+  x y M str s
+} def
+
+/bgcs { % x y height blskip red green blue str -> -  show string with bg color
+  /str exch def
+  /blue exch def
+  /green exch def
+  /red exch def
+  /blskip exch def
+  /height exch def
+  /y exch def
+  /x exch def
+
+  gsave
+    x y blskip sub str stringwidth pop height Box
+    red green blue setrgbcolor
+    fill
+  grestore
+  x y M str s
+} def
+
+% Highlight bars.
+/highlight_bars {      % nlines lineheight output_y_margin gray -> -
+  gsave
+    setgray
+    /ymarg exch def
+    /lineheight exch def
+    /nlines exch def
+
+    % This 2 is just a magic number to sync highlight lines to text.
+    0 d_header_y ymarg sub 2 sub translate
+
+    /cw d_output_w cols div def
+    /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
+
+    % for each column
+    0 1 cols 1 sub {
+      cw mul /xp exch def
+
+      % for each rows
+      0 1 nrows 1 sub {
+        /rn exch def
+        rn lineheight mul neg /yp exch def
+        rn nlines idiv 2 mod 0 eq {
+         % Draw highlight bar.  4 is just a magic indentation.
+         xp 4 add yp cw 8 sub lineheight neg Box fill
+       } if
+      } for
+    } for
+
+  grestore
+} def
+
+% Line highlight bar.
+/line_highlight {      % x y width height gray -> -
+  gsave
+    /gray exch def
+    Box gray setgray fill
+  grestore
+} def
+
+% Column separator lines.
+/column_lines {
+  gsave
+    .1 setlinewidth
+    0 d_footer_h translate
+    /cw d_output_w cols div def
+    1 1 cols 1 sub {
+      cw mul 0 moveto
+      0 d_output_h rlineto stroke
+    } for
+  grestore
+} def
+
+% Column borders.
+/column_borders {
+  gsave
+    .1 setlinewidth
+    0 d_footer_h moveto
+    0 d_output_h rlineto
+    d_output_w 0 rlineto
+    0 d_output_h neg rlineto
+    closepath stroke
+  grestore
+} def
+
+% Do the actual underlay drawing
+/draw_underlay {
+  ul_style 0 eq {
+    ul_str true charpath stroke
+  } {
+    ul_str show
+  } ifelse
+} def
+
+% Underlay
+/underlay {    % - -> -
+  gsave
+    0 d_page_h translate
+    d_page_h neg d_page_w atan rotate
+
+    ul_gray setgray
+    ul_font setfont
+    /dw d_page_h dup mul d_page_w dup mul add sqrt def
+    ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
+    draw_underlay
+  grestore
+} def
+
+/user_underlay {       % - -> -
+  gsave
+    ul_x ul_y translate
+    ul_angle rotate
+    ul_gray setgray
+    ul_font setfont
+    0 0 ul_h_ptsize 2 div sub moveto
+    draw_underlay
+  grestore
+} def
+
+% Page prefeed
+/page_prefeed {                % bool -> -
+  statusdict /prefeed known {
+    statusdict exch /prefeed exch put
+  } {
+    pop
+  } ifelse
+} def
+
+% Wrapped line markers
+/wrapped_line_mark {   % x y charwith charheight type -> -
+  /type exch def
+  /h exch def
+  /w exch def
+  /y exch def
+  /x exch def
+
+  type 2 eq {
+    % Black boxes (like TeX does)
+    gsave
+      0 setlinewidth
+      x w 4 div add y M
+      0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
+      closepath fill
+    grestore
+  } {
+    type 3 eq {
+      % Small arrows
+      gsave
+        .2 setlinewidth
+        x w 2 div add y h 2 div add M
+        w 4 div 0 rlineto
+        x w 4 div add y lineto stroke
+
+        x w 4 div add w 8 div add y h 4 div add M
+        x w 4 div add y lineto
+       w 4 div h 8 div rlineto stroke
+      grestore
+    } {
+      % do nothing
+    } ifelse
+  } ifelse
+} def
+
+% EPSF import.
+
+/BeginEPSF {
+  /b4_Inc_state save def               % Save state for cleanup
+  /dict_count countdictstack def       % Count objects on dict stack
+  /op_count count 1 sub def            % Count objects on operand stack
+  userdict begin
+  /showpage { } def
+  0 setgray 0 setlinecap
+  1 setlinewidth 0 setlinejoin
+  10 setmiterlimit [ ] 0 setdash newpath
+  /languagelevel where {
+    pop languagelevel
+    1 ne {
+      false setstrokeadjust false setoverprint
+    } if
+  } if
+} bind def
+
+/EndEPSF {
+  count op_count sub { pos } repeat    % Clean up stacks
+  countdictstack dict_count sub { end } repeat
+  b4_Inc_state restore
+} bind def
+
+% Check PostScript language level.
+/languagelevel where {
+  pop /gs_languagelevel languagelevel def
+} {
+  /gs_languagelevel 1 def
+} ifelse
+%%EndResource
+%%BeginResource: procset Enscript-Encoding-88591 1.6 4
+/encoding_vector [
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/space         /exclam         /quotedbl       /numbersign     
+/dollar        /percent        /ampersand      /quoteright     
+/parenleft     /parenright     /asterisk       /plus           
+/comma         /hyphen         /period         /slash          
+/zero          /one            /two            /three          
+/four          /five           /six            /seven          
+/eight         /nine           /colon          /semicolon      
+/less          /equal          /greater        /question       
+/at            /A              /B              /C              
+/D             /E              /F              /G              
+/H             /I              /J              /K              
+/L             /M              /N              /O              
+/P             /Q              /R              /S              
+/T             /U              /V              /W              
+/X             /Y              /Z              /bracketleft    
+/backslash     /bracketright   /asciicircum    /underscore     
+/quoteleft     /a              /b              /c              
+/d             /e              /f              /g              
+/h             /i              /j              /k              
+/l             /m              /n              /o              
+/p             /q              /r              /s              
+/t             /u              /v              /w              
+/x             /y              /z              /braceleft      
+/bar           /braceright     /tilde          /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/space         /exclamdown     /cent           /sterling       
+/currency      /yen            /brokenbar      /section        
+/dieresis      /copyright      /ordfeminine    /guillemotleft  
+/logicalnot    /hyphen         /registered     /macron         
+/degree        /plusminus      /twosuperior    /threesuperior  
+/acute         /mu             /paragraph      /bullet         
+/cedilla       /onesuperior    /ordmasculine   /guillemotright 
+/onequarter    /onehalf        /threequarters  /questiondown   
+/Agrave        /Aacute         /Acircumflex    /Atilde         
+/Adieresis     /Aring          /AE             /Ccedilla       
+/Egrave        /Eacute         /Ecircumflex    /Edieresis      
+/Igrave        /Iacute         /Icircumflex    /Idieresis      
+/Eth           /Ntilde         /Ograve         /Oacute         
+/Ocircumflex   /Otilde         /Odieresis      /multiply       
+/Oslash        /Ugrave         /Uacute         /Ucircumflex    
+/Udieresis     /Yacute         /Thorn          /germandbls     
+/agrave        /aacute         /acircumflex    /atilde         
+/adieresis     /aring          /ae             /ccedilla       
+/egrave        /eacute         /ecircumflex    /edieresis      
+/igrave        /iacute         /icircumflex    /idieresis      
+/eth           /ntilde         /ograve         /oacute         
+/ocircumflex   /otilde         /odieresis      /divide         
+/oslash        /ugrave         /uacute         /ucircumflex    
+/udieresis     /yacute         /thorn          /ydieresis      
+] def
+%%EndResource
+%%EndProlog
+%%BeginSetup
+%%IncludeResource: font Courier-Bold
+%%IncludeResource: font Courier
+/HFpt_w 10 def
+/HFpt_h 10 def
+/Courier-Bold /HF-gs-font MF
+/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
+/Courier /F-gs-font MF
+/F-gs-font 7 7 SF
+/#copies 1 def
+% Pagedevice definitions:
+gs_languagelevel 1 gt {
+  <<
+    /PageSize [595 842] 
+  >> setpagedevice
+} if
+%%BeginResource: procset Enscript-Header-simple 1.6 4
+
+/do_header {   % print default simple header
+  gsave
+    d_header_x d_header_y HFpt_h 3 div add translate
+
+    HF setfont
+    user_header_p {
+      5 0 moveto user_header_left_str show
+
+      d_header_w user_header_center_str stringwidth pop sub 2 div
+      0 moveto user_header_center_str show
+
+      d_header_w user_header_right_str stringwidth pop sub 5 sub
+      0 moveto user_header_right_str show
+    } {
+      5 0 moveto fname show
+      45 0 rmoveto fmodstr show
+      45 0 rmoveto pagenumstr show
+    } ifelse
+
+  grestore
+} def
+%%EndResource
+/d_page_w 770 def
+/d_page_h 559 def
+/d_header_x 0 def
+/d_header_y 544 def
+/d_header_w 770 def
+/d_header_h 15 def
+/d_footer_x 0 def
+/d_footer_y 0 def
+/d_footer_w 770 def
+/d_footer_h 0 def
+/d_output_w 770 def
+/d_output_h 544 def
+/cols 3 def
+%%EndSetup
+%%Page: (1) 1
+%%BeginPageSetup
+_S
+90 rotate
+36 -577 translate
+/pagenum 1 def
+/fname (bmw_small-tinyasm.S) def
+/fdir () def
+/ftail (bmw_small-tinyasm.S) def
+% User defined strings:
+/fmodstr (Mo Apr 05 09:57:29 2010) def
+/pagenumstr (1) def
+/user_header_p false def
+/user_footer_p false def
+%%EndPageSetup
+column_lines
+column_borders
+do_header
+5 534 M
+(/* bmw_small-tinyasm.S */) s
+5 526 M
+(/*) s
+5 518 M
+(    This file is part of the AVR-Crypto-Lib.) s
+5 510 M
+(    Copyright \(C\) 2009  Daniel Otte \(daniel.otte@rub.de\)) s
+5 494 M
+(    This program is free software: you can redistribute it) s
+5 486 M
+( and/or modify) s
+5 478 M
+(    it under the terms of the GNU General Public License a) s
+5 470 M
+(s published by) s
+5 462 M
+(    the Free Software Foundation, either version 3 of the ) s
+5 454 M
+(License, or) s
+5 446 M
+(    \(at your option\) any later version.) s
+5 430 M
+(    This program is distributed in the hope that it will b) s
+5 422 M
+(e useful,) s
+5 414 M
+(    but WITHOUT ANY WARRANTY; without even the implied war) s
+5 406 M
+(ranty of) s
+5 398 M
+(    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  ) s
+5 390 M
+(See the) s
+5 382 M
+(    GNU General Public License for more details.) s
+5 366 M
+(    You should have received a copy of the GNU General Pub) s
+5 358 M
+(lic License) s
+5 350 M
+(    along with this program.  If not, see <http://www.gnu.) s
+5 342 M
+(org/licenses/>.) s
+5 334 M
+(*/) s
+5 318 M
+(/*) s
+5 310 M
+( * File:        bmw_small-tinyasm.S) s
+5 302 M
+( * Author:      Daniel Otte) s
+5 294 M
+( * Date:        2010-03-28) s
+5 286 M
+( * License:     GPLv3 or later) s
+5 278 M
+( * Description: implementation of BlueMidnightWish) s
+5 270 M
+( *) s
+5 262 M
+( */) s
+5 246 M
+(#include "avr-asm-macros.S") s
+5 230 M
+(/*********************************************************) s
+5 222 M
+(*********************/) s
+5 214 M
+(/*) s
+5 206 M
+(  param a: r22:r23:r24:r25) s
+5 198 M
+(  param s: r20) s
+5 190 M
+(*/) s
+5 182 M
+(shiftleft32:) s
+5 174 M
+(        clr r0) s
+5 166 M
+(        cpi r20, 8) s
+5 158 M
+(        brlo bitrotateleft_1) s
+5 150 M
+(        mov r25, r24) s
+5 142 M
+(        mov r24, r23) s
+5 134 M
+(        mov r23, r22) s
+5 126 M
+(        clr r22) s
+5 118 M
+(        subi r20, 8) s
+5 110 M
+(        rjmp shiftleft32) s
+5 94 M
+(/*********************************************************) s
+5 86 M
+(*********************/) s
+5 78 M
+(/*) s
+5 70 M
+(  param a: r22:r23:r24:r25) s
+5 62 M
+(  param s: r20) s
+5 54 M
+(*/) s
+5 46 M
+(shiftright32:) s
+5 38 M
+(        cpi r20, 8) s
+5 30 M
+(        brlo bitshiftright) s
+5 22 M
+(        mov r22, r23) s
+5 14 M
+(        mov r23, r24) s
+5 6 M
+(        mov r24, r25) s
+261.667 534 M
+(        clr r25) s
+261.667 526 M
+(        subi r20, 8) s
+261.667 518 M
+(        rjmp shiftright32) s
+261.667 510 M
+(bitshiftright:) s
+261.667 502 M
+(        tst r20) s
+261.667 494 M
+(        breq 20f) s
+261.667 486 M
+(10:     lsr r25) s
+261.667 478 M
+(        ror r24) s
+261.667 470 M
+(        ror r23) s
+261.667 462 M
+(        ror r22) s
+261.667 454 M
+(        dec r20) s
+261.667 446 M
+(        brne 10b) s
+261.667 438 M
+(20: ret) s
+261.667 422 M
+(/*********************************************************) s
+261.667 414 M
+(*********************/) s
+261.667 406 M
+(/*) s
+261.667 398 M
+(  param a: r22:r23:r24:r25) s
+261.667 390 M
+(  param s: r20) s
+261.667 382 M
+(*/) s
+261.667 374 M
+(rotateleft32:) s
+261.667 366 M
+(        cpi r20, 8) s
+261.667 358 M
+(        brlo bitrotateleft) s
+261.667 350 M
+(        mov r0, r25) s
+261.667 342 M
+(        mov r25, r24) s
+261.667 334 M
+(        mov r24, r23) s
+261.667 326 M
+(        mov r23, r22) s
+261.667 318 M
+(        mov r22, r0) s
+261.667 310 M
+(        subi r20, 8) s
+261.667 302 M
+(        rjmp rotateleft32) s
+261.667 294 M
+(bitrotateleft:) s
+261.667 286 M
+(    mov r0, r25) s
+261.667 278 M
+(bitrotateleft_1:) s
+261.667 270 M
+(        tst r20) s
+261.667 262 M
+(        breq 20f) s
+261.667 254 M
+(10:) s
+261.667 246 M
+(        lsl r0) s
+261.667 238 M
+(        rol r22) s
+261.667 230 M
+(        rol r23) s
+261.667 222 M
+(        rol r24) s
+261.667 214 M
+(        rol r25) s
+261.667 206 M
+(        dec r20) s
+261.667 198 M
+(        brne 10b) s
+261.667 190 M
+(20: ret) s
+261.667 166 M
+(/*********************************************************) s
+261.667 158 M
+(*********************/) s
+261.667 142 M
+(s_table:) s
+261.667 134 M
+(s0:  .byte 1, 3, 4,19) s
+261.667 126 M
+(s1:  .byte 1, 2, 8,23) s
+261.667 118 M
+(s2:  .byte 2, 1,12,25) s
+261.667 110 M
+(s3:  .byte 2, 2,15,29) s
+261.667 102 M
+(s4:  .byte 1, 0, 0, 0) s
+261.667 94 M
+(s5:  .byte 2, 0, 0, 0) s
+261.667 78 M
+(eor_r22_in_r16:) s
+261.667 70 M
+(        eor r16, r22) s
+261.667 62 M
+(        eor r17, r23) s
+261.667 54 M
+(        eor r18, r24) s
+261.667 46 M
+(        eor r19, r25) s
+261.667 38 M
+(        ret) s
+261.667 22 M
+(/*) s
+261.667 14 M
+(  param x: r22:r23:r24:25) s
+261.667 6 M
+(  param s: r20) s
+518.333 534 M
+(*/) s
+518.333 526 M
+(sn:) s
+518.333 518 M
+(        push_range 2, 5) s
+518.333 510 M
+(        push r17) s
+518.333 502 M
+(        push r19) s
+518.333 494 M
+(        ldi r30, lo8\(s_table\)) s
+518.333 486 M
+(        ldi r31, hi8\(s_table\)) s
+518.333 478 M
+(        lsl r20) s
+518.333 470 M
+(        lsl r20) s
+518.333 462 M
+(        add r30, r20) s
+518.333 454 M
+(        adc r31, r1) s
+518.333 446 M
+(        movw r2, r22) s
+518.333 438 M
+(        movw r4, r24) s
+518.333 430 M
+(        lpm r20, Z+) s
+518.333 422 M
+(        rcall shiftright32) s
+518.333 414 M
+(        movw r16, r22) s
+518.333 406 M
+(        movw r18, r24) s
+518.333 398 M
+(;---) s
+518.333 390 M
+(        movw r22, r2) s
+518.333 382 M
+(        movw r24, r4) s
+518.333 374 M
+(        lpm r20, Z+) s
+518.333 366 M
+(        rcall shiftleft32) s
+518.333 358 M
+(        rcall eor_r22_in_r16) s
+518.333 350 M
+(;---) s
+518.333 342 M
+(        movw r22, r2) s
+518.333 334 M
+(        movw r24, r4) s
+518.333 326 M
+(        lpm r20, Z+) s
+518.333 318 M
+(        rcall rotateleft32) s
+518.333 310 M
+(        rcall eor_r22_in_r16) s
+518.333 302 M
+(;---) s
+518.333 294 M
+(        movw r22, r2) s
+518.333 286 M
+(        movw r24, r4) s
+518.333 278 M
+(        lpm r20, Z+) s
+518.333 270 M
+(        rcall rotateleft32) s
+518.333 262 M
+(        eor r22, r16) s
+518.333 254 M
+(        eor r23, r17) s
+518.333 246 M
+(        eor r24, r18) s
+518.333 238 M
+(        eor r25, r19) s
+518.333 230 M
+(        pop r19) s
+518.333 222 M
+(        pop r17) s
+518.333 214 M
+(        pop_range 2, 5) s
+518.333 206 M
+(        ret) s
+518.333 190 M
+(/*********************************************************) s
+518.333 182 M
+(*********************/) s
+518.333 174 M
+(/*) s
+518.333 166 M
+(  param dest: r26:r27 \(X\)) s
+518.333 158 M
+(  param src:  r30:r31 \(Z\)) s
+518.333 150 M
+(  param len:  r20) s
+518.333 142 M
+(*/) s
+518.333 134 M
+(memxor_short:) s
+518.333 126 M
+(;       tst r20) s
+518.333 118 M
+(;       breq memxor_exit) s
+518.333 110 M
+(10: ld r21, X) s
+518.333 102 M
+(        ld r22, Z+) s
+518.333 94 M
+(        eor r21, r22) s
+518.333 86 M
+(        st X+, r21) s
+518.333 78 M
+(        dec r20) s
+518.333 70 M
+(        brne 10b) s
+518.333 62 M
+(memxor_exit:) s
+518.333 54 M
+(        ret) s
+518.333 38 M
+(/*********************************************************) s
+518.333 30 M
+(*********************/) s
+518.333 22 M
+(q0 = 2) s
+518.333 14 M
+(q1 = 3) s
+518.333 6 M
+(h0 = 4) s
+_R
+S
+%%Page: (2) 2
+%%BeginPageSetup
+_S
+90 rotate
+36 -577 translate
+/pagenum 2 def
+/fname (bmw_small-tinyasm.S) def
+/fdir () def
+/ftail (bmw_small-tinyasm.S) def
+% User defined strings:
+/fmodstr (Mo Apr 05 09:57:29 2010) def
+/pagenumstr (2) def
+/user_header_p false def
+/user_footer_p false def
+%%EndPageSetup
+column_lines
+column_borders
+do_header
+5 534 M
+(h1 = 5) s
+5 526 M
+(m0 = 6) s
+5 518 M
+(m1 = 7) s
+5 502 M
+(add_hx_to_w:) s
+5 494 M
+(        movw r26, h0) s
+5 486 M
+(        add r26, r16) s
+5 478 M
+(        adc r27, r1) s
+5 470 M
+(        ld r22, Y) s
+5 462 M
+(        ldd r23, Y+1) s
+5 454 M
+(        ldd r24, Y+2) s
+5 446 M
+(        ldd r25, Y+3) s
+5 438 M
+(        lsl r20) s
+5 430 M
+(        rol r21) s
+5 422 M
+(        brcs 30f) s
+5 414 M
+(        /* addition */) s
+5 406 M
+(        ld r0, X+) s
+5 398 M
+(        add r22, r0) s
+5 390 M
+(        ld r0, X+) s
+5 382 M
+(        adc r23, r0) s
+5 374 M
+(        ld r0, X+) s
+5 366 M
+(        adc r24, r0) s
+5 358 M
+(        ld r0, X+) s
+5 350 M
+(        adc r25, r0) s
+5 342 M
+(        rjmp 50f) s
+5 334 M
+(30: /* substract */) s
+5 326 M
+(        ld r0, X+) s
+5 318 M
+(        sub r22, r0) s
+5 310 M
+(        ld r0, X+) s
+5 302 M
+(        sbc r23, r0) s
+5 294 M
+(        ld r0, X+) s
+5 286 M
+(        sbc r24, r0) s
+5 278 M
+(        ld r0, X+) s
+5 270 M
+(        sbc r25, r0) s
+5 262 M
+(50:) s
+5 254 M
+(        st Y+, r22) s
+5 246 M
+(        st Y+, r23) s
+5 238 M
+(        st Y+, r24) s
+5 230 M
+(        st Y+, r25) s
+5 222 M
+(        ret) s
+5 206 M
+(/*********************************************************) s
+5 198 M
+(*********************/) s
+5 190 M
+(load32_from_X:) s
+5 182 M
+(        ld r22, X+) s
+5 174 M
+(        ld r23, X+) s
+5 166 M
+(        ld r24, X+) s
+5 158 M
+(        ld r25, X+) s
+5 150 M
+(        ret) s
+5 134 M
+(load32_from_Y:) s
+5 126 M
+(        ld r22, Y+) s
+5 118 M
+(        ld r23, Y+) s
+5 110 M
+(        ld r24, Y+) s
+5 102 M
+(        ld r25, Y+) s
+5 94 M
+(        ret) s
+5 78 M
+(add_X_to_32:) s
+5 70 M
+(        ld r0, X+) s
+5 62 M
+(        add r22, r0) s
+5 54 M
+(        ld r0, X+) s
+5 46 M
+(        adc r23, r0) s
+5 38 M
+(        ld r0, X+) s
+5 30 M
+(        adc r24, r0) s
+5 22 M
+(        ld r0, X+) s
+5 14 M
+(        adc r25, r0) s
+5 6 M
+(        ret) s
+261.667 534 M
+(/*********************************************************) s
+261.667 526 M
+(*********************/) s
+261.667 518 M
+(/*) s
+261.667 510 M
+(  param q:  r28:r29 \(Y\)) s
+261.667 502 M
+(  param h:  r26:r27 \(X\)) s
+261.667 494 M
+(  param m:  r30:r31 \(Z\)) s
+261.667 486 M
+(*/) s
+261.667 470 M
+(f0_hacktable:) s
+261.667 462 M
+(        .byte 0x03, 0x11) s
+261.667 454 M
+(        .byte 0xDD, 0xB3) s
+261.667 446 M
+(        .byte 0x2A, 0x79) s
+261.667 438 M
+(        .byte 0x07, 0xAA) s
+261.667 430 M
+(        .byte 0x51, 0xC2) s
+261.667 422 M
+(f0_indextable:) s
+261.667 414 M
+(        .byte 5*4,7*4,10*4,13*4,14*4) s
+261.667 406 M
+(;       .byte 0 ; just for alignment) s
+261.667 398 M
+(f0_s_table:) s
+261.667 390 M
+(        .byte 0,1,2,3,4) s
+261.667 382 M
+(        .byte 0,1,2,3,4) s
+261.667 374 M
+(        .byte 0,1,2,3,4) s
+261.667 366 M
+(;       .byte 0) s
+261.667 350 M
+(f0:) s
+261.667 342 M
+(        movw h0, r26) s
+261.667 334 M
+(        movw q0, r28) s
+261.667 326 M
+(        movw m0, r30) s
+261.667 318 M
+(;--- DBG) s
+261.667 310 M
+(;       push_range 22, 25) s
+261.667 302 M
+(;       movw r24, r26) s
+261.667 294 M
+(;       ldi r22, 'H') s
+261.667 286 M
+(;       rcall printX) s
+261.667 278 M
+(;       pop_range  22, 25) s
+261.667 270 M
+(;--- END DBG) s
+261.667 262 M
+(;--- DBG) s
+261.667 254 M
+(;       push_range 22, 25) s
+261.667 246 M
+(;       movw r24, r30) s
+261.667 238 M
+(;       ldi r22, 'M') s
+261.667 230 M
+(;       rcall printX) s
+261.667 222 M
+(;       pop_range  22, 25) s
+261.667 214 M
+(;--- END DBG) s
+261.667 206 M
+(        /* xor m into h */) s
+261.667 198 M
+(        ldi r20, 64) s
+261.667 190 M
+(        rcall memxor_short) s
+261.667 182 M
+(        movw r30, m0) s
+261.667 174 M
+(        movw r26, h0) s
+261.667 158 M
+(        /* set q to zero */) s
+261.667 150 M
+(        ldi r22, 64) s
+261.667 142 M
+(10:     st Y+, r1) s
+261.667 134 M
+(        dec r22) s
+261.667 126 M
+(        brne 10b) s
+261.667 118 M
+(        movw r28, q0) s
+261.667 110 M
+(        /* calculate W and store it in Q */) s
+261.667 102 M
+(        ldi r19, 5) s
+261.667 94 M
+(30:) s
+261.667 86 M
+(        ldi r18, 16) s
+261.667 78 M
+(        /* load initial index */) s
+261.667 70 M
+(        ldi r30, lo8\(f0_indextable-1\)) s
+261.667 62 M
+(        ldi r31, hi8\(f0_indextable-1\)) s
+261.667 54 M
+(        add r30, r19) s
+261.667 46 M
+(        adc r31, r1) s
+261.667 38 M
+(        lpm r16, Z) s
+261.667 30 M
+(        /* load values from hacktable */) s
+261.667 22 M
+(        ldi r30, lo8\(f0_hacktable-2\)) s
+261.667 14 M
+(        ldi r31, hi8\(f0_hacktable-2\)) s
+261.667 6 M
+(        lsl r19) s
+518.333 534 M
+(        add r30, r19) s
+518.333 526 M
+(        adc r31, r1) s
+518.333 518 M
+(        lsr r19) s
+518.333 510 M
+(        lpm r21, Z+) s
+518.333 502 M
+(        lpm r20, Z) s
+518.333 494 M
+(40:) s
+518.333 486 M
+(        call add_hx_to_w) s
+518.333 478 M
+(        subi r16, -4) s
+518.333 470 M
+(        andi r16, 0x0f<<2) s
+518.333 462 M
+(        dec r18) s
+518.333 454 M
+(        brne 40b) s
+518.333 446 M
+(        movw r28, q0) s
+518.333 438 M
+(        dec r19) s
+518.333 430 M
+(        brne 30b) s
+518.333 422 M
+(        movw r26, h0) s
+518.333 414 M
+(;--- DBG) s
+518.333 406 M
+(;       push_range 22, 25) s
+518.333 398 M
+(;       movw r24, r28) s
+518.333 390 M
+(;       ldi r22, 'W') s
+518.333 382 M
+(;       rcall printX) s
+518.333 374 M
+(;       pop_range  22, 25) s
+518.333 366 M
+(;--- END DBG) s
+518.333 358 M
+(        /* xor m into h */) s
+518.333 350 M
+(        ldi r20, 64) s
+518.333 342 M
+(        movw r26, h0) s
+518.333 334 M
+(        movw r30, m0) s
+518.333 326 M
+(        rcall memxor_short) s
+518.333 318 M
+(        sbiw r26, 60) s
+518.333 310 M
+(;---) s
+518.333 302 M
+(        ldi r30, lo8\(f0_s_table\)) s
+518.333 294 M
+(        ldi r31, hi8\(f0_s_table\)) s
+518.333 286 M
+(        ldi r21, 15) s
+518.333 278 M
+(        mov r8, r21) s
+518.333 270 M
+(50:) s
+518.333 262 M
+(        ldd r22, Y+0) s
+518.333 254 M
+(        ldd r23, Y+1) s
+518.333 246 M
+(        ldd r24, Y+2) s
+518.333 238 M
+(        ldd r25, Y+3) s
+518.333 230 M
+(        lpm r20, Z+) s
+518.333 222 M
+(        movw r2, r30) s
+518.333 214 M
+(        rcall sn) s
+518.333 206 M
+(        movw r30, r2) s
+518.333 190 M
+(        rcall add_X_to_32) s
+518.333 174 M
+(        st Y+, r22) s
+518.333 166 M
+(        st Y+, r23) s
+518.333 158 M
+(        st Y+, r24) s
+518.333 150 M
+(        st Y+, r25) s
+518.333 142 M
+(        dec r8) s
+518.333 134 M
+(        brne 50b) s
+518.333 126 M
+(;---) s
+518.333 118 M
+(        ldd r22, Y+0) s
+518.333 110 M
+(        ldd r23, Y+1) s
+518.333 102 M
+(        ldd r24, Y+2) s
+518.333 94 M
+(        ldd r25, Y+3) s
+518.333 86 M
+(        clr r20) s
+518.333 78 M
+(        rcall sn) s
+518.333 70 M
+(        movw r30, r2) s
+518.333 62 M
+(        movw r26, h0) s
+518.333 54 M
+(        rcall add_X_to_32) s
+518.333 46 M
+(        sbiw r26, 4) s
+518.333 38 M
+(        std Y+0, r22) s
+518.333 30 M
+(        std Y+1, r23) s
+518.333 22 M
+(        std Y+2, r24) s
+518.333 14 M
+(        std Y+3, r25) s
+518.333 6 M
+(        sbiw r28, 15*4) s
+_R
+S
+%%Page: (3) 3
+%%BeginPageSetup
+_S
+90 rotate
+36 -577 translate
+/pagenum 3 def
+/fname (bmw_small-tinyasm.S) def
+/fdir () def
+/ftail (bmw_small-tinyasm.S) def
+% User defined strings:
+/fmodstr (Mo Apr 05 09:57:29 2010) def
+/pagenumstr (3) def
+/user_header_p false def
+/user_footer_p false def
+%%EndPageSetup
+column_lines
+column_borders
+do_header
+5 534 M
+(        movw r20, h0) s
+5 526 M
+(        movw r22, m0) s
+5 518 M
+(        ret) s
+5 502 M
+(/*********************************************************) s
+5 494 M
+(*********************/) s
+5 478 M
+(const_lut:) s
+5 470 M
+(        .long 0x55555550, 0x5aaaaaa5, 0x5ffffffa, 0x655555) s
+5 462 M
+(4f) s
+5 454 M
+(        .long 0x6aaaaaa4, 0x6ffffff9, 0x7555554e, 0x7aaaaa) s
+5 446 M
+(a3) s
+5 438 M
+(        .long 0x7ffffff8, 0x8555554d, 0x8aaaaaa2, 0x8fffff) s
+5 430 M
+(f7) s
+5 422 M
+(        .long 0x9555554c, 0x9aaaaaa1, 0x9ffffff6, 0xa55555) s
+5 414 M
+(4b) s
+5 398 M
+(/*********************************************************) s
+5 390 M
+(**********************) s
+5 382 M
+(* uint32_t addelment\(uint8_t j, const uint32_t* m, const u) s
+5 374 M
+(int32_t* h\){) s
+5 366 M
+(*       uint32_t r;) s
+5 358 M
+(*       r  = pgm_read_dword\(k_lut+j\);) s
+5 350 M
+(*       r += rotl_addel\(\(\(uint32_t*\)m\)[j&0xf], j+0\);) s
+5 342 M
+(*       r += rotl_addel\(\(\(uint32_t*\)m\)[\(j+3\)&0xf], j+3\);) s
+5 334 M
+(*       r -= rotl_addel\(\(\(uint32_t*\)m\)[\(j+10\)&0xf], j+10\);) s
+5 326 M
+(*       r ^= \(\(uint32_t*\)h\)[\(j+7\)&0xf];) s
+5 318 M
+(*       return r;) s
+5 310 M
+(* }) s
+5 302 M
+(* param j: r24) s
+5 294 M
+(* param m: r22:r23) s
+5 286 M
+(* param h: r20:r21) s
+5 278 M
+(*/) s
+5 270 M
+(j    = 16) s
+5 262 M
+(acc2 =  8) s
+5 254 M
+(acc3 =  9) s
+5 246 M
+(h0   = 10) s
+5 238 M
+(h1   = 11) s
+5 230 M
+(m0   = 12) s
+5 222 M
+(m1   = 13) s
+5 214 M
+(acc0 = 14) s
+5 206 M
+(acc1 = 15) s
+5 190 M
+(add32_to_acc:) s
+5 182 M
+(        add acc0, r22) s
+5 174 M
+(        adc acc1, r23) s
+5 166 M
+(        adc acc2, r24) s
+5 158 M
+(        adc acc3, r25) s
+5 150 M
+(        ret) s
+5 134 M
+(eor32_to_acc:) s
+5 126 M
+(        eor acc0, r22) s
+5 118 M
+(        eor acc1, r23) s
+5 110 M
+(        eor acc2, r24) s
+5 102 M
+(        eor acc3, r25) s
+5 94 M
+(        ret) s
+5 78 M
+(load_acc_from_X:) s
+5 70 M
+(        ld acc0, X+) s
+5 62 M
+(        ld acc1, X+) s
+5 54 M
+(        ld acc2, X+) s
+5 46 M
+(        ld acc3, X+) s
+5 38 M
+(        ret) s
+5 22 M
+(add_acc_to_Z:) s
+5 14 M
+(        ld r0, Z) s
+5 6 M
+(        add r0, acc0) s
+261.667 534 M
+(        st Z+, r0) s
+261.667 526 M
+(        ld r0, Z) s
+261.667 518 M
+(        adc r0, acc1) s
+261.667 510 M
+(        st Z+, r0) s
+261.667 502 M
+(        ld r0, Z) s
+261.667 494 M
+(        adc r0, acc2) s
+261.667 486 M
+(        st Z+, r0) s
+261.667 478 M
+(        ld r0, Z) s
+261.667 470 M
+(        adc r0, acc3) s
+261.667 462 M
+(        st Z+, r0) s
+261.667 454 M
+(        ret) s
+261.667 438 M
+(load_rotate_add_M:) s
+261.667 430 M
+(        andi r20, 0x0f) s
+261.667 422 M
+(        mov r0, r20) s
+261.667 414 M
+(        lsl r0) s
+261.667 406 M
+(        lsl r0) s
+261.667 398 M
+(        movw r26, m0) s
+261.667 390 M
+(        add r26, r0) s
+261.667 382 M
+(        adc r27, r1) s
+261.667 374 M
+(        ld r22, X+) s
+261.667 366 M
+(        ld r23, X+) s
+261.667 358 M
+(        ld r24, X+) s
+261.667 350 M
+(        ld r25, X+) s
+261.667 342 M
+(        inc r20) s
+261.667 334 M
+(        rcall rotateleft32) s
+261.667 326 M
+(        brts 10f) s
+261.667 318 M
+(        rcall add32_to_acc) s
+261.667 310 M
+(        ret) s
+261.667 302 M
+(10:     sub acc0, r22) s
+261.667 294 M
+(        sbc acc1, r23) s
+261.667 286 M
+(        sbc acc2, r24) s
+261.667 278 M
+(        sbc acc3, r25) s
+261.667 270 M
+(        ret) s
+261.667 254 M
+(addelement:) s
+261.667 246 M
+(        mov j, r24) s
+261.667 238 M
+(        movw h0, r20) s
+261.667 230 M
+(        movw m0, r22) s
+261.667 222 M
+(        lsl r24) s
+261.667 214 M
+(        lsl r24) s
+261.667 206 M
+(        mov r28, r24) s
+261.667 198 M
+(        ldi r30, lo8\(const_lut\)) s
+261.667 190 M
+(        ldi r31, hi8\(const_lut\)) s
+261.667 182 M
+(        add r30, r24) s
+261.667 174 M
+(        adc r31, r1) s
+261.667 166 M
+(        lpm acc0, Z+) s
+261.667 158 M
+(        lpm acc1, Z+) s
+261.667 150 M
+(        lpm acc2, Z+) s
+261.667 142 M
+(        lpm acc3, Z+) s
+261.667 134 M
+(        clt) s
+261.667 126 M
+(        mov r20, j) s
+261.667 118 M
+(        rcall load_rotate_add_M) s
+261.667 110 M
+(        mov r20, j) s
+261.667 102 M
+(        subi r20, -3) s
+261.667 94 M
+(        rcall load_rotate_add_M) s
+261.667 86 M
+(        mov r20, j) s
+261.667 78 M
+(        set) s
+261.667 70 M
+(        subi r20, -10) s
+261.667 62 M
+(        rcall load_rotate_add_M) s
+261.667 54 M
+(        lsl j) s
+261.667 46 M
+(        lsl j) s
+261.667 38 M
+(        subi j, -7*4) s
+261.667 30 M
+(        andi j, 0x3f) s
+261.667 22 M
+(        movw r26, h0) s
+261.667 14 M
+(        add r26, j) s
+261.667 6 M
+(        adc r27, r1) s
+518.333 534 M
+(        ld r0, X+) s
+518.333 526 M
+(        eor acc0, r0) s
+518.333 518 M
+(        ld r0, X+) s
+518.333 510 M
+(        eor acc1, r0) s
+518.333 502 M
+(        ld r0, X+) s
+518.333 494 M
+(        eor acc2, r0) s
+518.333 486 M
+(        ld r0, X+) s
+518.333 478 M
+(        eor acc3, r0) s
+518.333 470 M
+(;---) s
+518.333 462 M
+(        ret) s
+518.333 446 M
+(/*********************************************************) s
+518.333 438 M
+(*********************/) s
+518.333 430 M
+(/*) s
+518.333 422 M
+(  param q: r26:r27) s
+518.333 414 M
+(  param m: r22:r23) s
+518.333 406 M
+(  param h: r20:r21) s
+518.333 398 M
+(  param j: r24) s
+518.333 390 M
+(*/) s
+518.333 374 M
+(expand_intro:) s
+518.333 366 M
+(        push_range 20, 27) s
+518.333 358 M
+(;       push r24) s
+518.333 350 M
+(        rcall addelement) s
+518.333 342 M
+(;       pop r24) s
+518.333 334 M
+(        pop_range 20, 27) s
+518.333 326 M
+(        lsl r24) s
+518.333 318 M
+(        lsl r24) s
+518.333 310 M
+(        add r26, r24) s
+518.333 302 M
+(        adc r27, r1) s
+518.333 294 M
+(        ret) s
+518.333 286 M
+(expand1:) s
+518.333 278 M
+(        rcall expand_intro) s
+518.333 270 M
+(        ldi r19, 1) s
+518.333 262 M
+(10:) s
+518.333 254 M
+(        rcall load32_from_X) s
+518.333 246 M
+(        mov r20, r19) s
+518.333 238 M
+(        andi r20, 3) s
+518.333 230 M
+(        rcall sn) s
+518.333 222 M
+(        rcall add32_to_acc) s
+518.333 214 M
+(        inc r19) s
+518.333 206 M
+(        cpi r19, 17) s
+518.333 198 M
+(        brne 10b) s
+518.333 190 M
+(expand1_exit:) s
+518.333 182 M
+(;       adiw r26, 63) s
+518.333 174 M
+(        st X+, acc0) s
+518.333 166 M
+(        st X+, acc1) s
+518.333 158 M
+(        st X+, acc2) s
+518.333 150 M
+(        st X+, acc3) s
+518.333 142 M
+(        ret) s
+518.333 126 M
+(/*********************************************************) s
+518.333 118 M
+(*********************/) s
+518.333 110 M
+(/*) s
+518.333 102 M
+(  param q: r26:r27) s
+518.333 94 M
+(  param m: r22:r23) s
+518.333 86 M
+(  param h: r20:r21) s
+518.333 78 M
+(  param j: r24) s
+518.333 70 M
+(*/) s
+518.333 54 M
+(expand2_rot_table:) s
+518.333 46 M
+(        .byte 0,3,0,7,0,13,0,16,0,19,0,23,0,27) s
+518.333 30 M
+(expand2:) s
+518.333 22 M
+(        rcall expand_intro) s
+518.333 14 M
+(        ldi r19, 14) s
+518.333 6 M
+(        ldi r30, lo8\(expand2_rot_table\)) s
+_R
+S
+%%Page: (4) 4
+%%BeginPageSetup
+_S
+90 rotate
+36 -577 translate
+/pagenum 4 def
+/fname (bmw_small-tinyasm.S) def
+/fdir () def
+/ftail (bmw_small-tinyasm.S) def
+% User defined strings:
+/fmodstr (Mo Apr 05 09:57:29 2010) def
+/pagenumstr (4) def
+/user_header_p false def
+/user_footer_p false def
+%%EndPageSetup
+column_lines
+column_borders
+do_header
+5 534 M
+(        ldi r31, hi8\(expand2_rot_table\)) s
+5 526 M
+(10:) s
+5 518 M
+(        rcall load32_from_X) s
+5 510 M
+(        mov r20, r19) s
+5 502 M
+(        lpm r20, Z+) s
+5 494 M
+(        rcall rotateleft32) s
+5 486 M
+(        rcall add32_to_acc) s
+5 478 M
+(        dec r19) s
+5 470 M
+(        brne 10b) s
+5 462 M
+(        rcall load32_from_X) s
+5 454 M
+(        ldi r20, 4) s
+5 446 M
+(        rcall sn) s
+5 438 M
+(        rcall add32_to_acc) s
+5 430 M
+(        rcall load32_from_X) s
+5 422 M
+(        ldi r20, 5) s
+5 414 M
+(        rcall sn) s
+5 406 M
+(        rcall add32_to_acc) s
+5 390 M
+(        rjmp expand1_exit) s
+5 374 M
+(/*********************************************************) s
+5 366 M
+(*********************/) s
+5 358 M
+(/*) s
+5 350 M
+(  param q: r24:r25) s
+5 342 M
+(  param m: r22:r23) s
+5 334 M
+(  param h: r20:r21) s
+5 326 M
+(*/) s
+5 318 M
+(/* for calling expand1/2) s
+5 310 M
+(  param q: r26:r27) s
+5 302 M
+(  param m: r22:r23) s
+5 294 M
+(  param h: r20:r21) s
+5 286 M
+(  param j: r24) s
+5 278 M
+(*/) s
+5 270 M
+(f1:) s
+5 262 M
+(        movw r2, r24) s
+5 254 M
+(        movw r4, r22) s
+5 246 M
+(        movw r6, r20) s
+5 238 M
+(        movw r26, r2) s
+5 230 M
+(;       movw r22, r4) s
+5 222 M
+(;   movw r20, r6) s
+5 214 M
+(        clr r24) s
+5 206 M
+(        rcall expand1) s
+5 198 M
+(        movw r26, r2) s
+5 190 M
+(        movw r22, r4) s
+5 182 M
+(    movw r20, r6) s
+5 174 M
+(        ldi r24, 1) s
+5 166 M
+(        rcall expand1) s
+5 158 M
+(        ldi r17, 2) s
+5 150 M
+(10:     movw r26, r2) s
+5 142 M
+(        movw r22, r4) s
+5 134 M
+(        movw r20, r6) s
+5 126 M
+(        mov r24, r17) s
+5 118 M
+(        rcall expand2) s
+5 110 M
+(        inc r17) s
+5 102 M
+(        sbrs r17, 4) s
+5 94 M
+(        rjmp 10b) s
+5 86 M
+(        movw r24, r2) s
+5 78 M
+(        movw r22, r4) s
+5 70 M
+(        movw r20, r6) s
+5 62 M
+(        ret) s
+5 46 M
+(/*********************************************************) s
+5 38 M
+(*********************/) s
+5 30 M
+(/*) s
+5 22 M
+(  param q: r24:r25) s
+5 14 M
+(  param m: r22:r23) s
+5 6 M
+(  param h: r20:r21) s
+261.667 534 M
+(*/) s
+261.667 526 M
+(f2_1_shift_table:) s
+261.667 518 M
+(        .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x) s
+261.667 510 M
+(00) s
+261.667 502 M
+(        .byte 0x2B, 0x64, 0x66, 0x03, 0x51, 0x55, 0x87, 0x) s
+261.667 494 M
+(55) s
+261.667 486 M
+(f2_2_shift_table:) s
+261.667 478 M
+(        .byte \(2<<1\), \(7<<1\), \(4<<1\), \(3<<1\), \(4<<1\)+1, \(6) s
+261.667 470 M
+(<<1\)+1, \(6<<1\)) s
+261.667 462 M
+(        .byte 0 ; just for alignment) s
+261.667 454 M
+(acc2  =  8) s
+261.667 446 M
+(acc3  =  9) s
+261.667 438 M
+(acc0  = 14) s
+261.667 430 M
+(acc1  = 15) s
+261.667 422 M
+(xl0   =  2) s
+261.667 414 M
+(xl1   =  3) s
+261.667 406 M
+(xl2   =  4) s
+261.667 398 M
+(xl3   =  5) s
+261.667 390 M
+(xh0   =  6) s
+261.667 382 M
+(xh1   =  7) s
+261.667 374 M
+(xh2   = 10) s
+261.667 366 M
+(xh3   = 11) s
+261.667 358 M
+(q16_0 = 12) s
+261.667 350 M
+(q16_1 = 13) s
+261.667 342 M
+(h0   =  18) s
+261.667 334 M
+(h1   =  19) s
+261.667 326 M
+(f2:) s
+261.667 318 M
+(        movw r26, r24) s
+261.667 310 M
+(        /* calc XL */) s
+261.667 302 M
+(        adiw r26, 63) s
+261.667 294 M
+(        adiw r26,  1) s
+261.667 286 M
+(        movw q16_0, r26) s
+261.667 278 M
+(        clr xl0) s
+261.667 270 M
+(        clr xl1) s
+261.667 262 M
+(        clr xl2) s
+261.667 254 M
+(        clr xl3) s
+261.667 246 M
+(        ldi r17, 8) s
+261.667 238 M
+(10:     ld r0, X+) s
+261.667 230 M
+(        eor xl0, r0) s
+261.667 222 M
+(        ld r0, X+) s
+261.667 214 M
+(        eor xl1, r0) s
+261.667 206 M
+(        ld r0, X+) s
+261.667 198 M
+(        eor xl2, r0) s
+261.667 190 M
+(        ld r0, X+) s
+261.667 182 M
+(        eor xl3, r0) s
+261.667 174 M
+(        dec r17) s
+261.667 166 M
+(        brne 10b) s
+261.667 158 M
+(;--- /* calc XH */) s
+261.667 150 M
+(        movw xh0, xl0) s
+261.667 142 M
+(        movw xh2, xl2) s
+261.667 134 M
+(        ldi r17, 8) s
+261.667 126 M
+(10:     ld r0, X+) s
+261.667 118 M
+(        eor xh0, r0) s
+261.667 110 M
+(        ld r0, X+) s
+261.667 102 M
+(        eor xh1, r0) s
+261.667 94 M
+(        ld r0, X+) s
+261.667 86 M
+(        eor xh2, r0) s
+261.667 78 M
+(        ld r0, X+) s
+261.667 70 M
+(        eor xh3, r0) s
+261.667 62 M
+(        dec r17) s
+261.667 54 M
+(        brne 10b) s
+261.667 46 M
+(;--- DBG) s
+261.667 38 M
+(;       push_range 22, 25) s
+261.667 30 M
+(;       movw r22, xl0) s
+261.667 22 M
+(;       movw r24, xl2) s
+261.667 14 M
+(;       rcall print32) s
+261.667 6 M
+(;       movw r22, xh0) s
+518.333 534 M
+(;       movw r24, xh2) s
+518.333 526 M
+(;       rcall print32) s
+518.333 518 M
+(;       pop_range 22, 25) s
+518.333 510 M
+(;--- END DBG) s
+518.333 494 M
+(;--- /* calc first half of h0..h15 */) s
+518.333 486 M
+(        movw h0, r20) s
+518.333 478 M
+(        movw r28, r22) s
+518.333 470 M
+(        movw r26, q16_0) s
+518.333 462 M
+(        ldi r17, 16) s
+518.333 454 M
+(10:) s
+518.333 446 M
+(        ld acc0, Y+) s
+518.333 438 M
+(        ld acc1, Y+) s
+518.333 430 M
+(        ld acc2, Y+) s
+518.333 422 M
+(        ld acc3, Y+) s
+518.333 414 M
+(;---) s
+518.333 406 M
+(        ldi r30, lo8\(f2_1_shift_table-1\)) s
+518.333 398 M
+(        ldi r31, hi8\(f2_1_shift_table-1\)) s
+518.333 390 M
+(        movw r22, xh0) s
+518.333 382 M
+(        movw r24, xh2) s
+518.333 374 M
+(        add r30, r17) s
+518.333 366 M
+(        adc r31, r1) s
+518.333 358 M
+(        lpm r20, Z) s
+518.333 350 M
+(        mov r1, r20) s
+518.333 342 M
+(        andi r20, 0x0f) s
+518.333 334 M
+(        clt) s
+518.333 326 M
+(        cpi r17, 16) s
+518.333 318 M
+(        breq 20f) s
+518.333 310 M
+(        cpi r17, 11) s
+518.333 302 M
+(        brne 21f) s
+518.333 294 M
+(20:     set) s
+518.333 286 M
+(21:     brts 25f) s
+518.333 278 M
+(        rcall shiftright32) s
+518.333 270 M
+(        rjmp 26f) s
+518.333 262 M
+(25:     rcall shiftleft32) s
+518.333 254 M
+(26: rcall eor32_to_acc) s
+518.333 246 M
+(;---) s
+518.333 238 M
+(        rcall load32_from_X) s
+518.333 230 M
+(        mov r20, r1) s
+518.333 222 M
+(        clr r1) s
+518.333 214 M
+(        swap r20) s
+518.333 206 M
+(        andi r20, 0x0f) s
+518.333 198 M
+(        brts 27f) s
+518.333 190 M
+(        rcall shiftleft32) s
+518.333 182 M
+(        rjmp 28f) s
+518.333 174 M
+(27:     rcall shiftright32) s
+518.333 166 M
+(28:     rcall eor32_to_acc) s
+518.333 158 M
+(;---) s
+518.333 150 M
+(        movw r30, h0) s
+518.333 142 M
+(        st Z+, acc0) s
+518.333 134 M
+(        st Z+, acc1) s
+518.333 126 M
+(        st Z+, acc2) s
+518.333 118 M
+(        st Z+, acc3) s
+518.333 110 M
+(        movw h0, r30) s
+518.333 102 M
+(;---) s
+518.333 94 M
+(        dec r17) s
+518.333 86 M
+(        brne 10b) s
+518.333 78 M
+(;-----) s
+518.333 70 M
+(        sbiw r26, 4*8 /* X points to q[24] */) s
+518.333 62 M
+(        movw r28, r26) s
+518.333 54 M
+(        sbiw r28, 63) s
+518.333 46 M
+(        sbiw r28, 33 /* Y points to q[0] */) s
+518.333 38 M
+(        sbiw r30, 63) s
+518.333 30 M
+(        sbiw r30,  1 /* Z points to h0 */) s
+518.333 22 M
+(        ldi r17, 8) s
+518.333 14 M
+(10:     movw acc0, xl0) s
+518.333 6 M
+(        movw acc2, xl2) s
+_R
+S
+%%Page: (5) 5
+%%BeginPageSetup
+_S
+90 rotate
+36 -577 translate
+/pagenum 5 def
+/fname (bmw_small-tinyasm.S) def
+/fdir () def
+/ftail (bmw_small-tinyasm.S) def
+% User defined strings:
+/fmodstr (Mo Apr 05 09:57:29 2010) def
+/pagenumstr (5) def
+/user_header_p false def
+/user_footer_p false def
+%%EndPageSetup
+column_lines
+column_borders
+do_header
+5 534 M
+(        rcall load32_from_X) s
+5 526 M
+(        rcall eor32_to_acc) s
+5 518 M
+(        rcall load32_from_Y) s
+5 510 M
+(        rcall eor32_to_acc) s
+5 502 M
+(        rcall add_acc_to_Z) s
+5 494 M
+(        dec r17) s
+5 486 M
+(        brne 10b) s
+5 478 M
+(        sbiw r26, 9*4 /* X points to q[23] */) s
+5 470 M
+(        rcall load_acc_from_X) s
+5 462 M
+(        eor acc1, xl0) s
+5 454 M
+(        eor acc2, xl1) s
+5 446 M
+(        eor acc3, xl2) s
+5 438 M
+(        rcall load32_from_Y) s
+5 430 M
+(        rcall eor32_to_acc) s
+5 422 M
+(        rcall add_acc_to_Z) s
+5 414 M
+(;---) s
+5 406 M
+(        sbiw r26, 8*4 /* X points to q[16] */) s
+5 398 M
+(        mov h0, r30) s
+5 390 M
+(        ldi r17, 7) s
+5 382 M
+(10:) s
+5 374 M
+(        ldi r30, lo8\(f2_2_shift_table-1\)) s
+5 366 M
+(        ldi r31, hi8\(f2_2_shift_table-1\)) s
+5 358 M
+(        add r30, r17) s
+5 350 M
+(        adc r31, r1) s
+5 342 M
+(        lpm r20, Z) s
+5 334 M
+(        rcall load_acc_from_X) s
+5 326 M
+(        movw r22, xl0) s
+5 318 M
+(        movw r24, xl2) s
+5 310 M
+(        lsr r20) s
+5 302 M
+(        brcc 20f) s
+5 294 M
+(        rcall shiftleft32) s
+5 286 M
+(        rjmp 21f) s
+5 278 M
+(20:     rcall shiftright32) s
+5 270 M
+(21:) s
+5 262 M
+(        rcall eor32_to_acc) s
+5 254 M
+(        rcall load32_from_Y) s
+5 246 M
+(        rcall eor32_to_acc) s
+5 238 M
+(        movw r30, h0) s
+5 230 M
+(        rcall add_acc_to_Z) s
+5 222 M
+(        movw h0, r30) s
+5 214 M
+(        dec r17) s
+5 206 M
+(        brne 10b) s
+5 198 M
+(;-----) s
+5 190 M
+(        sbiw r30, 8*4 /* Z points to h8 */) s
+5 182 M
+(        movw r26, r30) s
+5 174 M
+(        sbiw r26, 4*4 /* X points to h4 */) s
+5 166 M
+(        ldi r17, 8) s
+5 158 M
+(        ldi r18, 9) s
+5 150 M
+(10:) s
+5 142 M
+(        rcall load32_from_X) s
+5 134 M
+(        mov r20, r18) s
+5 126 M
+(        rcall rotateleft32) s
+5 118 M
+(        movw acc0, r22) s
+5 110 M
+(        movw acc2, r24) s
+5 102 M
+(        rcall add_acc_to_Z) s
+5 94 M
+(        inc r18) s
+5 86 M
+(        cpi r17, 5) s
+5 78 M
+(        breq 20f) s
+5 70 M
+(        dec r17) s
+5 62 M
+(        brne 10b) s
+5 54 M
+(        ret) s
+5 46 M
+(20: sbiw r26, 8*4) s
+5 38 M
+(        dec r17) s
+5 30 M
+(        rjmp 10b) s
+5 14 M
+(/*********************************************************) s
+5 6 M
+(*********************/) s
+261.667 534 M
+(/*) s
+261.667 526 M
+(  param ctx:  r24:r25) s
+261.667 518 M
+(  param msg:  r22:r23) s
+261.667 510 M
+(*/) s
+261.667 502 M
+(/* f0) s
+261.667 494 M
+(  param q:  r28:r29 \(Y\)) s
+261.667 486 M
+(  param h:  r26:r27 \(X\)) s
+261.667 478 M
+(  param m:  r30:r31 \(Z\)) s
+261.667 470 M
+(*/) s
+261.667 462 M
+(/* f1) s
+261.667 454 M
+(  param q: r24:r25) s
+261.667 446 M
+(  param m: r22:r23) s
+261.667 438 M
+(  param h: r20:r21) s
+261.667 430 M
+(*/) s
+261.667 422 M
+(/* f2) s
+261.667 414 M
+(  param q: r24:r25) s
+261.667 406 M
+(  param m: r22:r23) s
+261.667 398 M
+(  param h: r20:r21) s
+261.667 390 M
+(*/) s
+261.667 382 M
+(.global bmw_small_nextBlock) s
+261.667 374 M
+(.global bmw224_nextBlock) s
+261.667 366 M
+(.global bmw256_nextBlock) s
+261.667 358 M
+(bmw_small_nextBlock:) s
+261.667 350 M
+(bmw224_nextBlock:) s
+261.667 342 M
+(bmw256_nextBlock:) s
+261.667 334 M
+(        push_range 28, 29) s
+261.667 326 M
+(        push_range  2, 17) s
+261.667 318 M
+(        stack_alloc_large 32*4, r28, r29) s
+261.667 310 M
+(        adiw r28, 1) s
+261.667 302 M
+(;       push_range 28, 29 /* push Q */) s
+261.667 294 M
+(;       push_range 22, 25 /* push M & H */) s
+261.667 286 M
+(        /* increment counter */) s
+261.667 278 M
+(        movw r26, r24) s
+261.667 270 M
+(        movw r2, r26) s
+261.667 262 M
+(        adiw r26, 63) s
+261.667 254 M
+(        adiw r26,  1) s
+261.667 246 M
+(        rcall load_acc_from_X) s
+261.667 238 M
+(        ldi r19, 1) s
+261.667 230 M
+(        add acc0, r19) s
+261.667 222 M
+(        adc acc1, r1) s
+261.667 214 M
+(        adc acc2, r1) s
+261.667 206 M
+(        adc acc3, r1) s
+261.667 198 M
+(        st -X, acc3) s
+261.667 190 M
+(        st -X, acc2) s
+261.667 182 M
+(        st -X, acc1) s
+261.667 174 M
+(        st -X, acc0) s
+261.667 166 M
+(        /* call f0 */) s
+261.667 158 M
+(        movw r30, r22) s
+261.667 150 M
+(        movw r26, r24) s
+261.667 142 M
+(        rcall f0) s
+261.667 134 M
+(        /* call f1*/) s
+261.667 126 M
+(        movw r24, r28) s
+261.667 110 M
+(;       rcall printQ) s
+261.667 102 M
+(        rcall f1) s
+261.667 94 M
+(        /* call f2 */) s
+261.667 86 M
+(;       pop_range 20, 25) s
+261.667 78 M
+(;       push_range 20, 25) s
+261.667 70 M
+(;       rcall printQ) s
+261.667 62 M
+(;       push r20) s
+261.667 54 M
+(;       push r21) s
+261.667 46 M
+(        call f2) s
+261.667 38 M
+(;--- DBG) s
+261.667 30 M
+(;       pop r25) s
+261.667 22 M
+(;       pop r24) s
+261.667 14 M
+(;       ldi r22, 'H') s
+261.667 6 M
+(;       rcall printX) s
+518.333 534 M
+(;--- END DBG) s
+518.333 526 M
+(        stack_free_large3 32*4) s
+518.333 518 M
+(        pop_range  2, 17) s
+518.333 510 M
+(        pop_range 28, 29) s
+518.333 502 M
+(        ret) s
+518.333 486 M
+(/*********************************************************) s
+518.333 478 M
+(*********************/) s
+518.333 470 M
+(/*) s
+518.333 462 M
+(  param ctx:  r24:r25) s
+518.333 454 M
+(  param msg:  r22:r23) s
+518.333 446 M
+(  param len:  r20:r21) s
+518.333 438 M
+(*/) s
+518.333 430 M
+(ctx0 =  2) s
+518.333 422 M
+(ctx1 =  3) s
+518.333 414 M
+(blc0 =  4) s
+518.333 406 M
+(blc1 =  5) s
+518.333 398 M
+(len0 = 28) s
+518.333 390 M
+(len1 = 29) s
+518.333 382 M
+(buf0 =  6) s
+518.333 374 M
+(buf1 =  7) s
+518.333 358 M
+(.global bmw_small_lastBlock) s
+518.333 350 M
+(.global bmw224_lastBlock) s
+518.333 342 M
+(.global bmw256_lastBlock) s
+518.333 334 M
+(bmw_small_lastBlock:) s
+518.333 326 M
+(bmw224_lastBlock:) s
+518.333 318 M
+(bmw256_lastBlock:) s
+518.333 310 M
+(/*      while\(length_b >= BMW_SMALL_BLOCKSIZE\){) s
+518.333 302 M
+(                bmw_small_nextBlock\(ctx, block\);) s
+518.333 294 M
+(                length_b -= BMW_SMALL_BLOCKSIZE;) s
+518.333 286 M
+(                block = \(uint8_t*\)block + BMW_SMALL_BLOCKS) s
+518.333 278 M
+(IZE_B;) s
+518.333 270 M
+(        }) s
+518.333 262 M
+(*/) s
+518.333 254 M
+(        push_range 2, 7) s
+518.333 246 M
+(        push_range 28, 29) s
+518.333 238 M
+(        movw ctx0, r24) s
+518.333 230 M
+(        movw blc0, r22) s
+518.333 222 M
+(        movw len0, r20) s
+518.333 214 M
+(1:) s
+518.333 206 M
+(        cpi len1, hi8\(512\)) s
+518.333 198 M
+(        brlo 2f) s
+518.333 190 M
+(        movw r24, ctx0) s
+518.333 182 M
+(        movw r22, blc0) s
+518.333 174 M
+(        rcall bmw_small_nextBlock) s
+518.333 166 M
+(        ldi r24, 64) s
+518.333 158 M
+(        add blc0, r24) s
+518.333 150 M
+(        adc blc1, r1) s
+518.333 142 M
+(        subi len1, hi8\(512\)) s
+518.333 134 M
+(        rjmp 1b) s
+518.333 126 M
+(2:) s
+518.333 118 M
+(/*      struct {) s
+518.333 110 M
+(                uint8_t  buffer[64];) s
+518.333 102 M
+(                uint32_t ctr;) s
+518.333 94 M
+(        } pctx;) s
+518.333 86 M
+(*/) s
+518.333 78 M
+(        stack_alloc_large 68) s
+518.333 70 M
+(        adiw r30, 1) s
+518.333 62 M
+(        movw buf0, r30) s
+518.333 54 M
+(/*      memset\(pctx.buffer, 0, 64\);) s
+518.333 46 M
+(        memcpy\(pctx.buffer, block, \(length_b+7\)/8\);) s
+518.333 38 M
+(        pctx.buffer[length_b>>3] |= 0x80 >> \(length_b&0x07) s
+518.333 30 M
+(\);) s
+518.333 22 M
+(*/      movw r24, len0) s
+518.333 14 M
+(        lsr r25) s
+518.333 6 M
+(        ror r24) s
+_R
+S
+%%Page: (6) 6
+%%BeginPageSetup
+_S
+90 rotate
+36 -577 translate
+/pagenum 6 def
+/fname (bmw_small-tinyasm.S) def
+/fdir () def
+/ftail (bmw_small-tinyasm.S) def
+% User defined strings:
+/fmodstr (Mo Apr 05 09:57:29 2010) def
+/pagenumstr (6) def
+/user_header_p false def
+/user_footer_p false def
+%%EndPageSetup
+column_lines
+column_borders
+do_header
+5 534 M
+(        lsr r24) s
+5 526 M
+(        lsr r24) s
+5 518 M
+(        ldi r23, 63) s
+5 510 M
+(        sub r23, r24) s
+5 502 M
+(        movw r26, blc0) s
+5 494 M
+(        tst r24) s
+5 486 M
+(        breq 301f) s
+5 478 M
+(        /* copy \(#r24\) bytes to stack buffer */) s
+5 470 M
+(30: ld r20, X+) s
+5 462 M
+(        st Z+, r20) s
+5 454 M
+(        dec r24) s
+5 446 M
+(        brne 30b) s
+5 438 M
+(301: /* calculate the appended byte */) s
+5 430 M
+(        clr r20) s
+5 422 M
+(        mov r21, len0) s
+5 414 M
+(        ldi r24, 0x80) s
+5 406 M
+(        andi r21, 0x07) s
+5 398 M
+(        breq 305f) s
+5 390 M
+(        ld r20, X+) s
+5 382 M
+(303:) s
+5 374 M
+(        lsr r24) s
+5 366 M
+(        dec r21) s
+5 358 M
+(        brne 303b) s
+5 350 M
+(305:) s
+5 342 M
+(        or r20, r24) s
+5 334 M
+(        st Z+, r20) s
+5 326 M
+(        tst r23) s
+5 318 M
+(        breq 32f) s
+5 310 M
+(31: st Z+, r1) s
+5 302 M
+(        dec r23) s
+5 294 M
+(        brne 31b) s
+5 286 M
+(32:) s
+5 278 M
+(/*      if\(length_b+1>64*8-64\){ ; = 64*7-1 = 447 max\(lengt) s
+5 270 M
+(h_b\)=511) s
+5 262 M
+(                bmw_small_nextBlock\(ctx, pctx.buffer\);) s
+5 254 M
+(                memset\(pctx.buffer, 0, 64-8\);) s
+5 246 M
+(                ctx->counter -= 1;) s
+5 238 M
+(        }) s
+5 230 M
+(*/) s
+5 222 M
+(        tst len1) s
+5 214 M
+(        breq 400f) s
+5 206 M
+(        cpi len0, 192) s
+5 198 M
+(        brlo 400f) s
+5 190 M
+(        movw r24, ctx0) s
+5 182 M
+(        movw r22, buf0) s
+5 174 M
+(        rcall bmw_small_nextBlock) s
+5 166 M
+(        movw r26, buf0) s
+5 158 M
+(        ldi r20, 64-8) s
+5 150 M
+(350:) s
+5 142 M
+(        st X+, r1) s
+5 134 M
+(        dec r20) s
+5 126 M
+(        brne 350b) s
+5 118 M
+(        movw r30, ctx0) s
+5 110 M
+(        adiw r30, 60) s
+5 102 M
+(        ldd r21, Z+4) s
+5 94 M
+(        ldd r22, Z+5) s
+5 86 M
+(        ldd r23, Z+6) s
+5 78 M
+(        ldd r24, Z+7) s
+5 70 M
+(        subi r21, 1) s
+5 62 M
+(        sbc r22, r1) s
+5 54 M
+(        sbc r23, r1) s
+5 46 M
+(        sbc r24, r1) s
+5 38 M
+(        rjmp 410f) s
+5 30 M
+(/*      *\(\(uint64_t*\)&\(pctx.buffer[64-8]\)\) = \(uint64_t\)\(ct) s
+5 22 M
+(x->counter*512LL\)+\(uint64_t\)length_b;) s
+5 14 M
+(        bmw_small_nextBlock\(ctx, pctx.buffer\);) s
+5 6 M
+(*/) s
+261.667 534 M
+(400:) s
+261.667 526 M
+(        movw r30, ctx0) s
+261.667 518 M
+(        adiw r30, 60) s
+261.667 510 M
+(        ldd r21, Z+4) s
+261.667 502 M
+(        ldd r22, Z+5) s
+261.667 494 M
+(        ldd r23, Z+6) s
+261.667 486 M
+(        ldd r24, Z+7) s
+261.667 478 M
+(410:) s
+261.667 470 M
+(        clr r25) s
+261.667 462 M
+(        lsl r21) s
+261.667 454 M
+(        rol r22) s
+261.667 446 M
+(        rol r23) s
+261.667 438 M
+(        rol r24) s
+261.667 430 M
+(        rol r25) s
+261.667 422 M
+(        mov r20, len0) s
+261.667 414 M
+(        add r21, len1) s
+261.667 406 M
+(        adc r22, r1) s
+261.667 398 M
+(        adc r23, r1) s
+261.667 390 M
+(        adc r24, r1) s
+261.667 382 M
+(        adc r25, r1) s
+261.667 374 M
+(        movw r30, buf0) s
+261.667 366 M
+(        adiw r30, 64-8) s
+261.667 358 M
+(        st Z+, r20) s
+261.667 350 M
+(        st Z+, r21) s
+261.667 342 M
+(        st Z+, r22) s
+261.667 334 M
+(        st Z+, r23) s
+261.667 326 M
+(        st Z+, r24) s
+261.667 318 M
+(        st Z+, r25) s
+261.667 310 M
+(        st Z+, r1) s
+261.667 302 M
+(        st Z+, r1) s
+261.667 294 M
+(        movw r24, ctx0) s
+261.667 286 M
+(        movw r22, buf0) s
+261.667 278 M
+(        rcall bmw_small_nextBlock) s
+261.667 270 M
+(/*      memset\(pctx.buffer, 0xaa, 64\);) s
+261.667 262 M
+(        for\(i=0; i<16;++i\){) s
+261.667 254 M
+(                pctx.buffer[i*4] = i+0xa0;) s
+261.667 246 M
+(        }) s
+261.667 238 M
+(*/) s
+261.667 230 M
+(        ldi r18, 0xa0) s
+261.667 222 M
+(        ldi r19, 0xaa) s
+261.667 214 M
+(        movw r26, buf0) s
+261.667 206 M
+(500:) s
+261.667 198 M
+(        st X+, r18) s
+261.667 190 M
+(        st X+, r19) s
+261.667 182 M
+(        st X+, r19) s
+261.667 174 M
+(        st X+, r19) s
+261.667 166 M
+(        inc r18) s
+261.667 158 M
+(        sbrs r18, 4) s
+261.667 150 M
+(        rjmp 500b) s
+261.667 142 M
+(/*      bmw_small_nextBlock\(\(bmw_small_ctx_t*\)&pctx, ctx->) s
+261.667 134 M
+(h\);) s
+261.667 126 M
+(        memcpy\(ctx->h, pctx.buffer, 64\);) s
+261.667 118 M
+(*/) s
+261.667 110 M
+(        movw r24, buf0) s
+261.667 102 M
+(        movw r22, ctx0) s
+261.667 94 M
+(        rcall bmw_small_nextBlock) s
+261.667 86 M
+(        ldi r18, 64) s
+261.667 78 M
+(        movw r26, ctx0) s
+261.667 70 M
+(        movw r30, buf0) s
+261.667 62 M
+(600:) s
+261.667 54 M
+(        ld r20, Z+) s
+261.667 46 M
+(        st X+, r20) s
+261.667 38 M
+(        dec r18) s
+261.667 30 M
+(        brne 600b) s
+261.667 14 M
+(        stack_free_large 68) s
+261.667 6 M
+(        pop_range 28, 29) s
+518.333 534 M
+(        pop_range 2, 7) s
+518.333 526 M
+(        ret) s
+518.333 502 M
+(/*********************************************************) s
+518.333 494 M
+(**********************) s
+518.333 486 M
+(* void bmw224_ctx2hash\(void* dest, const bmw224_ctx_t* ctx) s
+518.333 478 M
+(\){) s
+518.333 470 M
+(*       memcpy\(dest, &\(ctx->h[9]\), 224/8\);) s
+518.333 462 M
+(* }) s
+518.333 454 M
+(*) s
+518.333 446 M
+(* param dest:  r24:r25) s
+518.333 438 M
+(* param ctx:   r22:r23) s
+518.333 430 M
+(*/) s
+518.333 422 M
+(.global bmw224_ctx2hash) s
+518.333 414 M
+(bmw224_ctx2hash:) s
+518.333 406 M
+(        movw r26, r24) s
+518.333 398 M
+(        movw r30, r22) s
+518.333 390 M
+(        adiw r30, 9*4) s
+518.333 382 M
+(        ldi r22, 28) s
+518.333 374 M
+(        rjmp 1f) s
+518.333 358 M
+(/*********************************************************) s
+518.333 350 M
+(**********************) s
+518.333 342 M
+(* void bmw256_ctx2hash\(void* dest, const bmw256_ctx_t* ctx) s
+518.333 334 M
+(\){) s
+518.333 326 M
+(*       memcpy\(dest, &\(ctx->h[8]\), 256/8\);) s
+518.333 318 M
+(* }) s
+518.333 310 M
+(*) s
+518.333 302 M
+(* param dest:  r24:r25) s
+518.333 294 M
+(* param ctx:   r22:r23) s
+518.333 286 M
+(*/) s
+518.333 278 M
+(.global bmw256_ctx2hash) s
+518.333 270 M
+(bmw256_ctx2hash:) s
+518.333 262 M
+(        movw r26, r24) s
+518.333 254 M
+(        movw r30, r22) s
+518.333 246 M
+(        adiw r30, 8*4) s
+518.333 238 M
+(        ldi r22, 32) s
+518.333 230 M
+(1:) s
+518.333 222 M
+(        ld r23, Z+) s
+518.333 214 M
+(        st X+, r23) s
+518.333 206 M
+(        dec r22) s
+518.333 198 M
+(        brne 1b) s
+518.333 190 M
+(        ret) s
+518.333 174 M
+(/*********************************************************) s
+518.333 166 M
+(**********************) s
+518.333 158 M
+(* void bmw256\(void* dest, const void* msg, uint32_t length) s
+518.333 150 M
+(_b\){) s
+518.333 142 M
+(*       bmw_small_ctx_t ctx;) s
+518.333 134 M
+(*       bmw256_init\(&ctx\);) s
+518.333 126 M
+(*       while\(length_b>=BMW_SMALL_BLOCKSIZE\){) s
+518.333 118 M
+(*               bmw_small_nextBlock\(&ctx, msg\);) s
+518.333 110 M
+(*               length_b -= BMW_SMALL_BLOCKSIZE;) s
+518.333 102 M
+(*               msg = \(uint8_t*\)msg + BMW_SMALL_BLOCKSIZE_) s
+518.333 94 M
+(B;) s
+518.333 86 M
+(*       }) s
+518.333 78 M
+(*       bmw_small_lastBlock\(&ctx, msg, length_b\);) s
+518.333 70 M
+(*       bmw256_ctx2hash\(dest, &ctx\);) s
+518.333 62 M
+(* }) s
+518.333 54 M
+(*) s
+518.333 46 M
+(* param dest:     r24:r25) s
+518.333 38 M
+(* param msg:      r22:r23) s
+518.333 30 M
+(* param length_b: r18:r21) s
+518.333 22 M
+(*/) s
+518.333 14 M
+(ctx0 =   2) s
+518.333 6 M
+(ctx1 =   3) s
+_R
+S
+%%Page: (7) 7
+%%BeginPageSetup
+_S
+90 rotate
+36 -577 translate
+/pagenum 7 def
+/fname (bmw_small-tinyasm.S) def
+/fdir () def
+/ftail (bmw_small-tinyasm.S) def
+% User defined strings:
+/fmodstr (Mo Apr 05 09:57:29 2010) def
+/pagenumstr (7) def
+/user_header_p false def
+/user_footer_p false def
+%%EndPageSetup
+column_lines
+column_borders
+do_header
+5 534 M
+(msg0 =   4) s
+5 526 M
+(msg1 =   5) s
+5 518 M
+(len0 =   6) s
+5 510 M
+(len1 =   7) s
+5 502 M
+(len2 =   8) s
+5 494 M
+(len3 =   9) s
+5 486 M
+(dst0 =  10) s
+5 478 M
+(dst1 =  11) s
+5 470 M
+(.global bmw256) s
+5 462 M
+(bmw256:) s
+5 454 M
+(        push r16) s
+5 446 M
+(        ldi r16, 1) s
+5 438 M
+(        rjmp bmw_small_all) s
+5 422 M
+(/*********************************************************) s
+5 414 M
+(**********************) s
+5 406 M
+(* void bmw224\(void* dest, const void* msg, uint32_t length) s
+5 398 M
+(_b\){) s
+5 390 M
+(*       bmw_small_ctx_t ctx;) s
+5 382 M
+(*       bmw224_init\(&ctx\);) s
+5 374 M
+(*       while\(length_b>=BMW_SMALL_BLOCKSIZE\){) s
+5 366 M
+(*               bmw_small_nextBlock\(&ctx, msg\);) s
+5 358 M
+(*               length_b -= BMW_SMALL_BLOCKSIZE;) s
+5 350 M
+(*               msg = \(uint8_t*\)msg + BMW_SMALL_BLOCKSIZE_) s
+5 342 M
+(B;) s
+5 334 M
+(*       }) s
+5 326 M
+(*       bmw_small_lastBlock\(&ctx, msg, length_b\);) s
+5 318 M
+(*       bmw224_ctx2hash\(dest, &ctx\);) s
+5 310 M
+(* }) s
+5 302 M
+(*) s
+5 294 M
+(* param dest:     r24:r25) s
+5 286 M
+(* param msg:      r22:r23) s
+5 278 M
+(* param length_b: r18:r21) s
+5 270 M
+(*/) s
+5 262 M
+(ctx0 =   2) s
+5 254 M
+(ctx1 =   3) s
+5 246 M
+(msg0 =   4) s
+5 238 M
+(msg1 =   5) s
+5 230 M
+(len0 =   6) s
+5 222 M
+(len1 =   7) s
+5 214 M
+(len2 =   8) s
+5 206 M
+(len3 =   9) s
+5 198 M
+(dst0 =  10) s
+5 190 M
+(dst1 =  11) s
+5 182 M
+(.global bmw224) s
+5 174 M
+(bmw224:) s
+5 166 M
+(        push r16) s
+5 158 M
+(        clr r16) s
+5 142 M
+(bmw_small_all:) s
+5 134 M
+(        push_range 2, 11) s
+5 126 M
+(        stack_alloc_large 64+4) s
+5 118 M
+(        adiw r30, 1) s
+5 110 M
+(        movw ctx0, r30) s
+5 102 M
+(        movw dst0, r24) s
+5 94 M
+(        movw msg0, r22) s
+5 86 M
+(        movw len0, r18) s
+5 78 M
+(        movw len2, r20) s
+5 70 M
+(        movw r24, ctx0) s
+5 62 M
+(        ldi r30, pm_lo8\(init_lut\)) s
+5 54 M
+(        ldi r31, pm_hi8\(init_lut\)) s
+5 46 M
+(        add r30, r16) s
+5 38 M
+(        adc r31, r1) s
+5 30 M
+(        icall) s
+5 22 M
+(20:) s
+5 14 M
+(        mov r18, len2) s
+5 6 M
+(        or  r18, len3) s
+261.667 534 M
+(        breq 50f) s
+261.667 526 M
+(        movw r24, ctx0) s
+261.667 518 M
+(        movw r22, msg0) s
+261.667 510 M
+(        rcall bmw_small_nextBlock) s
+261.667 502 M
+(        ldi r20, 2) s
+261.667 494 M
+(        sub len1, r20) s
+261.667 486 M
+(        sbc len2, r1) s
+261.667 478 M
+(        sbc len3, r1) s
+261.667 470 M
+(        ldi r20, 64) s
+261.667 462 M
+(        add msg0, r20) s
+261.667 454 M
+(        adc msg1, r1) s
+261.667 446 M
+(        rjmp 20b) s
+261.667 438 M
+(50:) s
+261.667 430 M
+(        movw r24, ctx0) s
+261.667 422 M
+(        movw r22, msg0) s
+261.667 414 M
+(        movw r20, len0) s
+261.667 406 M
+(        rcall bmw_small_lastBlock) s
+261.667 398 M
+(        movw r24, dst0) s
+261.667 390 M
+(        movw r22, ctx0) s
+261.667 382 M
+(        ldi r30, pm_lo8\(c2h_lut\)) s
+261.667 374 M
+(        ldi r31, pm_hi8\(c2h_lut\)) s
+261.667 366 M
+(        add r30, r16) s
+261.667 358 M
+(        adc r31, r1) s
+261.667 350 M
+(        icall) s
+261.667 342 M
+(        stack_free_large 64+4) s
+261.667 334 M
+(        pop_range 2, 11) s
+261.667 326 M
+(        pop r16) s
+261.667 318 M
+(        ret) s
+261.667 302 M
+(init_lut:) s
+261.667 294 M
+(        rjmp bmw224_init) s
+261.667 286 M
+(        rjmp bmw256_init) s
+261.667 278 M
+(c2h_lut:) s
+261.667 270 M
+(        rjmp bmw224_ctx2hash) s
+261.667 262 M
+(        rjmp bmw256_ctx2hash) s
+261.667 246 M
+(/*********************************************************) s
+261.667 238 M
+(**********************) s
+261.667 230 M
+(* void bmw224_init\(bmw224_ctx_t* ctx\){) s
+261.667 222 M
+(*       uint8_t i;) s
+261.667 214 M
+(*       ctx->h[0] = 0x00010203;) s
+261.667 206 M
+(*       for\(i=1; i<16; ++i\){) s
+261.667 198 M
+(*               ctx->h[i] = ctx->h[i-1]+ 0x04040404;) s
+261.667 190 M
+(*       }) s
+261.667 182 M
+(*       ctx->counter=0;) s
+261.667 174 M
+(* }) s
+261.667 166 M
+(*) s
+261.667 158 M
+(* param ctx:  r24:r25) s
+261.667 150 M
+(*/) s
+261.667 142 M
+(.global bmw224_init) s
+261.667 134 M
+(bmw224_init:) s
+261.667 126 M
+(        movw r26, r24) s
+261.667 118 M
+(        ldi r22, 0x03) s
+261.667 110 M
+(        ldi r23, 0x02) s
+261.667 102 M
+(        ldi r24, 0x01) s
+261.667 94 M
+(        ldi r25, 0x00) s
+261.667 86 M
+(bmw_small_init:) s
+261.667 78 M
+(        st X+, r22) s
+261.667 70 M
+(        st X+, r23) s
+261.667 62 M
+(        st X+, r24) s
+261.667 54 M
+(        st X+, r25) s
+261.667 46 M
+(        ldi r18, 16-1) s
+261.667 38 M
+(        ldi r20, 0x04) s
+261.667 30 M
+(1:) s
+261.667 22 M
+(        add r22, r20) s
+261.667 14 M
+(        adc r23, r20) s
+261.667 6 M
+(        adc r24, r20) s
+518.333 534 M
+(        adc r25, r20) s
+518.333 526 M
+(        st X+, r22) s
+518.333 518 M
+(        st X+, r23) s
+518.333 510 M
+(        st X+, r24) s
+518.333 502 M
+(        st X+, r25) s
+518.333 494 M
+(        dec r18) s
+518.333 486 M
+(        brne 1b) s
+518.333 478 M
+(        st X+, r1) s
+518.333 470 M
+(        st X+, r1) s
+518.333 462 M
+(        st X+, r1) s
+518.333 454 M
+(        st X+, r1) s
+518.333 446 M
+(        ret) s
+518.333 430 M
+(.global bmw256_init) s
+518.333 422 M
+(bmw256_init:) s
+518.333 414 M
+(        movw r26, r24) s
+518.333 406 M
+(        ldi r22, 0x43) s
+518.333 398 M
+(        ldi r23, 0x42) s
+518.333 390 M
+(        ldi r24, 0x41) s
+518.333 382 M
+(        ldi r25, 0x40) s
+518.333 374 M
+(        rjmp bmw_small_init) s
+518.333 350 M
+(/*********************************************************) s
+518.333 342 M
+(*********************/) s
+518.333 326 M
+(#if DEBUG) s
+518.333 310 M
+(printQ:) s
+518.333 302 M
+(        push_range 20, 25) s
+518.333 294 M
+(        ldi r16, 4) s
+518.333 286 M
+(        mov r9, r16) s
+518.333 278 M
+(        movw r16, r24) s
+518.333 270 M
+(        ldi r24, lo8\(qdbg_str\)) s
+518.333 262 M
+(        ldi r25, hi8\(qdbg_str\)) s
+518.333 254 M
+(        call cli_putstr_P) s
+518.333 246 M
+(        clr r8) s
+518.333 238 M
+(10:     ldi r24, lo8\(qdbg_str1\)) s
+518.333 230 M
+(        ldi r25, hi8\(qdbg_str1\)) s
+518.333 222 M
+(        call cli_putstr_P) s
+518.333 214 M
+(        mov r24, r8) s
+518.333 206 M
+(        call cli_hexdump_byte) s
+518.333 198 M
+(        ldi r24, lo8\(qdbg_str2\)) s
+518.333 190 M
+(        ldi r25, hi8\(qdbg_str2\)) s
+518.333 182 M
+(        call cli_putstr_P) s
+518.333 174 M
+(        movw r24, r16) s
+518.333 166 M
+(        clr r23) s
+518.333 158 M
+(        ldi r22, 4) s
+518.333 150 M
+(        call cli_hexdump_rev) s
+518.333 142 M
+(        add r16, r9) s
+518.333 134 M
+(        adc r17, r1) s
+518.333 126 M
+(        inc r8) s
+518.333 118 M
+(        sbrs r8, 5) s
+518.333 110 M
+(        rjmp 10b) s
+518.333 102 M
+(        pop_range 20, 25) s
+518.333 94 M
+(        ret) s
+518.333 86 M
+(qdbg_str:  .asciz "\\r\\nDBG Q: ") s
+518.333 78 M
+(qdbg_str1: .asciz "\\r\\n Q[") s
+518.333 70 M
+(qdbg_str2: .asciz "] =  ") s
+518.333 46 M
+(printX:) s
+518.333 38 M
+(        push_range 6, 9) s
+518.333 30 M
+(        push_range 16, 27) s
+518.333 22 M
+(        push_range 30, 31) s
+518.333 14 M
+(        ldi r16, 4) s
+518.333 6 M
+(        mov r6, r22) s
+_R
+S
+%%Page: (8) 8
+%%BeginPageSetup
+_S
+90 rotate
+36 -577 translate
+/pagenum 8 def
+/fname (bmw_small-tinyasm.S) def
+/fdir () def
+/ftail (bmw_small-tinyasm.S) def
+% User defined strings:
+/fmodstr (Mo Apr 05 09:57:29 2010) def
+/pagenumstr (8) def
+/user_header_p false def
+/user_footer_p false def
+%%EndPageSetup
+column_lines
+column_borders
+do_header
+5 534 M
+(        mov r9, r16) s
+5 526 M
+(        movw r16, r24) s
+5 518 M
+(        ldi r24, lo8\(Xdbg_str\)) s
+5 510 M
+(        ldi r25, hi8\(Xdbg_str\)) s
+5 502 M
+(        call cli_putstr_P) s
+5 494 M
+(        mov r24, r6) s
+5 486 M
+(        call cli_putc) s
+5 478 M
+(        ldi r24, ':') s
+5 470 M
+(        call cli_putc) s
+5 462 M
+(        clr r8) s
+5 454 M
+(10:     ldi r24, lo8\(Xdbg_str1\)) s
+5 446 M
+(        ldi r25, hi8\(Xdbg_str1\)) s
+5 438 M
+(        call cli_putstr_P) s
+5 430 M
+(        mov r24, r6) s
+5 422 M
+(        call cli_putc) s
+5 414 M
+(        ldi r24, '[') s
+5 406 M
+(        call cli_putc) s
+5 398 M
+(        mov r24, r8) s
+5 390 M
+(        call cli_hexdump_byte) s
+5 382 M
+(        ldi r24, lo8\(Xdbg_str2\)) s
+5 374 M
+(        ldi r25, hi8\(Xdbg_str2\)) s
+5 366 M
+(        call cli_putstr_P) s
+5 358 M
+(        movw r24, r16) s
+5 350 M
+(        clr r23) s
+5 342 M
+(        ldi r22, 4) s
+5 334 M
+(        call cli_hexdump_rev) s
+5 326 M
+(        add r16, r9) s
+5 318 M
+(        adc r17, r1) s
+5 310 M
+(        inc r8) s
+5 302 M
+(        sbrs r8, 4) s
+5 294 M
+(        rjmp 10b) s
+5 286 M
+(        pop_range 30, 31) s
+5 278 M
+(        pop_range 16, 27) s
+5 270 M
+(        pop_range 6, 9) s
+5 262 M
+(        ret) s
+5 254 M
+(Xdbg_str:  .asciz "\\r\\nDBG ") s
+5 246 M
+(Xdbg_str1: .asciz "\\r\\n ") s
+5 238 M
+(Xdbg_str2: .asciz "] = ") s
+5 222 M
+(print32:) s
+5 214 M
+(        push_range 6, 9) s
+5 206 M
+(        push_range 16, 27) s
+5 198 M
+(        push_range 30, 31) s
+5 190 M
+(        movw r6, r22) s
+5 182 M
+(        movw r8, r24) s
+5 174 M
+(        ldi r24, lo8\(Xdbg_str\)) s
+5 166 M
+(        ldi r25, hi8\(Xdbg_str\)) s
+5 158 M
+(        call cli_putstr_P) s
+5 150 M
+(        mov r24, r9) s
+5 142 M
+(        call cli_hexdump_byte) s
+5 134 M
+(        mov r24, r8) s
+5 126 M
+(        call cli_hexdump_byte) s
+5 118 M
+(        mov r24, r7) s
+5 110 M
+(        call cli_hexdump_byte) s
+5 102 M
+(        mov r24, r6) s
+5 94 M
+(        call cli_hexdump_byte) s
+5 86 M
+(        pop_range 30, 31) s
+5 78 M
+(        pop_range 16, 27) s
+5 70 M
+(        pop_range 6, 9) s
+5 62 M
+(        ret) s
+5 38 M
+(print_acc:) s
+5 30 M
+(        push_range 16, 27) s
+5 22 M
+(        push_range 30, 31) s
+5 14 M
+(        ldi r24, lo8\(Xdbg_str\)) s
+5 6 M
+(        ldi r25, hi8\(Xdbg_str\)) s
+261.667 534 M
+(        call cli_putstr_P) s
+261.667 526 M
+(        mov r24, r9) s
+261.667 518 M
+(        call cli_hexdump_byte) s
+261.667 510 M
+(        mov r24, r8) s
+261.667 502 M
+(        call cli_hexdump_byte) s
+261.667 494 M
+(        mov r24, r15) s
+261.667 486 M
+(        call cli_hexdump_byte) s
+261.667 478 M
+(        mov r24, r14) s
+261.667 470 M
+(        call cli_hexdump_byte) s
+261.667 462 M
+(        pop_range 30, 31) s
+261.667 454 M
+(        pop_range 16, 27) s
+261.667 446 M
+(        ret) s
+261.667 430 M
+(#endif) s
+_R
+S
+%%Trailer
+%%Pages: 8
+%%DocumentNeededResources: font Courier-Bold Courier 
+%%EOF
diff --git a/bmw/bmw_small.c b/bmw/bmw_small.c
new file mode 100644 (file)
index 0000000..036ac25
--- /dev/null
@@ -0,0 +1,605 @@
+/* bmw_small.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    bmw_small.c
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-04-27
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "bmw_small.h"
+#include "memxor.h"
+
+#define SHL32(a,n) ((a)<<(n))
+#define SHR32(a,n) ((a)>>(n))
+#define ROTL32(a,n) (((a)<<(n))|((a)>>(32-(n))))
+#define ROTR32(a,n) (((a)>>(n))|((a)<<(32-(n))))
+
+
+#define TWEAK   1
+#if TWEAK
+#  define BUG24   0
+#else
+#  define BUG24   1
+#endif
+
+#define F0_HACK 2
+
+#define DEBUG 0
+
+#ifndef F0_HACK
+#  define F0_HACK 0
+#endif
+
+#if DEBUG
+ #include "cli.h"
+
+ void ctx_dump(const bmw_small_ctx_t* ctx){
+       uint8_t i;
+       cli_putstr("\r\n==== ctx dump ====");
+       for(i=0; i<16;++i){
+               cli_putstr("\r\n h[");
+               cli_hexdump(&i, 1);
+               cli_putstr("] = ");
+               cli_hexdump_rev(&(ctx->h[i]), 4);
+       }
+       cli_putstr("\r\n counter = ");
+       cli_hexdump(&(ctx->counter), 4);
+ }
+
+ void dump_x(const uint32_t* q, uint8_t elements, char x){
+       uint8_t i;
+       cli_putstr("\r\n==== ");
+       cli_putc(x);
+       cli_putstr(" dump ====");
+       for(i=0; i<elements;++i){
+               cli_putstr("\r\n ");
+               cli_putc(x);
+               cli_putstr("[");
+               cli_hexdump(&i, 1);
+               cli_putstr("] = ");
+               cli_hexdump_rev(&(q[i]), 4);
+       }
+ }
+#else
+ #define ctx_dump(x)
+ #define dump_x(a,b,c)
+#endif
+
+static
+uint32_t bmw_small_s0(uint32_t x){
+       uint32_t r;
+       r =   SHR32(x, 1)
+               ^ SHL32(x, 3)
+               ^ ROTL32(x, 4)
+               ^ ROTR32(x, 13);
+       return r;
+}
+
+static
+uint32_t bmw_small_s1(uint32_t x){
+       uint32_t r;
+       r =   SHR32(x, 1)
+               ^ SHL32(x, 2)
+               ^ ROTL32(x, 8)
+               ^ ROTR32(x, 9);
+       return r;
+}
+
+static
+uint32_t bmw_small_s2(uint32_t x){
+       uint32_t r;
+       r =   SHR32(x, 2)
+               ^ SHL32(x, 1)
+               ^ ROTL32(x, 12)
+               ^ ROTR32(x, 7);
+       return r;
+}
+
+static
+uint32_t bmw_small_s3(uint32_t x){
+       uint32_t r;
+       r =   SHR32(x, 2)
+               ^ SHL32(x, 2)
+               ^ ROTL32(x, 15)
+               ^ ROTR32(x, 3);
+       return r;
+}
+
+static
+uint32_t bmw_small_s4(uint32_t x){
+       uint32_t r;
+       r =   SHR32(x, 1)
+               ^ x;
+       return r;
+}
+
+static
+uint32_t bmw_small_s5(uint32_t x){
+       uint32_t r;
+       r =   SHR32(x, 2)
+               ^ x;
+       return r;
+}
+
+static
+uint32_t bmw_small_r1(uint32_t x){
+       uint32_t r;
+       r =   ROTL32(x, 3);
+       return r;
+}
+
+static
+uint32_t bmw_small_r2(uint32_t x){
+       uint32_t r;
+       r =   ROTL32(x, 7);
+       return r;
+}
+
+static
+uint32_t bmw_small_r3(uint32_t x){
+       uint32_t r;
+       r =   ROTL32(x, 13);
+       return r;
+}
+
+static
+uint32_t bmw_small_r4(uint32_t x){
+       uint32_t r;
+       r =   ROTL32(x, 16);
+       return r;
+}
+
+static
+uint32_t bmw_small_r5(uint32_t x){
+       uint32_t r;
+       r =   ROTR32(x, 13);
+       return r;
+}
+
+static
+uint32_t bmw_small_r6(uint32_t x){
+       uint32_t r;
+       r =   ROTR32(x, 9);
+       return r;
+}
+
+static
+uint32_t bmw_small_r7(uint32_t x){
+       uint32_t r;
+       r =   ROTR32(x, 5);
+       return r;
+}
+/*
+#define K 0x05555555L
+static
+uint32_t k_lut[] PROGMEM = {
+       16L*K, 17L*K, 18L*K, 19L*K, 20L*K, 21L*K, 22L*K, 23L*K,
+       24L*K, 25L*K, 26L*K, 27L*K, 28L*K, 29L*K, 30L*K, 31L*K
+};
+*/
+/* same as above but precomputed to avoid compiler warnings */
+
+static
+uint32_t k_lut[] = {
+       0x55555550L, 0x5aaaaaa5L, 0x5ffffffaL,
+       0x6555554fL, 0x6aaaaaa4L, 0x6ffffff9L,
+       0x7555554eL, 0x7aaaaaa3L, 0x7ffffff8L,
+       0x8555554dL, 0x8aaaaaa2L, 0x8ffffff7L,
+       0x9555554cL, 0x9aaaaaa1L, 0x9ffffff6L,
+       0xa555554bL };
+
+static
+uint32_t bmw_small_expand1(uint8_t j, const uint32_t* q, const void* m, const void* h){
+       uint32_t(*s[])(uint32_t) = {bmw_small_s1, bmw_small_s2, bmw_small_s3, bmw_small_s0};
+       uint32_t r;
+       uint8_t i;
+       /* r = 0x05555555*(j+16); */
+
+#if TWEAK
+       r = (   ROTL32(((uint32_t*)m)[j&0xf],      ((j+0)&0xf)+1  )
+              + ROTL32(((uint32_t*)m)[(j+3)&0xf],  ((j+3)&0xf)+1  )
+              - ROTL32(((uint32_t*)m)[(j+10)&0xf], ((j+10)&0xf)+1 )
+              + k_lut[j]
+            ) ^ ((uint32_t*)h)[(j+7)&0xf];
+#else
+       r = k_lut[j];
+       r += ((uint32_t*)m)[j&0xf];
+       r += ((uint32_t*)m)[(j+3)&0xf];
+       r -= ((uint32_t*)m)[(j+10)&0xf];
+#endif
+       for(i=0; i<16; ++i){
+               r += s[i%4](q[j+i]);
+       }
+       return r;
+}
+
+static
+uint32_t bmw_small_expand2(uint8_t j, const uint32_t* q, const void* m, const void* h){
+       uint32_t(*rf[])(uint32_t) = {bmw_small_r1, bmw_small_r2, bmw_small_r3,
+                                    bmw_small_r4, bmw_small_r5, bmw_small_r6,
+                                                            bmw_small_r7};
+       uint32_t r=0;
+       uint8_t i;
+       for(i=0; i<14; i+=2){
+               r += q[j+i];
+       }
+       for(i=0; i<14; i+=2){
+               r += rf[i/2](q[j+i+1]);
+       }
+#if TWEAK
+       r += bmw_small_s4(q[j+14]);
+       r += bmw_small_s5(q[j+15]);
+#else
+       r += bmw_small_s5(q[j+14]);
+       r += bmw_small_s4(q[j+15]);
+#endif
+#if TWEAK
+       r += (   ROTL32(((uint32_t*)m)[j&0xf],      ((j+0)&0xf)+1  )
+              + ROTL32(((uint32_t*)m)[(j+3)&0xf],  ((j+3)&0xf)+1  )
+              - ROTL32(((uint32_t*)m)[(j+10)&0xf], ((j+10)&0xf)+1 )
+              + k_lut[j]
+            ) ^ ((uint32_t*)h)[(j+7)&0xf];
+#else
+       r += k_lut[j];
+       r += ((uint32_t*)m)[j&0xf];
+       r += ((uint32_t*)m)[(j+3)&0xf];
+       r -= ((uint32_t*)m)[(j+10)&0xf];
+#endif
+       return r;
+}
+
+#if F0_HACK==2
+/* to understand this implementation take a look at f0-opt-table.txt */
+static uint16_t hack_table[5] = { 0x0311, 0xDDB3, 0x2A79, 0x07AA, 0x51C2 };
+static uint8_t  offset_table[5] = { 4+16, 6+16, 9+16, 12+16, 13+16 };
+
+static
+void bmw_small_f0(uint32_t* q, uint32_t* h, const void* m){
+       uint16_t hack_reg;
+       uint8_t c,i,j;
+       uint32_t(*s[])(uint32_t)={ bmw_small_s0, bmw_small_s1, bmw_small_s2,
+                                  bmw_small_s3, bmw_small_s4 };
+       for(i=0; i<16; ++i){
+               ((uint32_t*)h)[i] ^= ((uint32_t*)m)[i];
+       }
+       dump_x(h, 16, 'T');
+       memset(q, 0, 4*16);
+       c=4;
+       do{
+               i=15;
+               j=offset_table[c];
+               hack_reg=hack_table[c];
+               do{
+                       if(hack_reg&1){
+                               q[i]-= h[j&15];
+                       }else{
+                               q[i]+= h[j&15];
+                       }
+                       --j;
+                       hack_reg>>= 1;
+               }while(i--!=0);
+       }while(c--!=0);
+       dump_x(q, 16, 'W');
+       for(i=0; i<16; ++i){
+               q[i] = s[i%5](q[i]);
+       }
+#if TWEAK
+       for(i=0; i<16; ++i){
+               ((uint32_t*)h)[i] ^= ((uint32_t*)m)[i];
+       }
+       for(i=0; i<16; ++i){
+               q[i] += h[(i+1)&0xf];
+       }
+#endif
+}
+#endif /* F0_HACK==2*/
+
+#if F0_HACK==1
+static
+uint8_t f0_lut[] PROGMEM = {
+        5<<1, ( 7<<1)+1, (10<<1)+0, (13<<1)+0, (14<<1)+0,
+        6<<1, ( 8<<1)+1, (11<<1)+0, (14<<1)+0, (15<<1)+1,
+        0<<1, ( 7<<1)+0, ( 9<<1)+0, (12<<1)+1, (15<<1)+0,
+        0<<1, ( 1<<1)+1, ( 8<<1)+0, (10<<1)+1, (13<<1)+0,
+        1<<1, ( 2<<1)+0, ( 9<<1)+0, (11<<1)+1, (14<<1)+1,
+        3<<1, ( 2<<1)+1, (10<<1)+0, (12<<1)+1, (15<<1)+0,
+        4<<1, ( 0<<1)+1, ( 3<<1)+1, (11<<1)+1, (13<<1)+0,
+        1<<1, ( 4<<1)+1, ( 5<<1)+1, (12<<1)+1, (14<<1)+1,
+        2<<1, ( 5<<1)+1, ( 6<<1)+1, (13<<1)+0, (15<<1)+1,
+        0<<1, ( 3<<1)+1, ( 6<<1)+0, ( 7<<1)+1, (14<<1)+0,
+        8<<1, ( 1<<1)+1, ( 4<<1)+1, ( 7<<1)+1, (15<<1)+0,
+        8<<1, ( 0<<1)+1, ( 2<<1)+1, ( 5<<1)+1, ( 9<<1)+0,
+        1<<1, ( 3<<1)+0, ( 6<<1)+1, ( 9<<1)+1, (10<<1)+0,
+        2<<1, ( 4<<1)+0, ( 7<<1)+0, (10<<1)+0, (11<<1)+0,
+        3<<1, ( 5<<1)+1, ( 8<<1)+0, (11<<1)+1, (12<<1)+1,
+       12<<1, ( 4<<1)+1, ( 6<<1)+1, ( 9<<1)+1, (13<<1)+0
+};
+
+static
+void bmw_small_f0(uint32_t* q, uint32_t* h, const void* m){
+       uint8_t i,j=-1,v,sign,l=0;
+       uint32_t(*s[])(uint32_t)={ bmw_small_s0, bmw_small_s1, bmw_small_s2,
+                                  bmw_small_s3, bmw_small_s4 };
+       for(i=0; i<16; ++i){
+               ((uint32_t*)h)[i] ^= ((uint32_t*)m)[i];
+       }
+       dump_x(h, 16, 'T');
+       // memset(q, 0, 4*16);
+       for(i=0; i<5*16; ++i){
+               v = pgm_read_byte(f0_lut+i);
+               sign = v&1;
+               v >>=1;
+               if(i==l){
+                       j++;
+                       l+=5;
+                       q[j] = h[v];
+                       continue;
+               }
+               if(sign){
+                       q[j] -= h[v];
+               }else{
+                       q[j] += h[v];
+               }
+       }
+       dump_x(q, 16, 'W');
+       for(i=0; i<16; ++i){
+               q[i] = s[i%5](q[i]);
+       }
+#if TWEAK
+       for(i=0; i<16; ++i){
+               ((uint32_t*)h)[i] ^= ((uint32_t*)m)[i];
+       }
+       for(i=0; i<16; ++i){
+               q[i] += h[(i+1)&0xf];
+       }
+#endif /* TWEAK */
+}
+#endif /* F0_HACK==1 */
+
+#if F0_HACK==0
+static
+void bmw_small_f0(uint32_t* q, uint32_t* h, const void* m){
+       uint8_t i;
+       uint32_t(*s[])(uint32_t)={ bmw_small_s0, bmw_small_s1, bmw_small_s2,
+                                  bmw_small_s3, bmw_small_s4 };
+       for(i=0; i<16; ++i){
+               ((uint32_t*)h)[i] ^= ((uint32_t*)m)[i];
+       }
+       dump_x(h, 16, 'T');
+       q[ 0] = (h[ 5] - h[ 7] + h[10] + h[13] + h[14]);
+       q[ 1] = (h[ 6] - h[ 8] + h[11] + h[14] - h[15]);
+       q[ 2] = (h[ 0] + h[ 7] + h[ 9] - h[12] + h[15]);
+       q[ 3] = (h[ 0] - h[ 1] + h[ 8] - h[10] + h[13]);
+       q[ 4] = (h[ 1] + h[ 2] + h[ 9] - h[11] - h[14]);
+       q[ 5] = (h[ 3] - h[ 2] + h[10] - h[12] + h[15]);
+       q[ 6] = (h[ 4] - h[ 0] - h[ 3] - h[11] + h[13]);
+       q[ 7] = (h[ 1] - h[ 4] - h[ 5] - h[12] - h[14]);
+       q[ 8] = (h[ 2] - h[ 5] - h[ 6] + h[13] - h[15]);
+       q[ 9] = (h[ 0] - h[ 3] + h[ 6] - h[ 7] + h[14]);
+       q[10] = (h[ 8] - h[ 1] - h[ 4] - h[ 7] + h[15]);
+       q[11] = (h[ 8] - h[ 0] - h[ 2] - h[ 5] + h[ 9]);
+       q[12] = (h[ 1] + h[ 3] - h[ 6] - h[ 9] + h[10]);
+       q[13] = (h[ 2] + h[ 4] + h[ 7] + h[10] + h[11]);
+       q[14] = (h[ 3] - h[ 5] + h[ 8] - h[11] - h[12]);
+       q[15] = (h[12] - h[ 4] - h[ 6] - h[ 9] + h[13]);
+       dump_x(q, 16, 'W');
+       for(i=0; i<16; ++i){
+               q[i] = s[i%5](q[i]);
+       }
+#if TWEAK
+       for(i=0; i<16; ++i){
+               ((uint32_t*)h)[i] ^= ((uint32_t*)m)[i];
+       }
+       for(i=0; i<16; ++i){
+               q[i] += h[(i+1)&0xf];
+       }
+#endif /* TWEAK */
+}
+#endif /* F0_HACK==0 */
+
+static
+void bmw_small_f1(uint32_t* q, const void* m, const void* h){
+       uint8_t i;
+       q[16] = bmw_small_expand1(0, q, m, h);
+       q[17] = bmw_small_expand1(1, q, m, h);
+       for(i=2; i<16; ++i){
+               q[16+i] = bmw_small_expand2(i, q, m, h);
+       }
+}
+
+static
+void bmw_small_f2(uint32_t* h, uint32_t* q, const void* m){
+       uint32_t xl=0, xh;
+       uint8_t i;
+       for(i=16;i<24;++i){
+               xl ^= q[i];
+       }
+       xh = xl;
+       for(i=24;i<32;++i){
+               xh ^= q[i];
+       }
+#if DEBUG
+       cli_putstr("\r\n XL = ");
+       cli_hexdump_rev(&xl, 4);
+       cli_putstr("\r\n XH = ");
+       cli_hexdump_rev(&xh, 4);
+#endif
+       memcpy(h, m, 16*4);
+       h[0] ^= SHL32(xh, 5) ^ SHR32(q[16], 5);
+       h[1] ^= SHR32(xh, 7) ^ SHL32(q[17], 8);
+       h[2] ^= SHR32(xh, 5) ^ SHL32(q[18], 5);
+       h[3] ^= SHR32(xh, 1) ^ SHL32(q[19], 5);
+       h[4] ^= SHR32(xh, 3) ^ q[20];
+       h[5] ^= SHL32(xh, 6) ^ SHR32(q[21], 6);
+       h[6] ^= SHR32(xh, 4) ^ SHL32(q[22], 6);
+       h[7] ^= SHR32(xh,11) ^ SHL32(q[23], 2);
+       for(i=0; i<8; ++i){
+               h[i] += xl ^ q[24+i] ^ q[i];
+       }
+       for(i=0; i<8; ++i){
+               h[8+i] ^= xh ^ q[24+i];
+               h[8+i] += ROTL32(h[(4+i)%8],i+9);
+       }
+/*
+       h[ 8] += SHL32(xl, 8) ^ q[23] ^ q[ 8];
+       h[ 9] += SHR32(xl, 6) ^ q[16] ^ q[ 9];
+       h[10] += SHL32(xl, 6) ^ q[17] ^ q[10];
+       h[11] += SHL32(xl, 4) ^ q[18] ^ q[11];
+       h[12] += SHR32(xl, 3) ^ q[19] ^ q[12];
+       h[13] += SHR32(xl, 4) ^ q[20] ^ q[13];
+       h[14] += SHR32(xl, 7) ^ q[21] ^ q[14];
+       h[15] += SHR32(xl, 2) ^ q[22] ^ q[15];
+*/
+       memxor(q+9, q+16, 7*4);
+       q[8] ^= q[23];
+       h[ 8] += SHL32(xl, 8) ^ q[ 8];
+       h[ 9] += SHR32(xl, 6) ^ q[ 9];
+       h[10] += SHL32(xl, 6) ^ q[10];
+       h[11] += SHL32(xl, 4) ^ q[11];
+       h[12] += SHR32(xl, 3) ^ q[12];
+       h[13] += SHR32(xl, 4) ^ q[13];
+       h[14] += SHR32(xl, 7) ^ q[14];
+       h[15] += SHR32(xl, 2) ^ q[15];
+
+}
+
+void bmw_small_nextBlock(bmw_small_ctx_t* ctx, const void* block){
+       uint32_t q[32];
+       dump_x(block, 16, 'M');
+       bmw_small_f0(q, ctx->h, block);
+       dump_x(q, 16, 'Q');
+       bmw_small_f1(q, block, ctx->h);
+       dump_x(q, 32, 'Q');
+       bmw_small_f2(ctx->h, q, block);
+       ctx->counter += 1;
+       ctx_dump(ctx);
+}
+
+void bmw_small_lastBlock(bmw_small_ctx_t* ctx, const void* block, uint16_t length_b){
+       uint8_t buffer[64];
+       while(length_b >= BMW_SMALL_BLOCKSIZE){
+               bmw_small_nextBlock(ctx, block);
+               length_b -= BMW_SMALL_BLOCKSIZE;
+               block = (uint8_t*)block + BMW_SMALL_BLOCKSIZE_B;
+       }
+       memset(buffer, 0, 64);
+       memcpy(buffer, block, (length_b+7)/8);
+       buffer[length_b>>3] |= 0x80 >> (length_b&0x07);
+       if(length_b+1>64*8-64){
+               bmw_small_nextBlock(ctx, buffer);
+               memset(buffer, 0, 64-8);
+               ctx->counter -= 1;
+       }
+       *((uint64_t*)&(buffer[64-8])) = (uint64_t)(ctx->counter*512LL)+(uint64_t)length_b;
+       bmw_small_nextBlock(ctx, buffer);
+#if TWEAK
+       uint8_t i;
+       uint32_t q[32];
+       memset(buffer, 0xaa, 64);
+       for(i=0; i<16;++i){
+               buffer[i*4] = i+0xa0;
+       }
+//     dump_x(buffer, 16, 'A');
+       dump_x(ctx->h, 16, 'M');
+       bmw_small_f0(q, (uint32_t*)buffer, ctx->h);
+       dump_x(buffer, 16, 'a');
+       dump_x(q, 16, 'Q');
+       bmw_small_f1(q, ctx->h, (uint32_t*)buffer);
+       dump_x(q, 32, 'Q');
+       bmw_small_f2((uint32_t*)buffer, q, ctx->h);
+       memcpy(ctx->h, buffer, 64);
+#endif
+}
+
+void bmw224_init(bmw224_ctx_t* ctx){
+       uint8_t i;
+       ctx->h[0] = 0x00010203;
+       for(i=1; i<16; ++i){
+               ctx->h[i] = ctx->h[i-1]+ 0x04040404;
+       }
+#if BUG24
+       ctx->h[13] = 0x24353637;
+#endif
+       ctx->counter=0;
+       ctx_dump(ctx);
+}
+
+void bmw256_init(bmw256_ctx_t* ctx){
+       uint8_t i;
+       ctx->h[0] = 0x40414243;
+       for(i=1; i<16; ++i){
+               ctx->h[i] = ctx->h[i-1]+ 0x04040404;
+       }
+       ctx->counter=0;
+       ctx_dump(ctx);
+}
+
+void bmw224_nextBlock(bmw224_ctx_t* ctx, const void* block){
+       bmw_small_nextBlock(ctx, block);
+}
+
+void bmw256_nextBlock(bmw256_ctx_t* ctx, const void* block){
+       bmw_small_nextBlock(ctx, block);
+}
+
+void bmw224_lastBlock(bmw224_ctx_t* ctx, const void* block, uint16_t length_b){
+       bmw_small_lastBlock(ctx, block, length_b);
+}
+
+void bmw256_lastBlock(bmw256_ctx_t* ctx, const void* block, uint16_t length_b){
+       bmw_small_lastBlock(ctx, block, length_b);
+}
+
+void bmw224_ctx2hash(void* dest, const bmw224_ctx_t* ctx){
+       memcpy(dest, &(ctx->h[9]), 224/8);
+}
+
+void bmw256_ctx2hash(void* dest, const bmw256_ctx_t* ctx){
+       memcpy(dest, &(ctx->h[8]), 256/8);
+}
+
+void bmw224(void* dest, const void* msg, uint32_t length_b){
+       bmw_small_ctx_t ctx;
+       bmw224_init(&ctx);
+       while(length_b>=BMW_SMALL_BLOCKSIZE){
+               bmw_small_nextBlock(&ctx, msg);
+               length_b -= BMW_SMALL_BLOCKSIZE;
+               msg = (uint8_t*)msg + BMW_SMALL_BLOCKSIZE_B;
+       }
+       bmw_small_lastBlock(&ctx, msg, length_b);
+       bmw224_ctx2hash(dest, &ctx);
+}
+
+void bmw256(void* dest, const void* msg, uint32_t length_b){
+       bmw_small_ctx_t ctx;
+       bmw256_init(&ctx);
+       while(length_b>=BMW_SMALL_BLOCKSIZE){
+               bmw_small_nextBlock(&ctx, msg);
+               length_b -= BMW_SMALL_BLOCKSIZE;
+               msg = (uint8_t*)msg + BMW_SMALL_BLOCKSIZE_B;
+       }
+       bmw_small_lastBlock(&ctx, msg, length_b);
+       bmw256_ctx2hash(dest, &ctx);
+}
+
diff --git a/bmw/bmw_small.h b/bmw/bmw_small.h
new file mode 100644 (file)
index 0000000..f314712
--- /dev/null
@@ -0,0 +1,65 @@
+/* bmw_small.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    bmw_small.h
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-04-27
+ * \license GPLv3 or later
+ * 
+ */
+#ifndef BMW_SMALL_H_
+#define BMW_SMALL_H_
+
+#include <stdint.h>
+
+#define BMW_SMALL_BLOCKSIZE   512
+#define BMW_SMALL_BLOCKSIZE_B ((BMW_SMALL_BLOCKSIZE+7)/8)
+#define BMW224_BLOCKSIZE      BMW_SMALL_BLOCKSIZE
+#define BMW224_BLOCKSIZE_B    BMW_SMALL_BLOCKSIZE_B
+#define BMW256_BLOCKSIZE      BMW_SMALL_BLOCKSIZE
+#define BMW256_BLOCKSIZE_B    BMW_SMALL_BLOCKSIZE_B
+
+typedef struct {
+       uint32_t h[16];
+       uint32_t counter;
+} bmw_small_ctx_t;
+
+typedef bmw_small_ctx_t bmw224_ctx_t;
+typedef bmw_small_ctx_t bmw256_ctx_t;
+
+void bmw224_init(bmw224_ctx_t* ctx);
+void bmw256_init(bmw256_ctx_t* ctx);
+
+void bmw_small_nextBlock(bmw_small_ctx_t* ctx, const void* block);
+void bmw_small_lastBlock(bmw_small_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void bmw224_nextBlock(bmw224_ctx_t* ctx, const void* block);
+void bmw224_lastBlock(bmw224_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void bmw256_nextBlock(bmw256_ctx_t* ctx, const void* block);
+void bmw256_lastBlock(bmw256_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void bmw224_ctx2hash(void* dest, const bmw224_ctx_t* ctx);
+void bmw256_ctx2hash(void* dest, const bmw256_ctx_t* ctx);
+
+void bmw224(void* dest, const void* msg, uint32_t length_b);
+void bmw256(void* dest, const void* msg, uint32_t length_b);
+
+#endif /* BMW_SMALL_H_ */
diff --git a/bmw/bmw_small_speed.c b/bmw/bmw_small_speed.c
new file mode 100644 (file)
index 0000000..982cb13
--- /dev/null
@@ -0,0 +1,376 @@
+/* bmw_small.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    bmw_small.c
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-04-27
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "bmw_small.h"
+#include "memxor.h"
+
+#define SHL32(a,n) ((a)<<(n))
+#define SHR32(a,n) ((a)>>(n))
+#define ROTL32(a,n) (((a)<<(n))|((a)>>(32-(n))))
+#define ROTR32(a,n) (((a)>>(n))|((a)<<(32-(n))))
+
+
+#define DEBUG 0
+
+
+#if DEBUG
+ #include "cli.h"
+
+ void ctx_dump(const bmw_small_ctx_t* ctx){
+       uint8_t i;
+       cli_putstr("\r\n==== ctx dump ====");
+       for(i=0; i<16;++i){
+               cli_putstr("\r\n h[");
+               cli_hexdump(&i, 1);
+               cli_putstr("] = ");
+               cli_hexdump_rev(&(ctx->h[i]), 4);
+       }
+       cli_putstr("\r\n counter = ");
+       cli_hexdump(&(ctx->counter), 4);
+ }
+
+ void dump_x(const uint32_t* q, uint8_t elements, char x){
+       uint8_t i;
+       cli_putstr("\r\n==== ");
+       cli_putc(x);
+       cli_putstr(" dump ====");
+       for(i=0; i<elements;++i){
+               cli_putstr("\r\n ");
+               cli_putc(x);
+               cli_putstr("[");
+               cli_hexdump(&i, 1);
+               cli_putstr("] = ");
+               cli_hexdump_rev(&(q[i]), 4);
+       }
+ }
+#else
+ #define ctx_dump(x)
+ #define dump_x(a,b,c)
+#endif
+
+#define S32_0(x) ( (SHR32((x),   1)) ^ \
+                      (SHL32((x),   3)) ^ \
+                      (ROTL32((x),  4)) ^ \
+                      (ROTR32((x), 13)) )
+
+#define S32_1(x) ( (SHR32((x),   1)) ^ \
+                      (SHL32((x),   2)) ^ \
+                      (ROTL32((x),  8)) ^ \
+                      (ROTR32((x),  9)) )
+
+#define S32_2(x) ( (SHR32((x),   2)) ^ \
+                      (SHL32((x),   1)) ^ \
+                      (ROTL32((x), 12)) ^ \
+                      (ROTR32((x),  7)) )
+
+#define S32_3(x) ( (SHR32((x),   2)) ^ \
+                      (SHL32((x),   2)) ^ \
+                      (ROTL32((x), 15)) ^ \
+                      (ROTR32((x),  3)) )
+
+#define S32_4(x) ( (SHR32((x),   1)) ^ (x))
+
+#define S32_5(x) ( (SHR32((x),   2)) ^ (x))
+
+#define R32_1(x)   (ROTL32((x),  3))
+#define R32_2(x)   (ROTL32((x),  7))
+#define R32_3(x)   (ROTL32((x), 13))
+#define R32_4(x)   (ROTL32((x), 16))
+#define R32_5(x)   (ROTR32((x), 13))
+#define R32_6(x)   (ROTR32((x),  9))
+#define R32_7(x)   (ROTR32((x),  5))
+/*
+#define K 0x05555555L
+static
+uint32_t k_lut[] PROGMEM = {
+       16L*K, 17L*K, 18L*K, 19L*K, 20L*K, 21L*K, 22L*K, 23L*K,
+       24L*K, 25L*K, 26L*K, 27L*K, 28L*K, 29L*K, 30L*K, 31L*K
+};
+*/
+/* same as above but precomputed to avoid compiler warnings */
+
+static
+uint32_t k_lut[] = {
+       0x55555550L, 0x5aaaaaa5L, 0x5ffffffaL,
+       0x6555554fL, 0x6aaaaaa4L, 0x6ffffff9L,
+       0x7555554eL, 0x7aaaaaa3L, 0x7ffffff8L,
+       0x8555554dL, 0x8aaaaaa2L, 0x8ffffff7L,
+       0x9555554cL, 0x9aaaaaa1L, 0x9ffffff6L,
+       0xa555554bL };
+
+static
+uint32_t bmw_small_expand1(uint8_t j, const uint32_t* q, const void* m, const void* h){
+       uint32_t r;
+       /* r = 0x05555555*(j+16); */
+       r = (   ROTL32(((uint32_t*)m)[j&0xf],      ((j+0)&0xf)+1  )
+              + ROTL32(((uint32_t*)m)[(j+3)&0xf],  ((j+3)&0xf)+1  )
+              - ROTL32(((uint32_t*)m)[(j+10)&0xf], ((j+10)&0xf)+1 )
+              + k_lut[j]
+            ) ^ ((uint32_t*)h)[(j+7)&0xf];
+       r += S32_1(q[j+ 0]) + S32_2(q[j+ 1]) + S32_3(q[j+ 2]) + S32_0(q[j+ 3]) +
+                S32_1(q[j+ 4]) + S32_2(q[j+ 5]) + S32_3(q[j+ 6]) + S32_0(q[j+ 7]) +
+                S32_1(q[j+ 8]) + S32_2(q[j+ 9]) + S32_3(q[j+10]) + S32_0(q[j+11]) +
+                S32_1(q[j+12]) + S32_2(q[j+13]) + S32_3(q[j+14]) + S32_0(q[j+15]);
+
+       return r;
+}
+
+static
+uint32_t bmw_small_expand2(uint8_t j, const uint32_t* q, const void* m, const void* h){
+       uint32_t r;
+       r = (   ROTL32(((uint32_t*)m)[j&0xf],      ((j+0)&0xf)+1  )
+              + ROTL32(((uint32_t*)m)[(j+3)&0xf],  ((j+3)&0xf)+1  )
+              - ROTL32(((uint32_t*)m)[(j+10)&0xf], ((j+10)&0xf)+1 )
+              + k_lut[j]
+            ) ^ ((uint32_t*)h)[(j+7)&0xf];
+       r += (q[j+ 0]) + R32_1(q[j+ 1]) + (q[j+ 2]) + R32_2(q[j+ 3]) +
+                (q[j+ 4]) + R32_3(q[j+ 5]) + (q[j+ 6]) + R32_4(q[j+ 7]) +
+                (q[j+ 8]) + R32_5(q[j+ 9]) + (q[j+10]) + R32_6(q[j+11]) +
+                (q[j+12]) + R32_7(q[j+13]) + S32_4(q[j+14]) + S32_5(q[j+15]);
+       return r;
+}
+
+
+static
+void bmw_small_f0(uint32_t* q, uint32_t* h, const void* m){
+       uint8_t i;
+       i=15;
+       do{
+               ((uint32_t*)h)[i] ^= ((uint32_t*)m)[i];
+       }while(i--);
+       dump_x(h, 16, 'T');
+       q[ 0] = (h[ 5] - h[ 7] + h[10] + h[13] + h[14]);
+       q[ 1] = (h[ 6] - h[ 8] + h[11] + h[14] - h[15]);
+       q[ 2] = (h[ 0] + h[ 7] + h[ 9] - h[12] + h[15]);
+       q[ 3] = (h[ 0] - h[ 1] + h[ 8] - h[10] + h[13]);
+       q[ 4] = (h[ 1] + h[ 2] + h[ 9] - h[11] - h[14]);
+       q[ 5] = (h[ 3] - h[ 2] + h[10] - h[12] + h[15]);
+       q[ 6] = (h[ 4] - h[ 0] - h[ 3] - h[11] + h[13]);
+       q[ 7] = (h[ 1] - h[ 4] - h[ 5] - h[12] - h[14]);
+       q[ 8] = (h[ 2] - h[ 5] - h[ 6] + h[13] - h[15]);
+       q[ 9] = (h[ 0] - h[ 3] + h[ 6] - h[ 7] + h[14]);
+       q[10] = (h[ 8] - h[ 1] - h[ 4] - h[ 7] + h[15]);
+       q[11] = (h[ 8] - h[ 0] - h[ 2] - h[ 5] + h[ 9]);
+       q[12] = (h[ 1] + h[ 3] - h[ 6] - h[ 9] + h[10]);
+       q[13] = (h[ 2] + h[ 4] + h[ 7] + h[10] + h[11]);
+       q[14] = (h[ 3] - h[ 5] + h[ 8] - h[11] - h[12]);
+       q[15] = (h[12] - h[ 4] - h[ 6] - h[ 9] + h[13]);
+       dump_x(q, 16, 'W');
+       q[ 0] = S32_0(q[ 0]); q[ 1] = S32_1(q[ 1]); q[ 2] = S32_2(q[ 2]); q[ 3] = S32_3(q[ 3]); q[ 4] = S32_4(q[ 4]);
+       q[ 5] = S32_0(q[ 5]); q[ 6] = S32_1(q[ 6]); q[ 7] = S32_2(q[ 7]); q[ 8] = S32_3(q[ 8]); q[ 9] = S32_4(q[ 9]);
+       q[10] = S32_0(q[10]); q[11] = S32_1(q[11]); q[12] = S32_2(q[12]); q[13] = S32_3(q[13]); q[14] = S32_4(q[14]);
+       q[15] = S32_0(q[15]);
+       i=15;
+       do{
+               q[(i+15)&15] += ((uint32_t*)h)[i] ^= ((uint32_t*)m)[i];
+       }while(i--);
+}
+
+static
+void bmw_small_f1(uint32_t* q, const void* m, const void* h){
+       uint8_t i;
+       q[16] = bmw_small_expand1(0, q, m, h);
+       q[17] = bmw_small_expand1(1, q, m, h);
+       for(i=2; i<16; ++i){
+               q[16+i] = bmw_small_expand2(i, q, m, h);
+       }
+}
+
+static
+void bmw_small_f2(uint32_t* h, uint32_t* q, const void* m){
+       uint32_t xl=0, xh;
+       uint8_t i;
+       for(i=16;i<24;++i){
+               xl ^= q[i];
+       }
+       xh = xl;
+       for(i=24;i<32;++i){
+               xh ^= q[i];
+       }
+#if DEBUG
+       cli_putstr("\r\n XL = ");
+       cli_hexdump_rev(&xl, 4);
+       cli_putstr("\r\n XH = ");
+       cli_hexdump_rev(&xh, 4);
+#endif
+       memcpy(h, m, 16*4);
+       h[0] ^= SHL32(xh, 5) ^ SHR32(q[16], 5);
+       h[1] ^= SHR32(xh, 7) ^ SHL32(q[17], 8);
+       h[2] ^= SHR32(xh, 5) ^ SHL32(q[18], 5);
+       h[3] ^= SHR32(xh, 1) ^ SHL32(q[19], 5);
+       h[4] ^= SHR32(xh, 3) ^ q[20];
+       h[5] ^= SHL32(xh, 6) ^ SHR32(q[21], 6);
+       h[6] ^= SHR32(xh, 4) ^ SHL32(q[22], 6);
+       h[7] ^= SHR32(xh,11) ^ SHL32(q[23], 2);
+       for(i=0; i<8; ++i){
+               h[i] += xl ^ q[24+i] ^ q[i];
+       }
+       for(i=0; i<8; ++i){
+               h[8+i] ^= xh ^ q[24+i];
+               h[8+i] += ROTL32(h[(4+i)%8],i+9);
+       }
+/*
+       h[ 8] += SHL32(xl, 8) ^ q[23] ^ q[ 8];
+       h[ 9] += SHR32(xl, 6) ^ q[16] ^ q[ 9];
+       h[10] += SHL32(xl, 6) ^ q[17] ^ q[10];
+       h[11] += SHL32(xl, 4) ^ q[18] ^ q[11];
+       h[12] += SHR32(xl, 3) ^ q[19] ^ q[12];
+       h[13] += SHR32(xl, 4) ^ q[20] ^ q[13];
+       h[14] += SHR32(xl, 7) ^ q[21] ^ q[14];
+       h[15] += SHR32(xl, 2) ^ q[22] ^ q[15];
+*/
+       i=6;
+       do{
+               q[9+i] ^= q[16+i];
+       }while(i--);
+       q[8] ^= q[23];
+       h[ 8] += SHL32(xl, 8) ^ q[ 8];
+       h[ 9] += SHR32(xl, 6) ^ q[ 9];
+       h[10] += SHL32(xl, 6) ^ q[10];
+       h[11] += SHL32(xl, 4) ^ q[11];
+       h[12] += SHR32(xl, 3) ^ q[12];
+       h[13] += SHR32(xl, 4) ^ q[13];
+       h[14] += SHR32(xl, 7) ^ q[14];
+       h[15] += SHR32(xl, 2) ^ q[15];
+}
+
+void bmw_small_nextBlock(bmw_small_ctx_t* ctx, const void* block){
+       uint32_t q[32];
+       dump_x(block, 16, 'M');
+       bmw_small_f0(q, ctx->h, block);
+       dump_x(q, 16, 'Q');
+       bmw_small_f1(q, block, ctx->h);
+       dump_x(q, 32, 'Q');
+       bmw_small_f2(ctx->h, q, block);
+       ctx->counter += 1;
+       ctx_dump(ctx);
+}
+
+void bmw_small_lastBlock(bmw_small_ctx_t* ctx, const void* block, uint16_t length_b){
+       uint8_t buffer[64];
+       while(length_b >= BMW_SMALL_BLOCKSIZE){
+               bmw_small_nextBlock(ctx, block);
+               length_b -= BMW_SMALL_BLOCKSIZE;
+               block = (uint8_t*)block + BMW_SMALL_BLOCKSIZE_B;
+       }
+       memset(buffer, 0, 64);
+       memcpy(buffer, block, (length_b+7)/8);
+       buffer[length_b>>3] |= 0x80 >> (length_b&0x07);
+       if(length_b+1>64*8-64){
+               bmw_small_nextBlock(ctx, buffer);
+               memset(buffer, 0, 64-8);
+               ctx->counter -= 1;
+       }
+       *((uint64_t*)&(buffer[64-8])) = (uint64_t)(ctx->counter*512LL)+(uint64_t)length_b;
+       bmw_small_nextBlock(ctx, buffer);
+       uint8_t i;
+       uint32_t q[32];
+       memset(buffer, 0xaa, 64);
+       for(i=0; i<16;++i){
+               buffer[i*4] = i+0xa0;
+       }
+//     dump_x(buffer, 16, 'A');
+       dump_x(ctx->h, 16, 'M');
+       bmw_small_f0(q, (uint32_t*)buffer, ctx->h);
+       dump_x(buffer, 16, 'a');
+       dump_x(q, 16, 'Q');
+       bmw_small_f1(q, ctx->h, (uint32_t*)buffer);
+       dump_x(q, 32, 'Q');
+       bmw_small_f2((uint32_t*)buffer, q, ctx->h);
+       memcpy(ctx->h, buffer, 64);
+}
+
+void bmw224_init(bmw224_ctx_t* ctx){
+       uint8_t i;
+       ctx->h[0] = 0x00010203;
+       for(i=1; i<16; ++i){
+               ctx->h[i] = ctx->h[i-1]+ 0x04040404;
+       }
+       ctx->counter=0;
+       ctx_dump(ctx);
+}
+
+void bmw256_init(bmw256_ctx_t* ctx){
+       uint8_t i;
+       ctx->h[0] = 0x40414243;
+       for(i=1; i<16; ++i){
+               ctx->h[i] = ctx->h[i-1]+ 0x04040404;
+       }
+       ctx->counter=0;
+       ctx_dump(ctx);
+}
+
+void bmw224_nextBlock(bmw224_ctx_t* ctx, const void* block){
+       bmw_small_nextBlock(ctx, block);
+}
+
+void bmw256_nextBlock(bmw256_ctx_t* ctx, const void* block){
+       bmw_small_nextBlock(ctx, block);
+}
+
+void bmw224_lastBlock(bmw224_ctx_t* ctx, const void* block, uint16_t length_b){
+       bmw_small_lastBlock(ctx, block, length_b);
+}
+
+void bmw256_lastBlock(bmw256_ctx_t* ctx, const void* block, uint16_t length_b){
+       bmw_small_lastBlock(ctx, block, length_b);
+}
+
+void bmw224_ctx2hash(void* dest, const bmw224_ctx_t* ctx){
+       memcpy(dest, &(ctx->h[9]), 224/8);
+}
+
+void bmw256_ctx2hash(void* dest, const bmw256_ctx_t* ctx){
+       memcpy(dest, &(ctx->h[8]), 256/8);
+}
+
+void bmw224(void* dest, const void* msg, uint32_t length_b){
+       bmw_small_ctx_t ctx;
+       bmw224_init(&ctx);
+       while(length_b>=BMW_SMALL_BLOCKSIZE){
+               bmw_small_nextBlock(&ctx, msg);
+               length_b -= BMW_SMALL_BLOCKSIZE;
+               msg = (uint8_t*)msg + BMW_SMALL_BLOCKSIZE_B;
+       }
+       bmw_small_lastBlock(&ctx, msg, length_b);
+       bmw224_ctx2hash(dest, &ctx);
+}
+
+void bmw256(void* dest, const void* msg, uint32_t length_b){
+       bmw_small_ctx_t ctx;
+       bmw256_init(&ctx);
+       while(length_b>=BMW_SMALL_BLOCKSIZE){
+               bmw_small_nextBlock(&ctx, msg);
+               length_b -= BMW_SMALL_BLOCKSIZE;
+               msg = (uint8_t*)msg + BMW_SMALL_BLOCKSIZE_B;
+       }
+       bmw_small_lastBlock(&ctx, msg, length_b);
+       bmw256_ctx2hash(dest, &ctx);
+}
+
diff --git a/bmw/f0-opt-table.txt b/bmw/f0-opt-table.txt
new file mode 100644 (file)
index 0000000..a35e6ad
--- /dev/null
@@ -0,0 +1,77 @@
+
+
+       q[ 0] = (+ h[ 5] - h[ 7] + h[10] + h[13] + h[14]);
+       q[ 1] = (+ h[ 6] - h[ 8] + h[11] + h[14] - h[15]);
+       q[ 2] = (+ h[ 7] + h[ 9] - h[12] + h[15] + h[ 0]);
+       q[ 3] = (+ h[ 8] - h[10] + h[13] + h[ 0] - h[ 1]);
+       q[ 4] = (+ h[ 9] - h[11] - h[14] + h[ 1] + h[ 2]);
+       q[ 5] = (+ h[10] - h[12] + h[15] - h[ 2] + h[ 3]);
+       q[ 6] = (- h[11] + h[13] - h[ 0] - h[ 3] + h[ 4]);
+       q[ 7] = (- h[12] - h[14] + h[ 1] - h[ 4] - h[ 5]);
+       q[ 8] = (+ h[13] - h[15] + h[ 2] - h[ 5] - h[ 6]);
+       q[ 9] = (+ h[14] + h[ 0] - h[ 3] + h[ 6] - h[ 7]);
+       q[10] = (+ h[15] - h[ 1] - h[ 4] - h[ 7] + h[ 8]);
+       q[11] = (- h[ 0] - h[ 2] - h[ 5] + h[ 8] + h[ 9]);
+       q[12] = (+ h[ 1] + h[ 3] - h[ 6] - h[ 9] + h[10]);
+       q[13] = (+ h[ 2] + h[ 4] + h[ 7] + h[10] + h[11]);
+       q[14] = (+ h[ 3] - h[ 5] + h[ 8] - h[11] - h[12]);
+       q[15] = (- h[ 4] - h[ 6] - h[ 9] + h[12] + h[13]);
+
+##########################################################
+
+1 := -
+0 := +
+
+
+     +---------- 0x0311
+     | +-------- 0xDDB3
+     | | +------ 0x2A79
+     | | | +---- 0x07AA
+     | | | | +-- 0x51C2
+     | | | | |
+---------------
+ 0:  0 1 0 0 0  + - + + +
+ 1:  0 1 0 0 1  + - + + -
+ 2:  0 0 1 0 0  + + - + +
+ 3:  0 1 0 0 1  + - + + -
+---------------
+ 4:  0 1 1 0 0  + - - + +
+ 5:  0 1 0 1 0  + - + - +
+ 6:  1 0 1 1 0  - + - - +
+ 7:  1 1 0 1 1  - - + - -
+---------------
+ 8:  0 1 0 1 1  + - + - -
+ 9:  0 0 1 0 1  + + - + -
+10:  0 1 1 1 0  + - - - +
+11:  1 1 1 0 0  - - - + +
+---------------
+12:  0 0 1 1 0  + + - - +
+13:  0 0 0 0 0  + + + + +
+14:  0 1 0 1 1  + - + - -
+15:  1 1 1 0 0  - - - + +
+---------------
+     | | | | |
+     | | | | +-- 0x438A
+     | | | +---- 0x55E0
+     | | +------ 0x9E54
+     | +-------- 0xCDBB
+     +---------- 0x88C0
+
+####################################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bmw/f0-opt-table2.txt b/bmw/f0-opt-table2.txt
new file mode 100644 (file)
index 0000000..7eb7488
--- /dev/null
@@ -0,0 +1,129 @@
+                  /-------------- 3 --------------\
+                  |                               |
+                  +-- 2 --v-- 3 --v-- 3 --v-- 1 --+
+                  |       |       |       |       |
+       q[ 0] = (+ h[ 5] - h[ 7] + h[10] + h[13] + h[14]);
+       q[ 1] = (+ h[ 6] - h[ 8] + h[11] + h[14] - h[15]);
+       q[ 2] = (+ h[ 7] + h[ 9] - h[12] + h[15] + h[ 0]);
+       q[ 3] = (+ h[ 8] - h[10] + h[13] + h[ 0] - h[ 1]);
+       q[ 4] = (+ h[ 9] - h[11] - h[14] + h[ 1] + h[ 2]);
+       q[ 5] = (+ h[10] - h[12] + h[15] - h[ 2] + h[ 3]);
+       q[ 6] = (- h[11] + h[13] - h[ 0] - h[ 3] + h[ 4]);
+       q[ 7] = (- h[12] - h[14] + h[ 1] - h[ 4] - h[ 5]);
+       q[ 8] = (+ h[13] - h[15] + h[ 2] - h[ 5] - h[ 6]);
+       q[ 9] = (+ h[14] + h[ 0] - h[ 3] + h[ 6] - h[ 7]);
+       q[10] = (+ h[15] - h[ 1] - h[ 4] - h[ 7] + h[ 8]);
+       q[11] = (- h[ 0] - h[ 2] - h[ 5] + h[ 8] + h[ 9]);
+       q[12] = (+ h[ 1] + h[ 3] - h[ 6] - h[ 9] + h[10]);
+       q[13] = (+ h[ 2] + h[ 4] + h[ 7] + h[10] + h[11]);
+       q[14] = (+ h[ 3] - h[ 5] + h[ 8] - h[11] - h[12]);
+       q[15] = (- h[ 4] - h[ 6] - h[ 9] + h[12] + h[13]);
+
+                                A       B       C       D       E       F       G   
+       q[ 0] = (+ h[ 5] - h[ 7] + h[10] + h[13] + h[14]);
+       q[ 3] = (+ h[ 8] - h[10] + h[13] + h[ 0] - h[ 1]);
+       q[ 6] = (- h[11] + h[13] - h[ 0] - h[ 3] + h[ 4]);
+       q[ 9] = (+ h[14] + h[ 0] - h[ 3] + h[ 6] - h[ 7]);
+       q[12] = (+ h[ 1] + h[ 3] - h[ 6] - h[ 9] + h[10]);
+       q[15] = (- h[ 4] - h[ 6] - h[ 9] + h[12] + h[13]);
+       q[ 2] = (+ h[ 7] + h[ 9] - h[12] + h[15] + h[ 0]);
+       q[ 5] = (+ h[10] - h[12] + h[15] - h[ 2] + h[ 3]);
+       q[ 8] = (+ h[13] - h[15] + h[ 2] - h[ 5] - h[ 6]);
+       q[11] = (- h[ 0] - h[ 2] - h[ 5] + h[ 8] + h[ 9]);
+       q[14] = (+ h[ 3] - h[ 5] + h[ 8] - h[11] - h[12]);
+       q[ 1] = (+ h[ 6] - h[ 8] + h[11] + h[14] - h[15]);
+       q[ 4] = (+ h[ 9] - h[11] - h[14] + h[ 1] + h[ 2]);
+       q[ 7] = (- h[12] - h[14] + h[ 1] - h[ 4] - h[ 5]);
+       q[10] = (+ h[15] - h[ 1] - h[ 4] - h[ 7] + h[ 8]);
+       q[13] = (+ h[ 2] + h[ 4] + h[ 7] + h[10] + h[11]);
+;-- (1)
+       Q = 0; A=5; B=7; C=10; D=13; E=14; F=11; G=8;
+       Q = * A * B * C * D * E
+       Q+=3; A=G; G=F; F=E; E+=3; B=C; C=D; D+=3; 
+;-- (2)
+             G=5; F=8; E=11; C=7; D=10;
+
+
+/* signs */
+
++-+++
++-++-
+-+--+
+++-+-
+++--+
+---++
+++-++
++-+-+
++-+--
+---++
++-+--
++-++-
++--++
+--+--
++---+
++++++
+
+ +---------- 0x4222 / 0x2224
+ | +-------- 0x3AF7 / 0x7FA3
+ | | +------ 0xC725 / 0x527C
+ | | | +---- 0x4956 / 0x6594
+ | | | | +-- 0x50D2 / 0x2D05
+ | | | | |
+;---------- 
+ 0 1 0 0 0  -- 0x08
+ 0 1 0 0 1  -- 0x09
+ 1 0 1 1 0  -- 0x16
+ 0 0 1 0 1  -- 0x05
+;----------
+ 0 0 1 1 0  -- 0x06
+ 1 1 1 0 0  -- 0x1C
+ 0 0 1 0 0  -- 0x04
+ 0 1 0 1 0  -- 0x0A
+;----------
+ 0 1 0 1 1  -- 0x0B
+ 1 1 1 0 0  -- 0x1C
+ 0 1 0 1 1  -- 0x0B
+ 0 1 0 0 1  -- 0x09
+;----------
+ 0 1 1 0 0  -- 0x0C
+ 1 1 0 1 1  -- 0x1B
+ 0 1 1 1 0  -- 0x0E
+ 0 0 0 0 0     -- 0x00
+ ;---------
+/* signs (in order 0..15) */
++-+++
++-++-
+++-++
++-++-
++--++
++-+-+
+-+--+
+--+--
++-+--
+++-+-
++---+
+---++
+++--+
++++++
++-+--
+---++
+ 0 1 0 0 0  -- 0x08
+ 0 1 0 0 1  -- 0x09
+ 0 0 1 0 0  -- 0x04
+ 0 1 0 0 1  -- 0x05
+ 0 1 1 0 0  -- 0x0C
+ 0 1 0 1 0  -- 0x0A
+ 1 0 1 1 0  -- 0x16
+ 1 1 0 1 1  -- 0x1D
+ 0 1 0 1 1  -- 0x0D
+ 0 0 1 0 1  -- 0x05
+ 0 1 1 1 0  -- 0x0E
+ 1 1 1 0 0  -- 0x1C
+ 0 0 1 1 0  -- 0x06
+ 0 0 0 0 0  -- 0x00
+ 0 1 0 1 1  -- 0x0D
+ 1 1 1 0 0  -- 0x1C
\ No newline at end of file
diff --git a/bmw/memxor.c b/bmw/memxor.c
new file mode 100644 (file)
index 0000000..7485b3e
--- /dev/null
@@ -0,0 +1,12 @@
+#include <stdint.h>
+
+#include "memxor.h"
+
+void memxor(void* dest, const void* src, uint16_t n){
+  while(n--){
+    *((uint8_t*)dest) ^= *((uint8_t*)src);
+    dest = (uint8_t*)dest +1;
+    src  = (uint8_t*)src  +1;
+  }
+}
+
diff --git a/bmw/memxor.h b/bmw/memxor.h
new file mode 100644 (file)
index 0000000..a62a616
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef MEMXOR_H_
+#define MEMXOR_H_
+#include <stdint.h>
+
+void memxor(void* dest, const void* src, uint16_t n);
+
+#endif
diff --git a/cubehash/cubehash.c b/cubehash/cubehash.c
new file mode 100644 (file)
index 0000000..72c0d75
--- /dev/null
@@ -0,0 +1,181 @@
+/* cubehash.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     cubehash.c
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte
+ * \date     2010-02-20
+ * \license  GPLv3 or later
+ *
+ */
+
+
+#include "memxor.h"
+#include "cubehash.h"
+#include <string.h>
+#include <stdint.h>
+
+static uint32_t rol32(uint32_t a, uint8_t r){
+       return (a<<r)|(a>>(32-r));
+}
+/*
+• Add    x_0jklm into    x_1jklm modulo 232 , for each (j, k, l, m).
+• Rotate x_0jklm upwards by 7 bits, for each (j, k, l, m).
+• Swap   x_00klm with    x_01klm , for each (k, l, m).
+• Xor    x_1jklm into    x_0jklm , for each (j, k, l, m).
+• Swap   x_1jk0m with    x_1jk1m , for each (j, k, m).
+• Add    x_0jklm into    x_1jklm modulo 232 , for each (j, k, l, m).
+• Rotate x_0jklm upwards by 11 bits, for each (j, k, l, m).
+• Swap   x_0j0lm with    x_0j1lm , for each (j, l, m).
+• Xor    x_1jklm into    x_0jklm , for each (j, k, l, m).
+• Swap   x_1jkl0 with    x_1jkl1 , for each (j, k, l).
+*/
+
+static void cubehash_round(cubehash_ctx_t* ctx){
+       uint8_t i;
+       uint32_t t;
+       for(i=0; i<16; ++i){
+               ctx->a[i+16] += ctx->a[i];
+       }
+       for(i=0; i<16; ++i){
+               ctx->a[i] = rol32(ctx->a[i], 7);
+       }
+       for(i=0; i<8; ++i){
+               t = ctx->a[i];
+               ctx->a[i] = ctx->a[i+8];
+               ctx->a[i+8] = t;
+       }
+       for(i=0; i<16; ++i){
+               ctx->a[i] ^= ctx->a[i+16];
+       }
+       for(i=16; i<4*4+16; i+=4){
+               t = ctx->a[i];
+               ctx->a[i] = ctx->a[i+2];
+               ctx->a[i+2] = t;
+               t = ctx->a[i+1];
+               ctx->a[i+1] = ctx->a[i+3];
+               ctx->a[i+3] = t;
+       }
+       for(i=0; i<16; ++i){
+               ctx->a[i+16] += ctx->a[i];
+       }
+       for(i=0; i<16; ++i){
+               ctx->a[i] = rol32(ctx->a[i], 11);
+       }
+       for(i=0; i<4; ++i){
+               t = ctx->a[i];
+               ctx->a[i] = ctx->a[i+4];
+               ctx->a[i+4] = t;
+       }
+       for(i=8; i<4+8; ++i){
+               t = ctx->a[i];
+               ctx->a[i] = ctx->a[i+4];
+               ctx->a[i+4] = t;
+       }
+       for(i=0; i<16; ++i){
+               ctx->a[i] ^= ctx->a[i+16];
+       }
+       for(i=16; i<16+16; i+=2){
+               t = ctx->a[i];
+               ctx->a[i] = ctx->a[i+1];
+               ctx->a[i+1] = t;
+       }
+}
+
+void cubehash_init(uint8_t r, uint8_t b, uint16_t h, cubehash_ctx_t* ctx){
+       memset(ctx->a, 0, 32*4);
+       ctx->a[0] = h/8;
+       ctx->a[1] = b;
+       ctx->a[2] = r;
+       ctx->rounds = r;
+       ctx->blocksize_B = b;
+       for(b=0; b<10*r; ++b){
+               cubehash_round(ctx);
+       }
+}
+
+void cubehash_nextBlock(cubehash_ctx_t* ctx, void* block){
+       uint8_t i;
+       memxor(ctx->a, block, ctx->blocksize_B);
+       for(i=0; i<ctx->rounds; ++i){
+               cubehash_round(ctx);
+       }
+}
+
+void cubehash_lastBlock(cubehash_ctx_t* ctx, void* block, uint16_t length_b){
+       while(length_b>=ctx->blocksize_B*8){
+               cubehash_nextBlock(ctx, block);
+               block = (uint8_t*)block + ctx->blocksize_B;
+               length_b -= ctx->blocksize_B*8;
+       }
+       uint8_t buffer[ctx->blocksize_B];
+       uint8_t i;
+       memset(buffer, 0, ctx->blocksize_B);
+       memcpy(buffer, block, (length_b+7)/8);
+       buffer[length_b/8] |= 0x80 >> (length_b&7);
+       cubehash_nextBlock(ctx, buffer);
+       ctx->a[31] ^= 1;
+       for(i=0; i<10*(ctx->rounds); ++i){
+               cubehash_round(ctx);
+       }
+}
+
+void cubehash_ctx2hash(void* dest, uint16_t length_b, cubehash_ctx_t* ctx){
+       memcpy(dest, ctx->a, (length_b+7)/8);
+}
+
+/******************************************************************************/
+
+void cubehash224_init(cubehash_ctx_t* ctx){
+       cubehash_init(16, 32, 224, ctx);
+}
+
+void cubehash224_ctx2hash(void* dest, cubehash_ctx_t* ctx){
+       cubehash_ctx2hash(dest, 224, ctx);
+}
+
+/******************************************************************************/
+
+void cubehash256_init(cubehash_ctx_t* ctx){
+       cubehash_init(16, 32, 256, ctx);
+}
+
+void cubehash256_ctx2hash(void* dest, cubehash_ctx_t* ctx){
+       cubehash_ctx2hash(dest, 256, ctx);
+}
+
+/******************************************************************************/
+
+void cubehash384_init(cubehash_ctx_t* ctx){
+       cubehash_init(16, 32, 384, ctx);
+}
+
+void cubehash384_ctx2hash(void* dest, cubehash_ctx_t* ctx){
+       cubehash_ctx2hash(dest, 384, ctx);
+}
+
+/******************************************************************************/
+
+void cubehash512_init(cubehash_ctx_t* ctx){
+       cubehash_init(16, 32, 512, ctx);
+}
+
+void cubehash512_ctx2hash(void* dest, cubehash_ctx_t* ctx){
+       cubehash_ctx2hash(dest, 512, ctx);
+}
diff --git a/cubehash/cubehash.h b/cubehash/cubehash.h
new file mode 100644 (file)
index 0000000..1f7b13a
--- /dev/null
@@ -0,0 +1,57 @@
+/* cubehash.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+
+#ifndef CUBEHASH_H_
+#define CUBEHASH_H_
+
+#include <stdint.h>
+
+#define CUBEHASH224_BLOCKSIZE 256
+#define CUBEHASH224_BLOCKSIZE_B ((CUBEHASH224_BLOCKSIZE+7)/8)
+#define CUBEHASH256_BLOCKSIZE 256
+#define CUBEHASH256_BLOCKSIZE_B ((CUBEHASH256_BLOCKSIZE+7)/8)
+#define CUBEHASH384_BLOCKSIZE 256
+#define CUBEHASH384_BLOCKSIZE_B ((CUBEHASH284_BLOCKSIZE+7)/8)
+#define CUBEHASH512_BLOCKSIZE 256
+#define CUBEHASH512_BLOCKSIZE_B ((CUBEHASH512_BLOCKSIZE+7)/8)
+
+typedef struct {
+       uint32_t a[32];
+       uint8_t rounds;
+       uint8_t blocksize_B;
+} cubehash_ctx_t;
+
+void cubehash_init(uint8_t r, uint8_t b, uint16_t h, cubehash_ctx_t* ctx);
+void cubehash_nextBlock(cubehash_ctx_t* ctx, void* block);
+void cubehash_lastBlock(cubehash_ctx_t* ctx, void* block, uint16_t length_b);
+void cubehash_ctx2hash(void* dest, uint16_t length_b, cubehash_ctx_t* ctx);
+
+void cubehash224_init(cubehash_ctx_t* ctx);
+void cubehash224_ctx2hash(void* dest, cubehash_ctx_t* ctx);
+
+void cubehash256_init(cubehash_ctx_t* ctx);
+void cubehash256_ctx2hash(void* dest, cubehash_ctx_t* ctx);
+
+void cubehash384_init(cubehash_ctx_t* ctx);
+void cubehash384_ctx2hash(void* dest, cubehash_ctx_t* ctx);
+
+void cubehash512_init(cubehash_ctx_t* ctx);
+void cubehash512_ctx2hash(void* dest, cubehash_ctx_t* ctx);
+
+#endif /* CUBEHASH_H_ */
diff --git a/cubehash/memxor.c b/cubehash/memxor.c
new file mode 100644 (file)
index 0000000..7485b3e
--- /dev/null
@@ -0,0 +1,12 @@
+#include <stdint.h>
+
+#include "memxor.h"
+
+void memxor(void* dest, const void* src, uint16_t n){
+  while(n--){
+    *((uint8_t*)dest) ^= *((uint8_t*)src);
+    dest = (uint8_t*)dest +1;
+    src  = (uint8_t*)src  +1;
+  }
+}
+
diff --git a/cubehash/memxor.h b/cubehash/memxor.h
new file mode 100644 (file)
index 0000000..a62a616
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef MEMXOR_H_
+#define MEMXOR_H_
+#include <stdint.h>
+
+void memxor(void* dest, const void* src, uint16_t n);
+
+#endif
diff --git a/echo/aes_enc_round.c b/echo/aes_enc_round.c
new file mode 100644 (file)
index 0000000..20ebd98
--- /dev/null
@@ -0,0 +1,78 @@
+/* aes-round.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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 <stdint.h>
+#include "aes_enc_round.h"
+#include "gf256mul.h"
+#include "aes_sbox.h"
+
+static
+void aes_shiftcol(void* data, uint8_t shift){
+       uint8_t tmp[4];
+       tmp[0] = ((uint8_t*)data)[ 0];
+       tmp[1] = ((uint8_t*)data)[ 4];
+       tmp[2] = ((uint8_t*)data)[ 8];
+       tmp[3] = ((uint8_t*)data)[12];
+       ((uint8_t*)data)[ 0] = tmp[(shift+0)&3];
+       ((uint8_t*)data)[ 4] = tmp[(shift+1)&3];
+       ((uint8_t*)data)[ 8] = tmp[(shift+2)&3];
+       ((uint8_t*)data)[12] = tmp[(shift+3)&3];
+}
+
+#define GF256MUL_1(a) (a)
+#define GF256MUL_2(a) (gf256mul(2, (a), 0x1b))
+#define GF256MUL_3(a) (gf256mul(3, (a), 0x1b))
+
+void aes_enc_round(aes_cipher_state_t* state, const aes_roundkey_t* k){
+       uint8_t tmp[16], t;
+       uint8_t i;
+       /* subBytes */
+       for(i=0; i<16; ++i){
+               tmp[i] = aes_sbox[state->s[i]];
+       }
+       /* shiftRows */
+       aes_shiftcol(tmp+1, 1);
+       aes_shiftcol(tmp+2, 2);
+       aes_shiftcol(tmp+3, 3);
+       /* mixColums */
+       for(i=0; i<4; ++i){
+               t = tmp[4*i+0] ^ tmp[4*i+1] ^ tmp[4*i+2] ^ tmp[4*i+3];
+               state->s[4*i+0] =
+                         GF256MUL_2(tmp[4*i+0]^tmp[4*i+1])
+                       ^ tmp[4*i+0]
+                       ^ t;
+               state->s[4*i+1] =
+                         GF256MUL_2(tmp[4*i+1]^tmp[4*i+2])
+                       ^ tmp[4*i+1]
+                       ^ t;
+               state->s[4*i+2] =
+                         GF256MUL_2(tmp[4*i+2]^tmp[4*i+3])
+                       ^ tmp[4*i+2]
+                       ^ t;
+               state->s[4*i+3] =
+                         GF256MUL_2(tmp[4*i+3]^tmp[4*i+0])
+                       ^ tmp[4*i+3]
+                       ^ t;
+       }
+
+       /* addKey */
+       for(i=0; i<16; ++i){
+               state->s[i] ^= k->ks[i];
+       }
+}
diff --git a/echo/aes_enc_round.h b/echo/aes_enc_round.h
new file mode 100644 (file)
index 0000000..7490500
--- /dev/null
@@ -0,0 +1,34 @@
+/* aes_enc_round.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+
+#ifndef AES_ENC_ROUND_H_
+#define AES_ENC_ROUND_H_
+
+typedef struct{
+       uint8_t s[16];
+} aes_cipher_state_t;
+
+typedef struct{
+       uint8_t ks[16];
+} aes_roundkey_t;
+
+void aes_enc_round(aes_cipher_state_t* state, const aes_roundkey_t* k);
+
+
+#endif /* AES_ENC_ROUND_H_ */
diff --git a/echo/aes_sbox.c b/echo/aes_sbox.c
new file mode 100644 (file)
index 0000000..73849dd
--- /dev/null
@@ -0,0 +1,39 @@
+/* aes sbox */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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 <stdint.h>
+const uint8_t aes_sbox[256] = {
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+};
+
diff --git a/echo/aes_sbox.h b/echo/aes_sbox.h
new file mode 100644 (file)
index 0000000..421b576
--- /dev/null
@@ -0,0 +1,33 @@
+/* aes_sbox.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     aes_sbox.h
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2008-12-30
+ * \license  GPLv3 or later
+ * 
+ */
+#ifndef AES_SBOX_H_
+#define AES_SBOX_H_
+#include <stdint.h>
+
+extern const uint8_t aes_sbox[];
+
+#endif
diff --git a/echo/echo.c b/echo/echo.c
new file mode 100644 (file)
index 0000000..97ab73c
--- /dev/null
@@ -0,0 +1,335 @@
+/* echo.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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 "echo.h"
+#include "gf256mul.h"
+#include "memxor.h"
+#include "aes_enc_round.h"
+#include <stdint.h>
+#include <string.h>
+
+#ifdef DEBUG
+#undef DEBUG
+#endif
+
+#define DEBUG 0
+
+#if DEBUG
+#define DEBUG_DEPTH 2
+#include "cli.h"
+#endif
+
+
+#define INDEX(c,r) ((c)*16*4+(r)*16)
+
+#define GF256MUL_1(a) (a)
+#define GF256MUL_2(a) (gf256mul(2, (a), 0x1b))
+#define GF256MUL_3(a) (gf256mul(3, (a), 0x1b))
+
+static void mixcol(uint8_t* s){
+       uint8_t t, tmp[4];
+       tmp[0] = *(s+16*0);
+       tmp[1] = *(s+16*1);
+       tmp[2] = *(s+16*2);
+       tmp[3] = *(s+16*3);
+
+       t = tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3];
+       *(s+16*0) =
+                 GF256MUL_2(tmp[0]^tmp[1])
+               ^ tmp[0]
+               ^ t;
+       *(s+16*1) =
+                 GF256MUL_2(tmp[1]^tmp[2])
+               ^ tmp[1]
+               ^ t;
+       *(s+16*2) =
+                 GF256MUL_2(tmp[2]^tmp[3])
+               ^ tmp[2]
+               ^ t;
+       *(s+16*3) =
+                 GF256MUL_2(tmp[3]^tmp[0])
+               ^ tmp[3]
+               ^ t;
+}
+
+#if DEBUG
+static void dump_state(void* s){
+       uint8_t row, col;
+       for(col=0; col<4; col++){
+               for(row=0; row<4; row++){
+                       cli_putstr("\r\nrow ");
+                       cli_putc('0'+row);
+                       cli_putstr(", col ");
+                       cli_putc('0'+col);
+                       cli_putstr(": ");
+                       cli_hexdump((uint8_t*)s+col*16*4+row*16, 4);
+                       cli_putc(' ');
+                       cli_hexdump((uint8_t*)s+col*16*4+row*16+ 4, 4);
+                       cli_putc(' ');
+                       cli_hexdump((uint8_t*)s+col*16*4+row*16+ 8, 4);
+                       cli_putc(' ');
+                       cli_hexdump((uint8_t*)s+col*16*4+row*16+12, 4);
+               }
+       }
+}
+#endif
+
+static void echo_compress(uint8_t* s, uint8_t iterations, uint64_t* c, void* salt){
+       uint8_t i, j;
+       uint8_t k[16];
+#if DEBUG
+       uint8_t round=0;
+#endif
+       memcpy(k, c, 8);
+       memset(k+8, 0, 8);
+       do{
+               /* BIG.SubWords */
+#if DEBUG
+       cli_putstr("\r\n === ROUND ");
+       cli_putc('0'+round);
+       cli_putstr(" ===");
+       if(round<DEBUG_DEPTH){
+               dump_state(s);
+       }
+#endif
+               for(i=0; i<16; ++i){
+                       aes_enc_round((aes_cipher_state_t*)(s+16*i), (aes_roundkey_t*)k);
+                       aes_enc_round((aes_cipher_state_t*)(s+16*i), (aes_roundkey_t*)salt);
+                       *((uint64_t*)(k)) += 1;
+               }
+#if DEBUG
+               if(round<DEBUG_DEPTH){
+                       cli_putstr("\r\nAfter SubWords");
+                       dump_state(s);
+               }
+#endif
+               /* BIG.ShiftRows */
+               uint8_t t[16];
+               /* "Row" 1 */
+               memcpy(t,             s+INDEX(0, 1), 16);
+               memcpy(s+INDEX(0, 1), s+INDEX(1, 1), 16);
+               memcpy(s+INDEX(1, 1), s+INDEX(2, 1), 16);
+               memcpy(s+INDEX(2, 1), s+INDEX(3, 1), 16);
+               memcpy(s+INDEX(3, 1), t,             16);
+               /* "Row" 2 */
+               memcpy(t,             s+INDEX(0, 2), 16);
+               memcpy(s+INDEX(0, 2), s+INDEX(2, 2), 16);
+               memcpy(s+INDEX(2, 2), t,             16);
+               memcpy(t,             s+INDEX(1, 2), 16);
+               memcpy(s+INDEX(1, 2), s+INDEX(3, 2), 16);
+               memcpy(s+INDEX(3, 2), t,             16);
+               /* "Row" 3 */
+               memcpy(t,             s+INDEX(0, 3), 16);
+               memcpy(s+INDEX(0, 3), s+INDEX(3, 3), 16);
+               memcpy(s+INDEX(3, 3), s+INDEX(2, 3), 16);
+               memcpy(s+INDEX(2, 3), s+INDEX(1, 3), 16);
+               memcpy(s+INDEX(1, 3), t,             16);
+#if DEBUG
+               if(round<DEBUG_DEPTH){
+                       cli_putstr("\r\nAfter ShiftRows");
+                       dump_state(s);
+               }
+#endif
+               /* BIG.MixColumns */
+               for(i=0; i<4; i+=1){
+                       for(j=0; j<16; ++j){
+                               mixcol(s+i*64+j);
+                       }
+               }
+#if DEBUG
+               if(round<DEBUG_DEPTH){
+                       cli_putstr("\r\nAfter MixColumns");
+                       dump_state(s);
+               }
+               round++;
+#endif
+       }while(--iterations);
+
+}
+
+/******************************************************************************/
+
+static void compress512(void* v, void* m, uint64_t* c, void* salt){
+       uint8_t s[16*16];
+       uint8_t i;
+       memcpy(s, v, 16*4);           /* load v into state */
+       memcpy(s+16*4, m, 16*12);     /* load m into state */
+
+       echo_compress(s, 8, c, salt);
+
+       /* BIG.Final */
+       for(i=0; i<3; ++i){
+               memxor(v, (uint8_t*)m+4*16*i, 4*16);
+       }
+       for(i=0; i<4; ++i){
+               memxor(v, s+4*16*i, 4*16);
+       }
+}
+
+static void compress1024(void* v, void* m, uint64_t* c, void* salt){
+       uint8_t s[16*16];
+       memcpy(s, v, 16*8);           /* load v into state */
+       memcpy(s+16*8, m, 16*8);      /* load m into state */
+
+       echo_compress(s, 10, c, salt);
+
+       /* BIG.Final */
+       memxor(v, m, 16*8);
+       memxor(v, s, 16*8);
+       memxor(v, s+16*8, 16*8);
+}
+
+/******************************************************************************/
+
+void echo_small_nextBlock(echo_small_ctx_t* ctx, void* block){
+       ctx->counter += ECHO_SMALL_BLOCKSIZE;
+       compress512(ctx->v, block, &(ctx->counter), ctx->salt);
+}
+
+void echo_small_lastBlock(echo_small_ctx_t* ctx, void* block, uint16_t length_b){
+       while(length_b>=ECHO_SMALL_BLOCKSIZE){
+               echo_small_nextBlock(ctx, block);
+               block = (uint8_t*)block + ECHO_SMALL_BLOCKSIZE_B;
+               length_b -= ECHO_SMALL_BLOCKSIZE;
+       }
+       uint8_t buffer[ECHO_SMALL_BLOCKSIZE_B];
+       uint64_t total_len;
+       memset(buffer, 0, ECHO_SMALL_BLOCKSIZE_B);
+       memcpy(buffer, block, (length_b+7)/8);
+       buffer[length_b/8] |= 0x80 >> (length_b&7);
+       total_len = (ctx->counter += length_b);
+       if(length_b>=ECHO_SMALL_BLOCKSIZE-144){
+               compress512(ctx->v, buffer, &total_len, ctx->salt);
+               memset(buffer, 0, ECHO_SMALL_BLOCKSIZE_B);
+               ctx->counter = 0;
+       }
+       if(length_b==0){
+               ctx->counter = 0;
+       }
+       memcpy(buffer+ECHO_SMALL_BLOCKSIZE_B-18, &(ctx->id), 2);
+       memcpy(buffer+ECHO_SMALL_BLOCKSIZE_B-16, &total_len, 8);
+       compress512(ctx->v, buffer, &(ctx->counter), ctx->salt);
+}
+
+/******************************************************************************/
+
+void echo_large_nextBlock(echo_large_ctx_t* ctx, void* block){
+       ctx->counter += ECHO_LARGE_BLOCKSIZE;
+       compress1024(ctx->v, block, &(ctx->counter), ctx->salt);
+}
+
+void echo_large_lastBlock(echo_large_ctx_t* ctx, void* block, uint16_t length_b){
+       while(length_b>=ECHO_LARGE_BLOCKSIZE){
+               echo_large_nextBlock(ctx, block);
+               block = (uint8_t*)block + ECHO_LARGE_BLOCKSIZE_B;
+               length_b -= ECHO_LARGE_BLOCKSIZE;
+       }
+       uint8_t buffer[ECHO_LARGE_BLOCKSIZE_B];
+       uint64_t total_len;
+       memset(buffer, 0, ECHO_LARGE_BLOCKSIZE_B);
+       memcpy(buffer, block, (length_b+7)/8);
+       buffer[length_b/8] |= 0x80 >> (length_b&7);
+       total_len = (ctx->counter += length_b);
+       if(length_b>=ECHO_LARGE_BLOCKSIZE-144){
+               compress1024(ctx->v, buffer, &total_len, ctx->salt);
+               memset(buffer, 0, ECHO_LARGE_BLOCKSIZE_B);
+               ctx->counter = 0;
+       }
+       if(length_b==0){
+               ctx->counter = 0;
+       }
+       memcpy(buffer+ECHO_LARGE_BLOCKSIZE_B-18, &(ctx->id), 2);
+       memcpy(buffer+ECHO_LARGE_BLOCKSIZE_B-16, &total_len, 8);
+       compress1024(ctx->v, buffer, &(ctx->counter), ctx->salt);
+}
+/******************************************************************************/
+
+void echo_ctx2hash(void* dest, uint16_t length_b, echo_small_ctx_t* ctx){
+       memcpy(dest, ctx->v, (length_b+7)/8);
+}
+
+void echo224_ctx2hash(void* dest, echo_small_ctx_t* ctx){
+       memcpy(dest, ctx->v, 224/8);
+}
+
+void echo256_ctx2hash(void* dest, echo_small_ctx_t* ctx){
+       memcpy(dest, ctx->v, 256/8);
+}
+
+/******************************************************************************/
+
+void echo384_ctx2hash(void* dest, echo_large_ctx_t* ctx){
+       memcpy(dest, ctx->v, 384/8);
+}
+
+void echo512_ctx2hash(void* dest, echo_large_ctx_t* ctx){
+       memcpy(dest, ctx->v, 512/8);
+}
+
+/******************************************************************************/
+
+void echo224_init(echo_small_ctx_t* ctx){
+       memset(ctx->v, 0, 4*16);
+       ctx->counter = 0;
+       memset(ctx->salt, 0, 16);
+       ctx->id = 0x00E0;
+       ctx->v[0+16*0] = 0xE0;
+       ctx->v[0+16*1] = 0xE0;
+       ctx->v[0+16*2] = 0xE0;
+       ctx->v[0+16*3] = 0xE0;
+}
+
+void echo256_init(echo_small_ctx_t* ctx){
+       memset(ctx->v, 0, 4*16);
+       ctx->counter = 0;
+       memset(ctx->salt, 0, 16);
+       ctx->id = 0x0100;
+       ctx->v[1+16*0] = 0x01;
+       ctx->v[1+16*1] = 0x01;
+       ctx->v[1+16*2] = 0x01;
+       ctx->v[1+16*3] = 0x01;
+}
+
+/******************************************************************************/
+
+void echo384_init(echo_large_ctx_t* ctx){
+       uint8_t i;
+       memset(ctx->v, 0, 8*16);
+       ctx->counter = 0;
+       memset(ctx->salt, 0, 16);
+       ctx->id = 0x0180;
+       for(i=0; i<8; ++i){
+               ctx->v[0+16*i] = 0x80;
+               ctx->v[1+16*i] = 0x01;
+       }
+}
+
+void echo512_init(echo_large_ctx_t* ctx){
+       uint8_t i;
+       memset(ctx->v, 0, 8*16);
+       ctx->counter = 0;
+       memset(ctx->salt, 0, 16);
+       ctx->id = 0x0200;
+       for(i=0; i<8; ++i){
+               ctx->v[1+16*i] = 0x02;
+       }
+}
+
+/******************************************************************************/
diff --git a/echo/echo.h b/echo/echo.h
new file mode 100644 (file)
index 0000000..5b3df55
--- /dev/null
@@ -0,0 +1,69 @@
+/* echo.h */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+
+#ifndef ECHO_H_
+#define ECHO_H_
+
+#include <stdint.h>
+
+#define ECHO_SMALL_BLOCKSIZE 1536
+#define ECHO_SMALL_BLOCKSIZE_B ((ECHO_SMALL_BLOCKSIZE+7)/8)
+#define ECHO_LARGE_BLOCKSIZE 1024
+#define ECHO_LARGE_BLOCKSIZE_B ((ECHO_LARGE_BLOCKSIZE+7)/8)
+
+#define ECHO224_BLOCKSIZE ECHO_SMALL_BLOCKSIZE
+#define ECHO224_BLOCKSIZE_B ((ECHO224_BLOCKSIZE+7)/8)
+#define ECHO256_BLOCKSIZE ECHO_SMALL_BLOCKSIZE
+#define ECHO256_BLOCKSIZE_B ((ECHO256_BLOCKSIZE+7)/8)
+#define ECHO384_BLOCKSIZE ECHO_LARGE_BLOCKSIZE
+#define ECHO384_BLOCKSIZE_B ((ECHO384_BLOCKSIZE+7)/8)
+#define ECHO512_BLOCKSIZE ECHO_LARGE_BLOCKSIZE
+#define ECHO512_BLOCKSIZE_B ((ECHO512_BLOCKSIZE+7)/8)
+
+typedef struct{
+       uint8_t v[4*16];
+       uint8_t salt[16];
+       uint64_t counter;
+       uint16_t id;
+}echo_small_ctx_t;
+
+typedef struct{
+       uint8_t v[8*16];
+       uint8_t salt[16];
+       uint64_t counter;
+       uint16_t id;
+}echo_large_ctx_t;
+
+void echo_small_nextBlock(echo_small_ctx_t* ctx, void* block);
+void echo_small_lastBlock(echo_small_ctx_t* ctx, void* block, uint16_t length_b);
+void echo_small_ctx2hash(void* dest, uint16_t length_b, echo_small_ctx_t* ctx);
+void echo224_ctx2hash(void* dest, echo_small_ctx_t* ctx);
+void echo256_ctx2hash(void* dest, echo_small_ctx_t* ctx);
+void echo224_init(echo_small_ctx_t* ctx);
+void echo256_init(echo_small_ctx_t* ctx);
+
+void echo_large_nextBlock(echo_large_ctx_t* ctx, void* block);
+void echo_large_lastBlock(echo_large_ctx_t* ctx, void* block, uint16_t length_b);
+void echo_large_ctx2hash(void* dest, uint16_t length_b, echo_large_ctx_t* ctx);
+void echo384_ctx2hash(void* dest, echo_large_ctx_t* ctx);
+void echo512_ctx2hash(void* dest, echo_large_ctx_t* ctx);
+void echo384_init(echo_large_ctx_t* ctx);
+void echo512_init(echo_large_ctx_t* ctx);
+
+#endif /* ECHO_H_ */
diff --git a/echo/gf256mul.c b/echo/gf256mul.c
new file mode 100644 (file)
index 0000000..a473646
--- /dev/null
@@ -0,0 +1,40 @@
+/* gf256mul.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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 <stdint.h>
+
+uint8_t gf256mul(uint8_t a, uint8_t b, uint8_t reducer){
+       uint8_t r=0;
+       while(a&0xFE){
+               if(a&1){
+                       r ^= b;
+               }
+               a >>= 1;
+               if(b&0x80){
+                       b <<= 1;
+                       b ^= reducer;
+               }else{
+                       b <<= 1;
+               }
+       }
+       if(a&1){
+               r ^= b;
+       }
+       return r;
+}
diff --git a/echo/gf256mul.h b/echo/gf256mul.h
new file mode 100644 (file)
index 0000000..87f1cb3
--- /dev/null
@@ -0,0 +1,37 @@
+/* gf256mul.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+#ifndef GF256MUL_H_
+#define GF256MUL_H_
+
+/**
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2008-12-19
+ * \license GPLv3
+ * \brief
+ * 
+ * 
+ */
+
+#include <stdint.h>
+
+uint8_t gf256mul(uint8_t a, uint8_t b, uint8_t reducer);
+
+#endif /* GF256MUL_H_ */
+
diff --git a/echo/memxor.c b/echo/memxor.c
new file mode 100644 (file)
index 0000000..7485b3e
--- /dev/null
@@ -0,0 +1,12 @@
+#include <stdint.h>
+
+#include "memxor.h"
+
+void memxor(void* dest, const void* src, uint16_t n){
+  while(n--){
+    *((uint8_t*)dest) ^= *((uint8_t*)src);
+    dest = (uint8_t*)dest +1;
+    src  = (uint8_t*)src  +1;
+  }
+}
+
diff --git a/echo/memxor.h b/echo/memxor.h
new file mode 100644 (file)
index 0000000..a62a616
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef MEMXOR_H_
+#define MEMXOR_H_
+#include <stdint.h>
+
+void memxor(void* dest, const void* src, uint16_t n);
+
+#endif
diff --git a/gdb-debug b/gdb-debug
new file mode 100644 (file)
index 0000000..4bb1531
--- /dev/null
+++ b/gdb-debug
@@ -0,0 +1,3 @@
+target remote localhost:3333
+set remote hardware-breakpoint-limit 6
+set remote hardware-watchpoint-limit 4
diff --git a/gdb-flash b/gdb-flash
new file mode 100644 (file)
index 0000000..fcb62eb
--- /dev/null
+++ b/gdb-flash
@@ -0,0 +1,7 @@
+target remote localhost:3333
+set remote hardware-breakpoint-limit 6
+set remote hardware-watchpoint-limit 4
+monitor reset halt
+load
+monitor reset
+quit
diff --git a/groestl/aes_sbox.c b/groestl/aes_sbox.c
new file mode 100644 (file)
index 0000000..73849dd
--- /dev/null
@@ -0,0 +1,39 @@
+/* aes sbox */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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 <stdint.h>
+const uint8_t aes_sbox[256] = {
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+};
+
diff --git a/groestl/aes_sbox.h b/groestl/aes_sbox.h
new file mode 100644 (file)
index 0000000..5bc03b7
--- /dev/null
@@ -0,0 +1,33 @@
+/* aes_sbox.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     aes_sbox.h
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2008-12-30
+ * \license  GPLv3 or later
+ * 
+ */
+#ifndef AES_SBOX_H_
+#define AES_SBOX_H_
+#include <stdint.h>
+
+extern uint8_t aes_sbox[];
+
+#endif
diff --git a/groestl/gf256mul.c b/groestl/gf256mul.c
new file mode 100644 (file)
index 0000000..a473646
--- /dev/null
@@ -0,0 +1,40 @@
+/* gf256mul.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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 <stdint.h>
+
+uint8_t gf256mul(uint8_t a, uint8_t b, uint8_t reducer){
+       uint8_t r=0;
+       while(a&0xFE){
+               if(a&1){
+                       r ^= b;
+               }
+               a >>= 1;
+               if(b&0x80){
+                       b <<= 1;
+                       b ^= reducer;
+               }else{
+                       b <<= 1;
+               }
+       }
+       if(a&1){
+               r ^= b;
+       }
+       return r;
+}
diff --git a/groestl/gf256mul.h b/groestl/gf256mul.h
new file mode 100644 (file)
index 0000000..87f1cb3
--- /dev/null
@@ -0,0 +1,37 @@
+/* gf256mul.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+#ifndef GF256MUL_H_
+#define GF256MUL_H_
+
+/**
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2008-12-19
+ * \license GPLv3
+ * \brief
+ * 
+ * 
+ */
+
+#include <stdint.h>
+
+uint8_t gf256mul(uint8_t a, uint8_t b, uint8_t reducer);
+
+#endif /* GF256MUL_H_ */
+
diff --git a/groestl/groestl_large.c b/groestl/groestl_large.c
new file mode 100644 (file)
index 0000000..0650196
--- /dev/null
@@ -0,0 +1,241 @@
+/* groestl_large.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    groestl_large.c
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-06-11
+ * \license GPLv3 or later
+ * 
+ */
+
+#include "groestl_large.h"
+#include "aes_sbox.h"
+#include "gf256mul.h"
+#include "memxor.h"
+#include <stdint.h>
+#include <string.h>
+
+#define ROUNDS 14
+#define POLYNOM 0x1b
+
+#define DEBUG 0
+
+#if DEBUG
+ #include "cli.h"
+ void dump_m(const uint8_t* m){
+        uint8_t i,j;
+        for(i=0; i<16; ++i){
+               cli_putstr("\r\n");
+               for(j=0; j<8; ++j){
+                       cli_putc(' ');
+                       cli_hexdump(m+8*i+j, 1);
+               }
+        }
+ }
+#else
+ #define dump_m(m)
+#endif
+
+static const uint8_t matrix[] = {
+ 2, 2, 3, 4, 5, 3, 5, 7,
+ 7, 2, 2, 3, 4, 5, 3, 5,
+ 5, 7, 2, 2, 3, 4, 5, 3,
+ 3, 5, 7, 2, 2, 3, 4, 5,
+ 5, 3, 5, 7, 2, 2, 3, 4,
+ 4, 5, 3, 5, 7, 2, 2, 3,
+ 3, 4, 5, 3, 5, 7, 2, 2,
+ 2, 3, 4, 5, 3, 5, 7, 2
+};
+
+void groestl_large_rounds(uint8_t *m, uint8_t q){
+       uint8_t r,i,j;
+       uint8_t tmp[16];
+       for(r=0; r<ROUNDS; ++r){
+               if(q){
+                       m[7] ^= 0xff ^ r;
+               }else{
+                       m[0] ^= r;
+               }       
+#if DEBUG              
+               if(r<2){
+                       cli_putstr("\r\npost add-const");
+                       dump_m(m);
+               }
+#endif
+               for(i=0;i<16*8; ++i){
+                       m[i] = aes_sbox[m[i]];
+               }
+               for(i=1; i<7; ++i){
+                       for(j=0; j<16; ++j)
+                               tmp[j] = m[i+8*j];
+                       for(j=0; j<16; ++j){
+                               m[i+((j-i+16)%16)*8] = tmp[j];
+                       }
+               }
+               for(j=0; j<16; ++j)
+                       tmp[j] = m[7+8*j];
+               for(j=0; j<16; ++j){
+                       m[7+((j-11+16)%16)*8] = tmp[j];
+               }
+               
+#if DEBUG              
+               if(r<2){
+                       cli_putstr("\r\npost shift-bytes");
+                       dump_m(m);
+               }
+#endif                 
+               for(i=0; i<16; ++i){
+                       memcpy(tmp, m+8*i, 8);
+                       for(j=0; j<8; ++j){
+                               m[j+i*8] = gf256mul(matrix[8*j+0],tmp[0], POLYNOM)
+                                        ^ gf256mul(matrix[8*j+1],tmp[1], POLYNOM)
+                                        ^ gf256mul(matrix[8*j+2],tmp[2], POLYNOM)
+                                        ^ gf256mul(matrix[8*j+3],tmp[3], POLYNOM)
+                                        ^ gf256mul(matrix[8*j+4],tmp[4], POLYNOM)
+                                        ^ gf256mul(matrix[8*j+5],tmp[5], POLYNOM)
+                                        ^ gf256mul(matrix[8*j+6],tmp[6], POLYNOM)
+                                        ^ gf256mul(matrix[8*j+7],tmp[7], POLYNOM);
+                       }
+               }
+#if DEBUG
+               if(r<2){
+                       cli_putstr("\r\npost mix-bytes");
+                       dump_m(m);
+               }
+#endif                 
+       }
+}
+
+void groestl384_init(groestl384_ctx_t* ctx){
+       memset(ctx->h, 0, 16*8);
+       ctx->h[8*16-1] = (uint8_t)384;
+       ctx->h[8*16-2] = (uint8_t)(384>>8);
+       ctx->counter = 0;
+}
+
+void groestl512_init(groestl512_ctx_t* ctx){
+       memset(ctx->h, 0, 16*8);
+       ctx->h[8*16-2] = 2;
+       ctx->counter = 0;
+}
+
+void groestl_large_nextBlock(groestl_large_ctx_t* ctx, const void* block){
+       uint8_t tmp1[128], tmp2[128];
+/*
+       for(i=0; i<8; ++i){
+               for(j=0; j<8; ++j){
+                       tmp1[j*8+i] = ((uint8_t*)block)[i*8+j];
+               }
+       }
+*/ 
+       memcpy(tmp1, block, 128);
+       memcpy(tmp2, tmp1, 128);
+       memxor(tmp1, ctx->h, 128);
+       groestl_large_rounds(tmp1, 0);
+       groestl_large_rounds(tmp2, 1);
+       memxor(ctx->h, tmp1, 128);
+       memxor(ctx->h, tmp2, 128);
+       ctx->counter++;
+}
+
+void groestl_large_lastBlock(groestl_large_ctx_t* ctx, const void* block, uint16_t length_b){
+       uint8_t buffer[128];
+       while(length_b>=GROESTL_LARGE_BLOCKSIZE){
+               groestl_large_nextBlock(ctx, block);
+               length_b -= GROESTL_LARGE_BLOCKSIZE;
+               block = (uint8_t*)block + GROESTL_LARGE_BLOCKSIZE_B;
+       }
+       memset(buffer, 0, 128);
+       memcpy(buffer, block, (length_b+7)/8);
+       buffer[length_b/8] |= 0x80>>(length_b%8);
+       if(length_b>1024-65){
+               groestl_large_nextBlock(ctx, buffer);
+               memset(buffer, 0, 128-4);
+       }
+       ctx->counter++;
+       buffer[128-1]  = (uint8_t)(ctx->counter);
+       buffer[128-2]  = (uint8_t)((ctx->counter)>>8);
+       buffer[128-3]  = (uint8_t)((ctx->counter)>>16);
+       buffer[128-4]  = (uint8_t)((ctx->counter)>>24);
+       groestl_large_nextBlock(ctx, buffer);
+}
+
+void groestl_large_ctx2hash(void* dest, const groestl_large_ctx_t* ctx, uint16_t outlength_b){
+       uint8_t tmp[128];
+       memcpy(tmp, ctx->h, 128);
+       groestl_large_rounds(tmp, 0);
+       memxor(tmp, ctx->h, 128);
+#if DEBUG
+       cli_putstr("\r\npost finalisation");
+       dump_m(tmp);
+#endif         
+       memcpy(dest, tmp+128-outlength_b/8, outlength_b/8);
+}
+
+void groestl384_ctx2hash(void* dest, const groestl384_ctx_t* ctx){
+       groestl_large_ctx2hash(dest, ctx, 384);
+}
+
+void groestl512_ctx2hash(void* dest, const groestl512_ctx_t* ctx){
+       groestl_large_ctx2hash(dest, ctx, 512);
+}
+
+void groestl384_nextBlock(groestl384_ctx_t* ctx, const void* block){
+       groestl_large_nextBlock(ctx, block);
+}
+
+void groestl512_nextBlock(groestl512_ctx_t* ctx, const void* block){
+       groestl_large_nextBlock(ctx, block);
+}
+
+void groestl384_lastBlock(groestl384_ctx_t* ctx, const void* block, uint16_t length_b){
+       groestl_large_lastBlock(ctx, block, length_b);
+}
+
+void groestl512_lastBlock(groestl512_ctx_t* ctx, const void* block, uint16_t length_b){
+       groestl_large_lastBlock(ctx, block, length_b);
+}
+
+void groestl384(void* dest, const void* msg, uint32_t length_b){
+       groestl_large_ctx_t ctx;
+       groestl384_init(&ctx);
+       while(length_b>=GROESTL_LARGE_BLOCKSIZE){
+               groestl_large_nextBlock(&ctx, msg);
+               length_b -= GROESTL_LARGE_BLOCKSIZE;
+               msg = (uint8_t*)msg + GROESTL_LARGE_BLOCKSIZE_B;
+       }
+       groestl_large_lastBlock(&ctx, msg, length_b);
+       groestl_large_ctx2hash(dest, &ctx, 384);
+}
+
+void groestl512(void* dest, const void* msg, uint32_t length_b){
+       groestl_large_ctx_t ctx;
+       groestl512_init(&ctx);
+       while(length_b>=GROESTL_LARGE_BLOCKSIZE){
+               groestl_large_nextBlock(&ctx, msg);
+               length_b -= GROESTL_LARGE_BLOCKSIZE;
+               msg = (uint8_t*)msg + GROESTL_LARGE_BLOCKSIZE_B;
+       }
+       groestl_large_lastBlock(&ctx, msg, length_b);
+       groestl_large_ctx2hash(dest, &ctx, 512);
+}
+
+
+
diff --git a/groestl/groestl_large.h b/groestl/groestl_large.h
new file mode 100644 (file)
index 0000000..c932fb7
--- /dev/null
@@ -0,0 +1,65 @@
+/* groestl_large.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    groestl_large.h
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-05-19
+ * \license GPLv3 or later
+ * 
+ */
+#ifndef GROESTL_LARGE_H_
+#define GROESTL_LARGE_H_
+
+#include <stdint.h>
+
+#define GROESTL_LARGE_BLOCKSIZE   1024
+#define GROESTL_LARGE_BLOCKSIZE_B ((GROESTL_LARGE_BLOCKSIZE+7)/8)
+#define GROESTL384_BLOCKSIZE      GROESTL_LARGE_BLOCKSIZE
+#define GROESTL384_BLOCKSIZE_B    GROESTL_LARGE_BLOCKSIZE_B
+#define GROESTL512_BLOCKSIZE      GROESTL_LARGE_BLOCKSIZE
+#define GROESTL512_BLOCKSIZE_B    GROESTL_LARGE_BLOCKSIZE_B
+
+typedef struct {
+       uint8_t h[8*16];
+       uint32_t counter;
+} groestl_large_ctx_t;
+
+typedef groestl_large_ctx_t groestl384_ctx_t;
+typedef groestl_large_ctx_t groestl512_ctx_t;
+
+void groestl384_init(groestl384_ctx_t* ctx);
+void groestl512_init(groestl512_ctx_t* ctx);
+
+void groestl_large_nextBlock(groestl_large_ctx_t* ctx, const void* block);
+void groestl_large_lastBlock(groestl_large_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void groestl384_nextBlock(groestl384_ctx_t* ctx, const void* block);
+void groestl384_lastBlock(groestl384_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void groestl512_nextBlock(groestl512_ctx_t* ctx, const void* block);
+void groestl512_lastBlock(groestl512_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void groestl384_ctx2hash(void* dest, const groestl384_ctx_t* ctx);
+void groestl512_ctx2hash(void* dest, const groestl512_ctx_t* ctx);
+
+void groestl384(void* dest, const void* msg, uint32_t length_b);
+void groestl512(void* dest, const void* msg, uint32_t length_b);
+
+#endif /* GROESTL_GROESTL_H_ */
diff --git a/groestl/groestl_small.c b/groestl/groestl_small.c
new file mode 100644 (file)
index 0000000..5996c10
--- /dev/null
@@ -0,0 +1,233 @@
+/* groestl_small.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    groestl_small.c
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-05-19
+ * \license GPLv3 or later
+ *
+ */
+
+#include "groestl_small.h"
+#include "aes_sbox.h"
+#include "gf256mul.h"
+#include "memxor.h"
+#include <stdint.h>
+#include <string.h>
+
+#define ROUNDS 10
+#define POLYNOM 0x1b
+
+#define DEBUG 0
+
+#if DEBUG
+ #include "cli.h"
+ void dump_m(const uint8_t* m){
+        uint8_t i,j;
+        for(i=0; i<8; ++i){
+               cli_putstr("\r\n");
+               for(j=0; j<8; ++j){
+                       cli_putc(' ');
+                       cli_hexdump(m+8*i+j, 1);
+               }
+        }
+ }
+#else
+ #define dump_m(m)
+#endif
+
+static const uint8_t matrix[] = {
+ 2, 2, 3, 4, 5, 3, 5, 7,
+ 7, 2, 2, 3, 4, 5, 3, 5,
+ 5, 7, 2, 2, 3, 4, 5, 3,
+ 3, 5, 7, 2, 2, 3, 4, 5,
+ 5, 3, 5, 7, 2, 2, 3, 4,
+ 4, 5, 3, 5, 7, 2, 2, 3,
+ 3, 4, 5, 3, 5, 7, 2, 2,
+ 2, 3, 4, 5, 3, 5, 7, 2
+};
+
+void groestl_small_rounds(uint8_t *m, uint8_t q){
+       uint8_t r,i,j;
+       uint8_t tmp[8];
+       for(r=0; r<ROUNDS; ++r){
+               if(q){
+                       m[7] ^= 0xff ^ r;
+               }else{
+                       m[0] ^= r;
+               }
+#if DEBUG
+               if(r<2){
+                       cli_putstr("\r\npost add-const");
+                       dump_m(m);
+               }
+#endif
+               for(i=0;i<8*8; ++i){
+                       m[i] = aes_sbox[m[i]];
+               }
+               for(i=1; i<8; ++i){
+                       for(j=0; j<8; ++j)
+                               tmp[j] = m[i+8*j];
+                       for(j=0; j<8; ++j){
+                               m[i+((j-i+8)%8)*8] = tmp[j];
+                       }
+               }
+#if DEBUG
+               if(r<2){
+                       cli_putstr("\r\npost shift-bytes");
+                       dump_m(m);
+               }
+#endif
+               for(i=0; i<8; ++i){
+                       memcpy(tmp, m+8*i, 8);
+                       for(j=0; j<8; ++j){
+                               m[j+i*8] = gf256mul(matrix[8*j+0],tmp[0], POLYNOM)
+                                        ^ gf256mul(matrix[8*j+1],tmp[1], POLYNOM)
+                                        ^ gf256mul(matrix[8*j+2],tmp[2], POLYNOM)
+                                        ^ gf256mul(matrix[8*j+3],tmp[3], POLYNOM)
+                                        ^ gf256mul(matrix[8*j+4],tmp[4], POLYNOM)
+                                        ^ gf256mul(matrix[8*j+5],tmp[5], POLYNOM)
+                                        ^ gf256mul(matrix[8*j+6],tmp[6], POLYNOM)
+                                        ^ gf256mul(matrix[8*j+7],tmp[7], POLYNOM);
+                       }
+               }
+#if DEBUG
+               if(r<2){
+                       cli_putstr("\r\npost mix-bytes");
+                       dump_m(m);
+               }
+#endif
+       }
+}
+
+void groestl224_init(groestl224_ctx_t* ctx){
+       memset(ctx->h, 0, 8*8);
+       ctx->h[8*8-1] = 224;
+       ctx->counter = 1;
+}
+
+void groestl256_init(groestl256_ctx_t* ctx){
+       memset(ctx->h, 0, 8*8);
+       ctx->h[8*8-2] = 1;
+       ctx->counter = 1;
+}
+
+void groestl_small_nextBlock(groestl_small_ctx_t* ctx, const void* block){
+       uint8_t tmp1[64], tmp2[64];
+/*     for(i=0; i<8; ++i){
+               for(j=0; j<8; ++j){
+                       tmp1[j*8+i] = ((uint8_t*)block)[i*8+j];
+               }
+       }
+*/
+       memcpy(tmp1, block, 64);
+       memcpy(tmp2, tmp1, 64);
+       memxor(tmp1, ctx->h, 64);
+       groestl_small_rounds(tmp1, 0);
+       groestl_small_rounds(tmp2, 1);
+       memxor(ctx->h, tmp1, 64);
+       memxor(ctx->h, tmp2, 64);
+       ctx->counter++;
+}
+
+void groestl_small_lastBlock(groestl_small_ctx_t* ctx, const void* block, uint16_t length_b){
+       uint8_t buffer[64];
+       while(length_b>=GROESTL_SMALL_BLOCKSIZE){
+               groestl_small_nextBlock(ctx, block);
+               length_b -= GROESTL_SMALL_BLOCKSIZE;
+               block = (uint8_t*)block + GROESTL_SMALL_BLOCKSIZE_B;
+       }
+       memset(buffer, 0, 64);
+       memcpy(buffer, block, (length_b+7)/8);
+       buffer[length_b/8] |= 0x80>>(length_b&0x7);
+       if(length_b>512-65){
+               groestl_small_nextBlock(ctx, buffer);
+               memset(buffer, 0, 64-4);
+       }
+//     ctx->counter++;
+       buffer[64-1]  = (uint8_t)(ctx->counter);
+       buffer[64-2]  = (uint8_t)((ctx->counter)>>8);
+       buffer[64-3]  = (uint8_t)((ctx->counter)>>16);
+       buffer[64-4]  = (uint8_t)((ctx->counter)>>24);
+       groestl_small_nextBlock(ctx, buffer);
+}
+
+void groestl_small_ctx2hash(void* dest, const groestl_small_ctx_t* ctx, uint16_t outlength_b){
+       uint8_t tmp[64];
+       memcpy(tmp, ctx->h, 64);
+       groestl_small_rounds(tmp, 0);
+       memxor(tmp, ctx->h, 64);
+#if DEBUG
+       cli_putstr("\r\npost finalisation");
+       dump_m(tmp);
+#endif
+       memcpy(dest, tmp+64-outlength_b/8, outlength_b/8);
+}
+
+void groestl224_ctx2hash(void* dest, const groestl224_ctx_t* ctx){
+       groestl_small_ctx2hash(dest, ctx, 224);
+}
+
+void groestl256_ctx2hash(void* dest, const groestl256_ctx_t* ctx){
+       groestl_small_ctx2hash(dest, ctx, 256);
+}
+
+void groestl224_nextBlock(groestl224_ctx_t* ctx, const void* block){
+       groestl_small_nextBlock(ctx, block);
+}
+
+void groestl256_nextBlock(groestl256_ctx_t* ctx, const void* block){
+       groestl_small_nextBlock(ctx, block);
+}
+
+void groestl224_lastBlock(groestl224_ctx_t* ctx, const void* block, uint16_t length_b){
+       groestl_small_lastBlock(ctx, block, length_b);
+}
+
+void groestl256_lastBlock(groestl256_ctx_t* ctx, const void* block, uint16_t length_b){
+       groestl_small_lastBlock(ctx, block, length_b);
+}
+
+void groestl224(void* dest, const void* msg, uint32_t length_b){
+       groestl_small_ctx_t ctx;
+       groestl224_init(&ctx);
+       while(length_b>=GROESTL_SMALL_BLOCKSIZE){
+               groestl_small_nextBlock(&ctx, msg);
+               length_b -= GROESTL_SMALL_BLOCKSIZE;
+               msg = (uint8_t*)msg + GROESTL_SMALL_BLOCKSIZE_B;
+       }
+       groestl_small_lastBlock(&ctx, msg, length_b);
+       groestl_small_ctx2hash(dest, &ctx, 224);
+}
+
+void groestl256(void* dest, const void* msg, uint32_t length_b){
+       groestl_small_ctx_t ctx;
+       groestl256_init(&ctx);
+       while(length_b>=GROESTL_SMALL_BLOCKSIZE){
+               groestl_small_nextBlock(&ctx, msg);
+               length_b -= GROESTL_SMALL_BLOCKSIZE;
+               msg = (uint8_t*)msg + GROESTL_SMALL_BLOCKSIZE_B;
+       }
+       groestl_small_lastBlock(&ctx, msg, length_b);
+       groestl_small_ctx2hash(dest, &ctx, 256);
+}
+
+
+
diff --git a/groestl/groestl_small.h b/groestl/groestl_small.h
new file mode 100644 (file)
index 0000000..819cc4c
--- /dev/null
@@ -0,0 +1,65 @@
+/* groestl_small.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    groestl_small.h
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-05-19
+ * \license GPLv3 or later
+ * 
+ */
+#ifndef GROESTL_SMALL_H_
+#define GROESTL_SMALL_H_
+
+#include <stdint.h>
+
+#define GROESTL_SMALL_BLOCKSIZE   512
+#define GROESTL_SMALL_BLOCKSIZE_B ((GROESTL_SMALL_BLOCKSIZE+7)/8)
+#define GROESTL224_BLOCKSIZE      GROESTL_SMALL_BLOCKSIZE
+#define GROESTL224_BLOCKSIZE_B    GROESTL_SMALL_BLOCKSIZE_B
+#define GROESTL256_BLOCKSIZE      GROESTL_SMALL_BLOCKSIZE
+#define GROESTL256_BLOCKSIZE_B    GROESTL_SMALL_BLOCKSIZE_B
+
+typedef struct {
+       uint8_t h[8*8];
+       uint32_t counter;
+} groestl_small_ctx_t;
+
+typedef groestl_small_ctx_t groestl224_ctx_t;
+typedef groestl_small_ctx_t groestl256_ctx_t;
+
+void groestl224_init(groestl224_ctx_t* ctx);
+void groestl256_init(groestl256_ctx_t* ctx);
+
+void groestl_small_nextBlock(groestl_small_ctx_t* ctx, const void* block);
+void groestl_small_lastBlock(groestl_small_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void groestl224_nextBlock(groestl224_ctx_t* ctx, const void* block);
+void groestl224_lastBlock(groestl224_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void groestl256_nextBlock(groestl256_ctx_t* ctx, const void* block);
+void groestl256_lastBlock(groestl256_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void groestl224_ctx2hash(void* dest, const groestl224_ctx_t* ctx);
+void groestl256_ctx2hash(void* dest, const groestl256_ctx_t* ctx);
+
+void groestl224(void* dest, const void* msg, uint32_t length_b);
+void groestl256(void* dest, const void* msg, uint32_t length_b);
+
+#endif /* GROESTL_GROESTL_H_ */
diff --git a/groestl/memxor.c b/groestl/memxor.c
new file mode 100644 (file)
index 0000000..7485b3e
--- /dev/null
@@ -0,0 +1,12 @@
+#include <stdint.h>
+
+#include "memxor.h"
+
+void memxor(void* dest, const void* src, uint16_t n){
+  while(n--){
+    *((uint8_t*)dest) ^= *((uint8_t*)src);
+    dest = (uint8_t*)dest +1;
+    src  = (uint8_t*)src  +1;
+  }
+}
+
diff --git a/groestl/memxor.h b/groestl/memxor.h
new file mode 100644 (file)
index 0000000..a62a616
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef MEMXOR_H_
+#define MEMXOR_H_
+#include <stdint.h>
+
+void memxor(void* dest, const void* src, uint16_t n);
+
+#endif
diff --git a/hfal-basic.c b/hfal-basic.c
new file mode 100644 (file)
index 0000000..dbb1e7d
--- /dev/null
@@ -0,0 +1,80 @@
+/* hfal-basic.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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 "hashfunction_descriptor.h"
+#include "hfal-basic.h"
+#include <stdlib.h>
+
+uint8_t hfal_hash_init(const hfdesc_t* hash_descriptor, hfgen_ctx_t* ctx){
+       ctx->desc_ptr = (hfdesc_t*)hash_descriptor;
+       if(!(ctx->ctx=malloc(hash_descriptor->ctxsize_B)))
+               return 3;
+       hash_descriptor->init(ctx->ctx);
+       return 0;
+}
+
+void hfal_hash_nextBlock(hfgen_ctx_t* ctx, const void* block){
+       ctx->desc_ptr->nextBlock(ctx->ctx, block);
+}
+
+void hfal_hash_lastBlock(hfgen_ctx_t* ctx, const void* block, uint16_t length_b){
+       ctx->desc_ptr->lastBlock(ctx->ctx, block, length_b);
+}
+
+void hfal_hash_ctx2hash(void* dest, hfgen_ctx_t* ctx){
+       ctx->desc_ptr->ctx2hash(dest, ctx->ctx);
+}
+
+void hfal_hash_free(hfgen_ctx_t* ctx){
+       hf_free_fpt f;
+       f = ctx->desc_ptr->free;
+       if(f)
+               f(ctx->ctx);
+       free(ctx->ctx);
+}
+
+void hfal_hash_mem(const hfdesc_t* hash_descriptor, void* dest, const void* msg, uint32_t length_b){
+       void_fpt f;
+       f = (void_fpt)(hash_descriptor->mem);
+       if(f){
+               ((hf_mem_fpt)f)(dest, msg, length_b);
+       }else{
+               uint16_t bs,bsb;
+               uint8_t ctx[hash_descriptor->ctxsize_B];
+               hash_descriptor->init(ctx);
+               bs = hash_descriptor->blocksize_b;
+               bsb=bs/8;
+               f=(void_fpt)(hash_descriptor->nextBlock);
+               while(length_b>bs){
+                       ((hf_nextBlock_fpt)f)(ctx, msg);
+                       length_b -= bs;
+                       msg = (uint8_t*)msg + bsb;
+               }
+               hash_descriptor->lastBlock(ctx, msg, length_b);
+               hash_descriptor->ctx2hash(dest, ctx);
+       }
+}
+
+uint16_t hfal_hash_getBlocksize(const hfdesc_t* hash_descriptor){
+       return hash_descriptor->blocksize_b;
+}
+
+uint16_t hfal_hash_getHashsize(const hfdesc_t* hash_descriptor){
+       return hash_descriptor->hashsize_b;
+}
diff --git a/hfal-basic.h b/hfal-basic.h
new file mode 100644 (file)
index 0000000..e03bffe
--- /dev/null
@@ -0,0 +1,34 @@
+/* hfal-basic.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+
+#ifndef HFAL_BASIC_H_
+#define HFAL_BASIC_H_
+
+#include "hashfunction_descriptor.h"
+
+uint8_t hfal_hash_init(const hfdesc_t* hash_descriptor, hfgen_ctx_t* ctx);
+void hfal_hash_nextBlock(hfgen_ctx_t* ctx, const void* block);
+void hfal_hash_lastBlock(hfgen_ctx_t* ctx, const void* block, uint16_t length_b);
+void hfal_hash_ctx2hash(void* dest, hfgen_ctx_t* ctx);
+void hfal_hash_free(hfgen_ctx_t* ctx);
+void hfal_hash_mem(const hfdesc_t* hash_descriptor, void* dest, const void* msg, uint32_t length_b);
+uint16_t hfal_hash_getBlocksize(const hfdesc_t* hash_descriptor);
+uint16_t hfal_hash_getHashsize(const hfdesc_t* hash_descriptor);
+
+#endif /* HFAL_BASIC_H_ */
diff --git a/hfal_blake_large.c b/hfal_blake_large.c
new file mode 100644 (file)
index 0000000..8a432ff
--- /dev/null
@@ -0,0 +1,66 @@
+/* hfal_blake_large.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_blake_large.c
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-05-08
+ * \license  GPLv3 or later
+ * 
+ */
+
+#include <stdlib.h>
+#include "hashfunction_descriptor.h"
+#include "blake_large.h"
+
+
+static const char blake48_str[]  = "Blake-48";
+static const char blake64_str[]  = "Blake-64";
+
+const hfdesc_t blake48_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       blake48_str,
+       sizeof(blake48_ctx_t),
+       BLAKE48_BLOCKSIZE,
+       384,
+       (hf_init_fpt)blake48_init,
+       (hf_nextBlock_fpt)blake_large_nextBlock,
+       (hf_lastBlock_fpt)blake_large_lastBlock,
+       (hf_ctx2hash_fpt)blake48_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)blake48
+};
+
+const hfdesc_t blake64_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       blake64_str,
+       sizeof(blake64_ctx_t),
+       BLAKE64_BLOCKSIZE,
+       512,
+       (hf_init_fpt)blake64_init,
+       (hf_nextBlock_fpt)blake_large_nextBlock,
+       (hf_lastBlock_fpt)blake_large_lastBlock,
+       (hf_ctx2hash_fpt)blake64_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)blake64
+};
+
+
diff --git a/hfal_blake_large.h b/hfal_blake_large.h
new file mode 100644 (file)
index 0000000..a6740b5
--- /dev/null
@@ -0,0 +1,36 @@
+/* hfal_blake_large.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_blake_large.h
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-05-08
+ * \license  GPLv3 or later
+ * 
+ */
+
+#ifndef HFAL_BLAKE_LARGE_H_
+#define HFAL_BLAKE_LARGE_H_
+
+#include "hashfunction_descriptor.h"
+
+extern const hfdesc_t blake48_desc;
+extern const hfdesc_t blake64_desc;
+
+#endif /* HFAL_BLAKE_LARGE_H_ */
diff --git a/hfal_blake_small.c b/hfal_blake_small.c
new file mode 100644 (file)
index 0000000..7273abb
--- /dev/null
@@ -0,0 +1,66 @@
+/* hfal_blake_small.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_blake_small.c
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-05-05
+ * \license  GPLv3 or later
+ * 
+ */
+
+#include <stdlib.h>
+#include "hashfunction_descriptor.h"
+#include "blake_small.h"
+
+
+static const char blake28_str[] = "Blake-28";
+static const char blake32_str[] = "Blake-32";
+
+const hfdesc_t blake28_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       blake28_str,
+       sizeof(blake28_ctx_t),
+       BLAKE28_BLOCKSIZE,
+       224,
+       (hf_init_fpt)blake28_init,
+       (hf_nextBlock_fpt)blake_small_nextBlock,
+       (hf_lastBlock_fpt)blake_small_lastBlock,
+       (hf_ctx2hash_fpt)blake28_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)blake28
+};
+
+const hfdesc_t blake32_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       blake32_str,
+       sizeof(blake32_ctx_t),
+       BLAKE32_BLOCKSIZE,
+       256,
+       (hf_init_fpt)blake32_init,
+       (hf_nextBlock_fpt)blake_small_nextBlock,
+       (hf_lastBlock_fpt)blake_small_lastBlock,
+       (hf_ctx2hash_fpt)blake32_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)blake32
+};
+
+
diff --git a/hfal_blake_small.h b/hfal_blake_small.h
new file mode 100644 (file)
index 0000000..925d72d
--- /dev/null
@@ -0,0 +1,36 @@
+/* hfal_blake_small.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_blake_small.h
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-05-05
+ * \license  GPLv3 or later
+ * 
+ */
+
+#ifndef HFAL_BLAKE_SMALL_H_
+#define HFAL_BLAKE_SMALL_H_
+
+#include "hashfunction_descriptor.h"
+
+extern const hfdesc_t blake28_desc;
+extern const hfdesc_t blake32_desc;
+
+#endif /* HFAL_BLAKE_SMALL_H_ */
diff --git a/hfal_bmw_large.c b/hfal_bmw_large.c
new file mode 100644 (file)
index 0000000..348895f
--- /dev/null
@@ -0,0 +1,66 @@
+/* hfal_bmw_large.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_bmw_large.c
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-04-28
+ * \license  GPLv3 or later
+ * 
+ */
+
+#include <stdlib.h>
+#include "hashfunction_descriptor.h"
+#include "bmw_large.h"
+
+
+static const char bmw384_str[]  = "BlueMidnightWish-384";
+static const char bmw512_str[]  = "BlueMidnightWish-512";
+
+const hfdesc_t bmw384_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       bmw384_str,
+       sizeof(bmw384_ctx_t),
+       BMW384_BLOCKSIZE,
+       384,
+       (hf_init_fpt)bmw384_init,
+       (hf_nextBlock_fpt)bmw384_nextBlock,
+       (hf_lastBlock_fpt)bmw384_lastBlock,
+       (hf_ctx2hash_fpt)bmw384_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)bmw384
+};
+
+const hfdesc_t bmw512_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       bmw512_str,
+       sizeof(bmw512_ctx_t),
+       BMW512_BLOCKSIZE,
+       512,
+       (hf_init_fpt)bmw512_init,
+       (hf_nextBlock_fpt)bmw512_nextBlock,
+       (hf_lastBlock_fpt)bmw512_lastBlock,
+       (hf_ctx2hash_fpt)bmw512_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)bmw512
+};
+
+
diff --git a/hfal_bmw_large.h b/hfal_bmw_large.h
new file mode 100644 (file)
index 0000000..5a28b2c
--- /dev/null
@@ -0,0 +1,36 @@
+/* hfal_bmw_large.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_bmw_large.h
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-04-28
+ * \license  GPLv3 or later
+ * 
+ */
+
+#ifndef HFAL_BMW_LARGE_H_
+#define HFAL_BMW_LARGE_H_
+
+#include "hashfunction_descriptor.h"
+
+extern const hfdesc_t bmw384_desc;
+extern const hfdesc_t bmw512_desc;
+
+#endif /* HFAL_BMW_LARGE_H_ */
diff --git a/hfal_bmw_small.c b/hfal_bmw_small.c
new file mode 100644 (file)
index 0000000..9bcd500
--- /dev/null
@@ -0,0 +1,66 @@
+/* hfal_bmw_small.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_bmw_small.c
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-04-28
+ * \license  GPLv3 or later
+ * 
+ */
+
+#include <stdlib.h>
+#include "hashfunction_descriptor.h"
+#include "bmw_small.h"
+
+
+static const char bmw224_str[]  = "BlueMidnightWish-224";
+static const char bmw256_str[]  = "BlueMidnightWish-256";
+
+const hfdesc_t bmw224_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       bmw224_str,
+       sizeof(bmw224_ctx_t),
+       BMW224_BLOCKSIZE,
+       224,
+       (hf_init_fpt)bmw224_init,
+       (hf_nextBlock_fpt)bmw224_nextBlock,
+       (hf_lastBlock_fpt)bmw224_lastBlock,
+       (hf_ctx2hash_fpt)bmw224_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)bmw224
+};
+
+const hfdesc_t bmw256_desc  = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       bmw256_str,
+       sizeof(bmw256_ctx_t),
+       BMW256_BLOCKSIZE,
+       256,
+       (hf_init_fpt)bmw256_init,
+       (hf_nextBlock_fpt)bmw256_nextBlock,
+       (hf_lastBlock_fpt)bmw256_lastBlock,
+       (hf_ctx2hash_fpt)bmw256_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)bmw256
+};
+
+
diff --git a/hfal_bmw_small.h b/hfal_bmw_small.h
new file mode 100644 (file)
index 0000000..08f3c86
--- /dev/null
@@ -0,0 +1,36 @@
+/* hfal_bmw_small.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_bmw_small.h
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-04-28
+ * \license  GPLv3 or later
+ * 
+ */
+
+#ifndef HFAL_BMW_SMALL_H_
+#define HFAL_BMW_SMALL_H_
+
+#include "hashfunction_descriptor.h"
+
+extern const hfdesc_t bmw224_desc;
+extern const hfdesc_t bmw256_desc;
+
+#endif /* HFAL_BMW_SMALL_H_ */
diff --git a/hfal_cubehash.c b/hfal_cubehash.c
new file mode 100644 (file)
index 0000000..132f1dd
--- /dev/null
@@ -0,0 +1,98 @@
+/* hfal_cubehash.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_cubehash.c
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte
+ * \date     2010-02-09
+ * \license  GPLv3 or later
+ *
+ */
+
+#include <stdlib.h>
+#include "hashfunction_descriptor.h"
+#include "cubehash.h"
+
+
+static const char cubehash224_str[] = "CubeHash-224";
+static const char cubehash256_str[] = "CubeHash-256";
+static const char cubehash384_str[] = "CubeHash-384";
+static const char cubehash512_str[] = "CubeHash-512";
+
+const hfdesc_t cubehash224_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       cubehash224_str,
+       sizeof(cubehash_ctx_t),
+       CUBEHASH224_BLOCKSIZE,
+       224,
+       (hf_init_fpt)cubehash224_init,
+       (hf_nextBlock_fpt)cubehash_nextBlock,
+       (hf_lastBlock_fpt)cubehash_lastBlock,
+       (hf_ctx2hash_fpt)cubehash224_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+
+const hfdesc_t cubehash256_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       cubehash256_str,
+       sizeof(cubehash_ctx_t),
+       CUBEHASH256_BLOCKSIZE,
+       256,
+       (hf_init_fpt)cubehash256_init,
+       (hf_nextBlock_fpt)cubehash_nextBlock,
+       (hf_lastBlock_fpt)cubehash_lastBlock,
+       (hf_ctx2hash_fpt)cubehash256_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+
+const hfdesc_t cubehash384_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       cubehash384_str,
+       sizeof(cubehash_ctx_t),
+       CUBEHASH384_BLOCKSIZE,
+       384,
+       (hf_init_fpt)cubehash384_init,
+       (hf_nextBlock_fpt)cubehash_nextBlock,
+       (hf_lastBlock_fpt)cubehash_lastBlock,
+       (hf_ctx2hash_fpt)cubehash384_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+
+const hfdesc_t cubehash512_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       cubehash512_str,
+       sizeof(cubehash_ctx_t),
+       CUBEHASH512_BLOCKSIZE,
+       512,
+       (hf_init_fpt)cubehash512_init,
+       (hf_nextBlock_fpt)cubehash_nextBlock,
+       (hf_lastBlock_fpt)cubehash_lastBlock,
+       (hf_ctx2hash_fpt)cubehash512_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+
+
diff --git a/hfal_cubehash.h b/hfal_cubehash.h
new file mode 100644 (file)
index 0000000..40441f3
--- /dev/null
@@ -0,0 +1,31 @@
+/* hfal_cubehash.h */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+
+#ifndef HFAL_CUBEHASH_H_
+#define HFAL_CUBEHASH_H_
+
+#include "hashfunction_descriptor.h"
+
+extern const hfdesc_t cubehash224_desc;
+extern const hfdesc_t cubehash256_desc;
+extern const hfdesc_t cubehash384_desc;
+extern const hfdesc_t cubehash512_desc;
+
+
+#endif /* HFAL_CUBEHASH_H_ */
diff --git a/hfal_echo.c b/hfal_echo.c
new file mode 100644 (file)
index 0000000..a8ce1a3
--- /dev/null
@@ -0,0 +1,98 @@
+/* hfal_echo.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_echo.c
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte
+ * \date     2010-02-21
+ * \license  GPLv3 or later
+ *
+ */
+
+#include <stdlib.h>
+#include "hashfunction_descriptor.h"
+#include "echo.h"
+
+
+static const char echo224_str[]    = "ECHO-224";
+static const char echo256_str[]    = "ECHO-256";
+static const char echo384_str[]    = "ECHO-384";
+static const char echo512_str[]    = "ECHO-512";
+
+const hfdesc_t echo224_desc  = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       echo224_str,
+       sizeof(echo_small_ctx_t),
+       ECHO224_BLOCKSIZE,
+       224,
+       (hf_init_fpt)echo224_init,
+       (hf_nextBlock_fpt)echo_small_nextBlock,
+       (hf_lastBlock_fpt)echo_small_lastBlock,
+       (hf_ctx2hash_fpt)echo224_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+
+const hfdesc_t echo256_desc  = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       echo256_str,
+       sizeof(echo_small_ctx_t),
+       ECHO256_BLOCKSIZE,
+       256,
+       (hf_init_fpt)echo256_init,
+       (hf_nextBlock_fpt)echo_small_nextBlock,
+       (hf_lastBlock_fpt)echo_small_lastBlock,
+       (hf_ctx2hash_fpt)echo256_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+
+const hfdesc_t echo384_desc  = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       echo384_str,
+       sizeof(echo_large_ctx_t),
+       ECHO384_BLOCKSIZE,
+       384,
+       (hf_init_fpt)echo384_init,
+       (hf_nextBlock_fpt)echo_large_nextBlock,
+       (hf_lastBlock_fpt)echo_large_lastBlock,
+       (hf_ctx2hash_fpt)echo384_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+
+const hfdesc_t echo512_desc  = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       echo512_str,
+       sizeof(echo_large_ctx_t),
+       ECHO512_BLOCKSIZE,
+       512,
+       (hf_init_fpt)echo512_init,
+       (hf_nextBlock_fpt)echo_large_nextBlock,
+       (hf_lastBlock_fpt)echo_large_lastBlock,
+       (hf_ctx2hash_fpt)echo512_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+
+
diff --git a/hfal_echo.h b/hfal_echo.h
new file mode 100644 (file)
index 0000000..78be0db
--- /dev/null
@@ -0,0 +1,30 @@
+/* hfal_echo.h */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+
+#ifndef HFAL_ECHO_H_
+#define HFAL_ECHO_H_
+
+#include "hashfunction_descriptor.h"
+
+extern const hfdesc_t echo224_desc;
+extern const hfdesc_t echo256_desc;
+extern const hfdesc_t echo384_desc;
+extern const hfdesc_t echo512_desc;
+
+#endif /* HFAL_ECHO_H_ */
diff --git a/hfal_groestl_large.c b/hfal_groestl_large.c
new file mode 100644 (file)
index 0000000..e33be03
--- /dev/null
@@ -0,0 +1,67 @@
+/* hfal_groestl_large.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_groestl_large.c
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-05-05
+ * \license  GPLv3 or later
+ * 
+ */
+
+
+#include <stdlib.h>
+#include "hashfunction_descriptor.h"
+#include "groestl_large.h"
+#include "groestl_small.h"
+
+
+static const char groestl384_str[] = "Groestl-384";
+static const char groestl512_str[] = "Groestl-512";
+
+const hfdesc_t groestl384_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       groestl384_str,
+       sizeof(groestl384_ctx_t),
+       GROESTL384_BLOCKSIZE,
+       384,
+       (hf_init_fpt)groestl384_init,
+       (hf_nextBlock_fpt)groestl_large_nextBlock,
+       (hf_lastBlock_fpt)groestl_large_lastBlock,
+       (hf_ctx2hash_fpt)groestl384_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)groestl384
+};
+
+const hfdesc_t groestl512_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       groestl512_str,
+       sizeof(groestl512_ctx_t),
+       GROESTL512_BLOCKSIZE,
+       512,
+       (hf_init_fpt)groestl512_init,
+       (hf_nextBlock_fpt)groestl_large_nextBlock,
+       (hf_lastBlock_fpt)groestl_large_lastBlock,
+       (hf_ctx2hash_fpt)groestl512_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)groestl512
+};
+
diff --git a/hfal_groestl_large.h b/hfal_groestl_large.h
new file mode 100644 (file)
index 0000000..cbf331b
--- /dev/null
@@ -0,0 +1,37 @@
+/* hfal_groestl_large.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_groestl_large.h
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-06-11
+ * \license  GPLv3 or later
+ * 
+ */
+
+#ifndef HFAL_GROESTL_LARGE_H_
+#define HFAL_GROESTL_LARGE_H_
+
+
+#include "hashfunction_descriptor.h"
+
+extern const hfdesc_t groestl384_desc;
+extern const hfdesc_t groestl512_desc;
+
+#endif /* HFAL_GROESTL_LARGE_H_ */
diff --git a/hfal_groestl_small.c b/hfal_groestl_small.c
new file mode 100644 (file)
index 0000000..00f3d3d
--- /dev/null
@@ -0,0 +1,67 @@
+/* hfal_groestl_small.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_groestl_small.c
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-05-05
+ * \license  GPLv3 or later
+ * 
+ */
+
+
+#include <stdlib.h>
+#include "hashfunction_descriptor.h"
+#include "groestl_small.h"
+
+
+static const char groestl224_str[] = "Groestl-224";
+static const char groestl256_str[] = "Groestl-256";
+
+const hfdesc_t groestl224_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       groestl224_str,
+       sizeof(groestl224_ctx_t),
+       GROESTL224_BLOCKSIZE,
+       224,
+       (hf_init_fpt)groestl224_init,
+       (hf_nextBlock_fpt)groestl_small_nextBlock,
+       (hf_lastBlock_fpt)groestl_small_lastBlock,
+       (hf_ctx2hash_fpt)groestl224_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)groestl224
+};
+
+const hfdesc_t groestl256_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       groestl256_str,
+       sizeof(groestl256_ctx_t),
+       GROESTL256_BLOCKSIZE,
+       256,
+       (hf_init_fpt)groestl256_init,
+       (hf_nextBlock_fpt)groestl_small_nextBlock,
+       (hf_lastBlock_fpt)groestl_small_lastBlock,
+       (hf_ctx2hash_fpt)groestl256_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)groestl256
+};
+
+
diff --git a/hfal_groestl_small.h b/hfal_groestl_small.h
new file mode 100644 (file)
index 0000000..4295f37
--- /dev/null
@@ -0,0 +1,37 @@
+/* hfal_groestl_small.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_groestl_small.h
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-05-05
+ * \license  GPLv3 or later
+ * 
+ */
+
+#ifndef HFAL_GROESTL_SMALL_H_
+#define HFAL_GROESTL_SMALL_H_
+
+
+#include "hashfunction_descriptor.h"
+
+extern const hfdesc_t groestl224_desc;
+extern const hfdesc_t groestl256_desc;
+
+#endif /* HFAL_GROESTL_SMALL_H_ */
diff --git a/hfal_keccak.c b/hfal_keccak.c
new file mode 100644 (file)
index 0000000..b3981ea
--- /dev/null
@@ -0,0 +1,99 @@
+/* hfal_keccak.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_keccak.c
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2010-02-09
+ * \license  GPLv3 or later
+ * 
+ */
+
+
+#include <stdlib.h>
+#include "hashfunction_descriptor.h"
+#include "keccak.h"
+
+
+static const char keccak224_str[] = "Keccak-224";
+static const char keccak256_str[] = "Keccak-256";
+static const char keccak384_str[] = "Keccak-384";
+static const char keccak512_str[] = "Keccak-512";
+
+const hfdesc_t keccak224_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       keccak224_str,
+       sizeof(keccak_ctx_t),
+       KECCAK224_BLOCKSIZE,
+       224,
+       (hf_init_fpt)keccak224_init,
+       (hf_nextBlock_fpt)keccak_nextBlock,
+       (hf_lastBlock_fpt)keccak_lastBlock,
+       (hf_ctx2hash_fpt)keccak224_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+
+const hfdesc_t keccak256_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       keccak256_str,
+       sizeof(keccak_ctx_t),
+       KECCAK256_BLOCKSIZE,
+       256,
+       (hf_init_fpt)keccak256_init,
+       (hf_nextBlock_fpt)keccak_nextBlock,
+       (hf_lastBlock_fpt)keccak_lastBlock,
+       (hf_ctx2hash_fpt)keccak256_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+
+const hfdesc_t keccak384_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       keccak384_str,
+       sizeof(keccak_ctx_t),
+       KECCAK384_BLOCKSIZE,
+       384,
+       (hf_init_fpt)keccak384_init,
+       (hf_nextBlock_fpt)keccak_nextBlock,
+       (hf_lastBlock_fpt)keccak_lastBlock,
+       (hf_ctx2hash_fpt)keccak384_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+
+const hfdesc_t keccak512_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       keccak512_str,
+       sizeof(keccak_ctx_t),
+       KECCAK512_BLOCKSIZE,
+       512,
+       (hf_init_fpt)keccak512_init,
+       (hf_nextBlock_fpt)keccak_nextBlock,
+       (hf_lastBlock_fpt)keccak_lastBlock,
+       (hf_ctx2hash_fpt)keccak512_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+
+
diff --git a/hfal_keccak.h b/hfal_keccak.h
new file mode 100644 (file)
index 0000000..16ddeae
--- /dev/null
@@ -0,0 +1,39 @@
+/* hfal_keccak.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_keccak.h
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2010-02-09
+ * \license  GPLv3 or later
+ * 
+ */
+
+#ifndef HFAL_KECCAK_H_
+#define HFAL_KECCAK_H_
+
+
+#include "hashfunction_descriptor.h"
+
+extern const hfdesc_t keccak224_desc;
+extern const hfdesc_t keccak256_desc;
+extern const hfdesc_t keccak384_desc;
+extern const hfdesc_t keccak512_desc;
+
+#endif /* HFAL_KECCAK_H_ */
diff --git a/hfal_md5.c b/hfal_md5.c
new file mode 100644 (file)
index 0000000..8e3399c
--- /dev/null
@@ -0,0 +1,49 @@
+/* hfal_md5.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_md5.c
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-02-09
+ * \license  GPLv3 or later
+ * 
+ */
+
+
+#include <stdlib.h>
+#include "hashfunction_descriptor.h"
+#include "md5.h"
+
+static const char md5_str[] = "MD5";
+
+const hfdesc_t md5_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       md5_str,
+       sizeof(md5_ctx_t),
+       512,
+       128,
+       (hf_init_fpt)md5_init,
+       (hf_nextBlock_fpt)md5_nextBlock,
+       (hf_lastBlock_fpt)md5_lastBlock,
+       (hf_ctx2hash_fpt)md5_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)md5
+};
+
diff --git a/hfal_md5.h b/hfal_md5.h
new file mode 100644 (file)
index 0000000..3682493
--- /dev/null
@@ -0,0 +1,36 @@
+/* hfal_md5.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_md5.h
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-02-09
+ * \license  GPLv3 or later
+ * 
+ */
+
+#ifndef HFAL_MD5_H_
+#define HFAL_MD5_H_
+
+
+#include "hashfunction_descriptor.h"
+
+extern const hfdesc_t md5_desc;
+
+#endif /* HFAL_MD5_H_ */
diff --git a/hfal_sha1.c b/hfal_sha1.c
new file mode 100644 (file)
index 0000000..b38ab4d
--- /dev/null
@@ -0,0 +1,49 @@
+/* hfal_sha1.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_sha1.c
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-02-04
+ * \license  GPLv3 or later
+ * 
+ */
+
+
+#include <stdlib.h>
+#include "hashfunction_descriptor.h"
+#include "sha1.h"
+
+static const char sha1_str[] = "SHA-1";
+
+const hfdesc_t sha1_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       sha1_str,
+       sizeof(sha1_ctx_t),
+       512,
+       160,
+       (hf_init_fpt)sha1_init,
+       (hf_nextBlock_fpt)sha1_nextBlock,
+       (hf_lastBlock_fpt)sha1_lastBlock,
+       (hf_ctx2hash_fpt)sha1_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)sha1
+};
+
diff --git a/hfal_sha1.h b/hfal_sha1.h
new file mode 100644 (file)
index 0000000..f0f6b8d
--- /dev/null
@@ -0,0 +1,36 @@
+/* hfal_sha1.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_sha1.h
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-02-04
+ * \license  GPLv3 or later
+ * 
+ */
+
+#ifndef HFAL_SHA1_H_
+#define HFAL_SHA1_H_
+
+
+#include "hashfunction_descriptor.h"
+
+extern const hfdesc_t sha1_desc;
+
+#endif /* HFAL_SHA1_H_ */
diff --git a/hfal_sha256.c b/hfal_sha256.c
new file mode 100644 (file)
index 0000000..2da04d8
--- /dev/null
@@ -0,0 +1,49 @@
+/* hfal_sha256.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_sha256.c
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-02-04
+ * \license  GPLv3 or later
+ * 
+ */
+
+
+#include <stdlib.h>
+#include "hashfunction_descriptor.h"
+#include "sha256.h"
+
+static const char sha256_str[] = "SHA-256";
+
+const hfdesc_t sha256_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       sha256_str,
+       sizeof(sha256_ctx_t),
+       512,
+       256,
+       (hf_init_fpt)sha256_init,
+       (hf_nextBlock_fpt)sha256_nextBlock,
+       (hf_lastBlock_fpt)sha256_lastBlock,
+       (hf_ctx2hash_fpt)sha256_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)sha256
+};
+
diff --git a/hfal_sha256.h b/hfal_sha256.h
new file mode 100644 (file)
index 0000000..aa57598
--- /dev/null
@@ -0,0 +1,36 @@
+/* hfal_sha256.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_sha256.h
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-02-04
+ * \license  GPLv3 or later
+ * 
+ */
+
+#ifndef HFAL_SHA256_H_
+#define HFAL_SHA256_H_
+
+
+#include "hashfunction_descriptor.h"
+
+extern const hfdesc_t sha256_desc;
+
+#endif /* HFAL_SHA256_H_ */
diff --git a/hfal_shabal.c b/hfal_shabal.c
new file mode 100644 (file)
index 0000000..ec0c7b6
--- /dev/null
@@ -0,0 +1,113 @@
+/* hfal_shabal.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_shabal.c
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-04-20
+ * \license  GPLv3 or later
+ * 
+ */
+
+
+#include <stdlib.h>
+#include "hashfunction_descriptor.h"
+#include "shabal.h"
+
+
+static const char shabal192_str[] = "Shabal-192";
+static const char shabal224_str[] = "Shabal-224";
+static const char shabal256_str[] = "Shabal-256";
+static const char shabal384_str[] = "Shabal-384";
+static const char shabal512_str[] = "Shabal-512";
+
+const hfdesc_t shabal192_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       shabal192_str,
+       sizeof(shabal_ctx_t),
+       SHABAL_BLOCKSIZE,
+       192,
+       (hf_init_fpt)shabal192_init,
+       (hf_nextBlock_fpt)shabal_nextBlock,
+       (hf_lastBlock_fpt)shabal_lastBlock,
+       (hf_ctx2hash_fpt)shabal192_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)shabal192
+};
+
+const hfdesc_t shabal224_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       shabal224_str,
+       sizeof(shabal_ctx_t),
+       SHABAL_BLOCKSIZE,
+       224,
+       (hf_init_fpt)shabal224_init,
+       (hf_nextBlock_fpt)shabal_nextBlock,
+       (hf_lastBlock_fpt)shabal_lastBlock,
+       (hf_ctx2hash_fpt)shabal224_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)shabal224
+};
+
+const hfdesc_t shabal256_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       shabal256_str,
+       sizeof(shabal_ctx_t),
+       SHABAL_BLOCKSIZE,
+       256,
+       (hf_init_fpt)shabal256_init,
+       (hf_nextBlock_fpt)shabal_nextBlock,
+       (hf_lastBlock_fpt)shabal_lastBlock,
+       (hf_ctx2hash_fpt)shabal256_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)shabal256
+};
+
+const hfdesc_t shabal384_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       shabal384_str,
+       sizeof(shabal_ctx_t),
+       SHABAL_BLOCKSIZE,
+       384,
+       (hf_init_fpt)shabal384_init,
+       (hf_nextBlock_fpt)shabal_nextBlock,
+       (hf_lastBlock_fpt)shabal_lastBlock,
+       (hf_ctx2hash_fpt)shabal384_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)shabal384
+};
+
+const hfdesc_t shabal512_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       shabal512_str,
+       sizeof(shabal_ctx_t),
+       SHABAL_BLOCKSIZE,
+       512,
+       (hf_init_fpt)shabal512_init,
+       (hf_nextBlock_fpt)shabal_nextBlock,
+       (hf_lastBlock_fpt)shabal_lastBlock,
+       (hf_ctx2hash_fpt)shabal512_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)shabal512
+};
diff --git a/hfal_shabal.h b/hfal_shabal.h
new file mode 100644 (file)
index 0000000..f56f604
--- /dev/null
@@ -0,0 +1,40 @@
+/* hfal_shabal.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_shabal.h
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-04-20
+ * \license  GPLv3 or later
+ * 
+ */
+
+#ifndef HFAL_SHABAL_H_
+#define HFAL_SHABAL_H_
+
+
+#include "hashfunction_descriptor.h"
+
+extern const hfdesc_t shabal192_desc;
+extern const hfdesc_t shabal224_desc;
+extern const hfdesc_t shabal256_desc;
+extern const hfdesc_t shabal384_desc;
+extern const hfdesc_t shabal512_desc;
+
+#endif /* HFAL_SHABAL_H_ */
diff --git a/hfal_skein1024.c b/hfal_skein1024.c
new file mode 100644 (file)
index 0000000..2ee3400
--- /dev/null
@@ -0,0 +1,162 @@
+/* hfal_skein1024.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_skein1024.c
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-03-13
+ * \license  GPLv3 or later
+ * 
+ */
+
+
+#include <stdlib.h>
+#include "hashfunction_descriptor.h"
+#include "skein.h"
+
+
+static const char skein1024_128_str[] = "Skein-1024-128";
+static const char skein1024_160_str[] = "Skein-1024-160";
+static const char skein1024_224_str[] = "Skein-1024-224";
+static const char skein1024_256_str[] = "Skein-1024-256";
+static const char skein1024_384_str[] = "Skein-1024-384";
+static const char skein1024_512_str[] = "Skein-1024-512";
+static const char skein1024_1024_str[] = "Skein-1024-1024";
+
+void skein1024_128_init(skein1024_ctx_t* ctx){
+       skein1024_init(ctx, 128);
+}
+void skein1024_160_init(skein1024_ctx_t* ctx){
+       skein1024_init(ctx, 160);
+}
+void skein1024_224_init(skein1024_ctx_t* ctx){
+       skein1024_init(ctx, 224);
+}
+void skein1024_256_init(skein1024_ctx_t* ctx){
+       skein1024_init(ctx, 256);
+}
+void skein1024_384_init(skein1024_ctx_t* ctx){
+       skein1024_init(ctx, 384);
+}
+void skein1024_512_init(skein1024_ctx_t* ctx){
+       skein1024_init(ctx, 512);
+}
+void skein1024_1024_init(skein1024_ctx_t* ctx){
+       skein1024_init(ctx, 1024);
+}
+
+const hfdesc_t skein1024_128_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       skein1024_128_str,
+       sizeof(skein1024_ctx_t),
+       SKEIN1024_BLOCKSIZE,
+       128,
+       (hf_init_fpt)skein1024_128_init,
+       (hf_nextBlock_fpt)skein1024_nextBlock,
+       (hf_lastBlock_fpt)skein1024_lastBlock,
+       (hf_ctx2hash_fpt)skein1024_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+const hfdesc_t skein1024_160_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       skein1024_160_str,
+       sizeof(skein1024_ctx_t),
+       SKEIN1024_BLOCKSIZE,
+       160,
+       (hf_init_fpt)skein1024_160_init,
+       (hf_nextBlock_fpt)skein1024_nextBlock,
+       (hf_lastBlock_fpt)skein1024_lastBlock,
+       (hf_ctx2hash_fpt)skein1024_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+const hfdesc_t skein1024_224_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       skein1024_224_str,
+       sizeof(skein1024_ctx_t),
+       SKEIN1024_BLOCKSIZE,
+       224,
+       (hf_init_fpt)skein1024_224_init,
+       (hf_nextBlock_fpt)skein1024_nextBlock,
+       (hf_lastBlock_fpt)skein1024_lastBlock,
+       (hf_ctx2hash_fpt)skein1024_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+const hfdesc_t skein1024_256_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       skein1024_256_str,
+       sizeof(skein1024_ctx_t),
+       SKEIN1024_BLOCKSIZE,
+       256,
+       (hf_init_fpt)skein1024_256_init,
+       (hf_nextBlock_fpt)skein1024_nextBlock,
+       (hf_lastBlock_fpt)skein1024_lastBlock,
+       (hf_ctx2hash_fpt)skein1024_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+const hfdesc_t skein1024_384_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       skein1024_384_str,
+       sizeof(skein1024_ctx_t),
+       SKEIN1024_BLOCKSIZE,
+       384,
+       (hf_init_fpt)skein1024_384_init,
+       (hf_nextBlock_fpt)skein1024_nextBlock,
+       (hf_lastBlock_fpt)skein1024_lastBlock,
+       (hf_ctx2hash_fpt)skein1024_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+const hfdesc_t skein1024_512_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       skein1024_512_str,
+       sizeof(skein1024_ctx_t),
+       SKEIN1024_BLOCKSIZE,
+       512,
+       (hf_init_fpt)skein1024_512_init,
+       (hf_nextBlock_fpt)skein1024_nextBlock,
+       (hf_lastBlock_fpt)skein1024_lastBlock,
+       (hf_ctx2hash_fpt)skein1024_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+const hfdesc_t skein1024_1024_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       skein1024_1024_str,
+       sizeof(skein1024_ctx_t),
+       SKEIN1024_BLOCKSIZE,
+       1024,
+       (hf_init_fpt)skein1024_1024_init,
+       (hf_nextBlock_fpt)skein1024_nextBlock,
+       (hf_lastBlock_fpt)skein1024_lastBlock,
+       (hf_ctx2hash_fpt)skein1024_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+
diff --git a/hfal_skein1024.h b/hfal_skein1024.h
new file mode 100644 (file)
index 0000000..4deeca6
--- /dev/null
@@ -0,0 +1,42 @@
+/* hfal_skein1024.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_skein1024.h
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-03-13
+ * \license  GPLv3 or later
+ * 
+ */
+
+#ifndef HFAL_SKEIN1024_H_
+#define HFAL_SKEIN1024_H_
+
+
+#include "hashfunction_descriptor.h"
+
+extern const hfdesc_t skein1024_128_desc;
+extern const hfdesc_t skein1024_160_desc;
+extern const hfdesc_t skein1024_224_desc;
+extern const hfdesc_t skein1024_256_desc;
+extern const hfdesc_t skein1024_384_desc;
+extern const hfdesc_t skein1024_512_desc;
+extern const hfdesc_t skein1024_1024_desc;
+
+#endif /* HFAL_SHA1024_H_ */
diff --git a/hfal_skein256.c b/hfal_skein256.c
new file mode 100644 (file)
index 0000000..2daeb84
--- /dev/null
@@ -0,0 +1,143 @@
+/* hfal_skein256.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_skein256.c
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-03-13
+ * \license  GPLv3 or later
+ * 
+ */
+
+
+#include <stdlib.h>
+#include "hashfunction_descriptor.h"
+#include "skein.h"
+
+
+static const char skein256_128_str[] = "Skein-256-128";
+static const char skein256_160_str[] = "Skein-256-160";
+static const char skein256_224_str[] = "Skein-256-224";
+static const char skein256_256_str[] = "Skein-256-256";
+static const char skein256_384_str[] = "Skein-256-384";
+static const char skein256_512_str[] = "Skein-256-512";
+
+void skein256_128_init(skein256_ctx_t* ctx){
+       skein256_init(ctx, 128);
+}
+void skein256_160_init(skein256_ctx_t* ctx){
+       skein256_init(ctx, 160);
+}
+void skein256_224_init(skein256_ctx_t* ctx){
+       skein256_init(ctx, 224);
+}
+void skein256_256_init(skein256_ctx_t* ctx){
+       skein256_init(ctx, 256);
+}
+void skein256_384_init(skein256_ctx_t* ctx){
+       skein256_init(ctx, 384);
+}
+void skein256_512_init(skein256_ctx_t* ctx){
+       skein256_init(ctx, 512);
+}
+
+const hfdesc_t skein256_128_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       skein256_128_str,
+       sizeof(skein256_ctx_t),
+       SKEIN256_BLOCKSIZE,
+       128,
+       (hf_init_fpt)skein256_128_init,
+       (hf_nextBlock_fpt)skein256_nextBlock,
+       (hf_lastBlock_fpt)skein256_lastBlock,
+       (hf_ctx2hash_fpt)skein256_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+const hfdesc_t skein256_160_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       skein256_160_str,
+       sizeof(skein256_ctx_t),
+       SKEIN256_BLOCKSIZE,
+       160,
+       (hf_init_fpt)skein256_160_init,
+       (hf_nextBlock_fpt)skein256_nextBlock,
+       (hf_lastBlock_fpt)skein256_lastBlock,
+       (hf_ctx2hash_fpt)skein256_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+const hfdesc_t skein256_224_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       skein256_224_str,
+       sizeof(skein256_ctx_t),
+       SKEIN256_BLOCKSIZE,
+       224,
+       (hf_init_fpt)skein256_224_init,
+       (hf_nextBlock_fpt)skein256_nextBlock,
+       (hf_lastBlock_fpt)skein256_lastBlock,
+       (hf_ctx2hash_fpt)skein256_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+const hfdesc_t skein256_256_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       skein256_256_str,
+       sizeof(skein256_ctx_t),
+       SKEIN256_BLOCKSIZE,
+       256,
+       (hf_init_fpt)skein256_256_init,
+       (hf_nextBlock_fpt)skein256_nextBlock,
+       (hf_lastBlock_fpt)skein256_lastBlock,
+       (hf_ctx2hash_fpt)skein256_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+const hfdesc_t skein256_384_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       skein256_384_str,
+       sizeof(skein256_ctx_t),
+       SKEIN256_BLOCKSIZE,
+       384,
+       (hf_init_fpt)skein256_384_init,
+       (hf_nextBlock_fpt)skein256_nextBlock,
+       (hf_lastBlock_fpt)skein256_lastBlock,
+       (hf_ctx2hash_fpt)skein256_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+const hfdesc_t skein256_512_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       skein256_512_str,
+       sizeof(skein256_ctx_t),
+       SKEIN256_BLOCKSIZE,
+       512,
+       (hf_init_fpt)skein256_512_init,
+       (hf_nextBlock_fpt)skein256_nextBlock,
+       (hf_lastBlock_fpt)skein256_lastBlock,
+       (hf_ctx2hash_fpt)skein256_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
diff --git a/hfal_skein256.h b/hfal_skein256.h
new file mode 100644 (file)
index 0000000..ec75a3d
--- /dev/null
@@ -0,0 +1,41 @@
+/* hfal_skein256.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_skein256.h
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-03-13
+ * \license  GPLv3 or later
+ * 
+ */
+
+#ifndef HFAL_SKEIN256_H_
+#define HFAL_SKEIN256_H_
+
+
+#include "hashfunction_descriptor.h"
+
+extern const hfdesc_t skein256_128_desc;
+extern const hfdesc_t skein256_160_desc;
+extern const hfdesc_t skein256_224_desc;
+extern const hfdesc_t skein256_256_desc;
+extern const hfdesc_t skein256_384_desc;
+extern const hfdesc_t skein256_512_desc;
+
+#endif /* HFAL_SKEIN256_H_ */
diff --git a/hfal_skein512.c b/hfal_skein512.c
new file mode 100644 (file)
index 0000000..b93dab1
--- /dev/null
@@ -0,0 +1,162 @@
+/* hfal_skein512.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_skein512.c
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-03-13
+ * \license  GPLv3 or later
+ * 
+ */
+
+
+#include <stdlib.h>
+#include "hashfunction_descriptor.h"
+#include "skein.h"
+
+
+static const char skein512_128_str[] = "Skein-512-128";
+static const char skein512_160_str[] = "Skein-512-160";
+static const char skein512_224_str[] = "Skein-512-224";
+static const char skein512_256_str[] = "Skein-512-256";
+static const char skein512_384_str[] = "Skein-512-384";
+static const char skein512_512_str[] = "Skein-512-512";
+static const char skein512_1024_str[] = "Skein-512-1024";
+
+void skein512_128_init(skein512_ctx_t* ctx){
+       skein512_init(ctx, 128);
+}
+void skein512_160_init(skein512_ctx_t* ctx){
+       skein512_init(ctx, 160);
+}
+void skein512_224_init(skein512_ctx_t* ctx){
+       skein512_init(ctx, 224);
+}
+void skein512_256_init(skein512_ctx_t* ctx){
+       skein512_init(ctx, 256);
+}
+void skein512_384_init(skein512_ctx_t* ctx){
+       skein512_init(ctx, 384);
+}
+void skein512_512_init(skein512_ctx_t* ctx){
+       skein512_init(ctx, 512);
+}
+void skein512_1024_init(skein512_ctx_t* ctx){
+       skein512_init(ctx, 1024);
+}
+
+const hfdesc_t skein512_128_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       skein512_128_str,
+       sizeof(skein512_ctx_t),
+       SKEIN512_BLOCKSIZE,
+       128,
+       (hf_init_fpt)skein512_128_init,
+       (hf_nextBlock_fpt)skein512_nextBlock,
+       (hf_lastBlock_fpt)skein512_lastBlock,
+       (hf_ctx2hash_fpt)skein512_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+const hfdesc_t skein512_160_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       skein512_160_str,
+       sizeof(skein512_ctx_t),
+       SKEIN512_BLOCKSIZE,
+       160,
+       (hf_init_fpt)skein512_160_init,
+       (hf_nextBlock_fpt)skein512_nextBlock,
+       (hf_lastBlock_fpt)skein512_lastBlock,
+       (hf_ctx2hash_fpt)skein512_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+const hfdesc_t skein512_224_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       skein512_224_str,
+       sizeof(skein512_ctx_t),
+       SKEIN512_BLOCKSIZE,
+       224,
+       (hf_init_fpt)skein512_224_init,
+       (hf_nextBlock_fpt)skein512_nextBlock,
+       (hf_lastBlock_fpt)skein512_lastBlock,
+       (hf_ctx2hash_fpt)skein512_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+const hfdesc_t skein512_256_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       skein512_256_str,
+       sizeof(skein512_ctx_t),
+       SKEIN512_BLOCKSIZE,
+       256,
+       (hf_init_fpt)skein512_256_init,
+       (hf_nextBlock_fpt)skein512_nextBlock,
+       (hf_lastBlock_fpt)skein512_lastBlock,
+       (hf_ctx2hash_fpt)skein512_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+const hfdesc_t skein512_384_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       skein512_384_str,
+       sizeof(skein512_ctx_t),
+       SKEIN512_BLOCKSIZE,
+       384,
+       (hf_init_fpt)skein512_384_init,
+       (hf_nextBlock_fpt)skein512_nextBlock,
+       (hf_lastBlock_fpt)skein512_lastBlock,
+       (hf_ctx2hash_fpt)skein512_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+const hfdesc_t skein512_512_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       skein512_512_str,
+       sizeof(skein512_ctx_t),
+       SKEIN512_BLOCKSIZE,
+       512,
+       (hf_init_fpt)skein512_512_init,
+       (hf_nextBlock_fpt)skein512_nextBlock,
+       (hf_lastBlock_fpt)skein512_lastBlock,
+       (hf_ctx2hash_fpt)skein512_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+const hfdesc_t skein512_1024_desc = {
+       HFDESC_TYPE_HASHFUNCTION,
+       0,
+       skein512_1024_str,
+       sizeof(skein512_ctx_t),
+       SKEIN512_BLOCKSIZE,
+       1024,
+       (hf_init_fpt)skein512_1024_init,
+       (hf_nextBlock_fpt)skein512_nextBlock,
+       (hf_lastBlock_fpt)skein512_lastBlock,
+       (hf_ctx2hash_fpt)skein512_ctx2hash,
+       (hf_free_fpt)NULL,
+       (hf_mem_fpt)NULL
+};
+
diff --git a/hfal_skein512.h b/hfal_skein512.h
new file mode 100644 (file)
index 0000000..3947e43
--- /dev/null
@@ -0,0 +1,42 @@
+/* hfal_skein512.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     hfal_skein512.h
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-03-13
+ * \license  GPLv3 or later
+ * 
+ */
+
+#ifndef HFAL_SKEIN512_H_
+#define HFAL_SKEIN512_H_
+
+
+#include "hashfunction_descriptor.h"
+
+extern const hfdesc_t skein512_128_desc;
+extern const hfdesc_t skein512_160_desc;
+extern const hfdesc_t skein512_224_desc;
+extern const hfdesc_t skein512_256_desc;
+extern const hfdesc_t skein512_384_desc;
+extern const hfdesc_t skein512_512_desc;
+extern const hfdesc_t skein512_1024_desc;
+
+#endif /* HFAL_SHA512_H_ */
diff --git a/host/bigint_test.rb b/host/bigint_test.rb
new file mode 100644 (file)
index 0000000..eabaec5
--- /dev/null
@@ -0,0 +1,742 @@
+#!/usr/bin/ruby
+# bigint_test.rb
+=begin
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008, 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+=end
+
+$debug = true
+$debug = false
+require 'rubygems'
+require 'serialport'
+require 'getopt/std'
+require 'ftools'
+require 'date'
+$buffer_size = 0
+$conffile_check = Hash.new
+$conffile_check.default = 0
+
+################################################################################
+# readconfigfile                                                               #
+################################################################################
+
+def readconfigfile(fname, conf)
+  return conf if $conffile_check[fname]==1
+  $conffile_check[fname]=1
+  section = "default"
+  if not File.exists?(fname)
+    return conf
+  end
+  file = File.open(fname, "r")
+  until file.eof
+    line = file.gets()
+       next if /[\s]*#/.match(line)
+       if m=/\[[\s]*([^\s]*)[\s]*\]/.match(line)
+         section=m[1]
+         conf[m[1]] = Hash.new
+         next
+       end
+       next if not /=/.match(line)
+       m=/[\s]*([^\s]*)[\s]*=[\s]*([^\s]*)/.match(line)
+       if m[1]=="include"
+         Dir.glob(m[2]){ |fn| conf = readconfigfile(fn, conf) }
+       else
+         conf[section][m[1]] = m[2]
+       end
+  end
+  file.close()
+  return conf
+end
+
+################################################################################
+# expmod                                                                       #
+################################################################################
+
+def expmod(base, power, mod)
+  result = 1
+  while power > 0
+    result = (result * base) % mod if power & 1 == 1
+    base = (base * base) % mod
+    power >>= 1;
+  end
+  return result
+end
+
+################################################################################
+# gcdext                                                                 #
+################################################################################
+
+def gcdext(x,y)
+  g=1
+  while(x&1==0 && y&1==0) do
+    x>>=1
+    y>>=1
+    g<<=1
+  end
+  u=x; v=y; a=1; b=0; c=0; d=1
+  begin
+    while(u&1==0) do
+      if(a%2==1 || b%2==1)
+        a += y
+        b -= x
+      end
+      u>>=1; a>>=1; b>>=1
+    end
+    while(v&1==0) do
+      if(c%2==1 || d%2==1)
+        c += y
+        d -= x
+      end
+      v>>=1; c>>=1; d>>=1;
+    end
+    if(u>=v)
+      u -= v; a-=c; b-=d
+    else
+      v -= u; c-=a; d-=b
+    end
+  end while(u!=0)
+  return[g*v, c, d]
+end
+
+################################################################################
+# reset_system                                                                 #
+################################################################################
+
+def reset_system
+  $sp.print("exit\r")
+  sleep 0.1
+  $sp.print("exit\r")
+  sleep 0.1
+end
+
+################################################################################
+# init_system                                                                  #
+################################################################################
+
+def init_system(test_prog)
+  $sp.print("echo off \r")
+  print("DBG i: " + "echo off \r"+"\n") if $debug
+  sleep 0.1
+  $sp.print("#{test_prog}\r")
+  print("DBG i: " + "#{test_prog} \r"+"\n") if $debug
+  sleep 1
+end
+
+
+################################################################################
+# screen_progress                                                              #
+################################################################################
+def screen_progress(v)
+  if $linepos==0
+    printf("\n%5d [%04d]: ", $testno, $size)
+  end
+  putc((v)?('*'):('!'))
+  $testno += 1
+  $linepos = ($linepos+1)%$linewidth
+end
+
+################################################################################
+# add_test                                                                     #
+################################################################################
+
+def add_test(a,b)
+  begin
+    line = $sp.gets()
+    line = "" if line==nil
+    puts("DBG got: "+line) if $debug
+    if /^Error:.*/.match(line)
+      puts line
+      return false
+    end
+  end while not /[\s]*enter a:[\s]*/.match(line)
+  $sp.print(a.to_s(16)+" ")
+  begin
+    line = $sp.gets()
+    line = "" if line==nil
+    puts("DBG got: "+line) if $debug
+    if /^Error:.*/.match(line)
+      puts line
+      return false
+    end
+  end while not /[\s]*enter b:[\s]*/.match(line)
+  $sp.print(b.to_s(16)+" ")
+  begin
+    line = $sp.gets()
+    line = "" if line==nil
+    puts("DBG got: "+line) if $debug
+    if /^Error:.*/.match(line)
+      puts line
+      return false
+    end
+  end while not m=/[\s]*([-]?[0-9a-fA-F]*)[\s]+\+[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line)
+  a_ = m[1].to_i(16)
+  b_ = m[2].to_i(16)
+  c_ = m[3].to_i(16)
+  line.chomp!
+  if(a_== a && b_ == b && c_ == (a+b))
+    $logfile.printf("[pass]: %s\n", line)
+    return true
+  else
+    $logfile.printf("[fail (%s%s%s)]: %s", (a==a_)?"":"a", (b==b_)?"":"b", (c_==a+b)?"":"c",line)
+    $logfile.printf(" ; should %s + %s = %s\n", a.to_s(16), b.to_s(16), (a+b).to_s(16))
+    return false
+  end
+  return false
+end
+
+################################################################################
+# mul_test                                                                     #
+################################################################################
+
+def mul_test(a,b)
+  begin
+    line = $sp.gets()
+    line = "" if line==nil
+    puts("DBG got: "+line) if $debug
+    if /^Error:.*/.match(line)
+      puts line
+      return false
+    end
+  end while not /[\s]*enter a:[\s]*/.match(line)
+  $sp.print(a.to_s(16)+" ")
+  begin
+    line = $sp.gets()
+    line = "" if line==nil
+    puts("DBG got: "+line) if $debug
+    if /^Error:.*/.match(line)
+      puts line
+      return false
+    end
+  end while not /[\s]*enter b:[\s]*/.match(line)
+  $sp.print(b.to_s(16)+" ")
+  begin
+    line = $sp.gets()
+    line = "" if line==nil
+    puts("DBG got: "+line) if $debug
+    if /^Error:.*/.match(line)
+      puts line
+      return false
+    end
+  end while not m=/[\s]*([+-]?[0-9a-fA-F]*)[\s]+\*[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line)
+  a_ = m[1].to_i(16)
+  b_ = m[2].to_i(16)
+  c_ = m[3].to_i(16)
+  line.chomp!
+  if(a_== a && b_ == b && c_ == (a*b))
+    $logfile.printf("[pass]: %s\n", line)
+    return true
+  else
+    $logfile.printf("[fail (%s%s%s)]: %s", (a==a_)?"":"a", (b==b_)?"":"b", (c_==a*b)?"":"c",line)
+    $logfile.printf(" ; should %s * %s = %s\n", a.to_s(16), b.to_s(16), (a*b).to_s(16))
+    return false
+  end
+  return false
+end
+
+################################################################################
+# square_test                                                                  #
+################################################################################
+
+def square_test(a)
+  begin
+    line = $sp.gets()
+    line = "" if line==nil
+    puts("DBG got: "+line) if $debug
+    if /^Error:.*/.match(line)
+      puts line
+      return false
+    end
+  end while not /[\s]*enter a:[\s]*/.match(line)
+  $sp.print(a.to_s(16)+" ")
+  begin
+    line = $sp.gets()
+    line = "" if line==nil
+    puts("DBG got: "+line) if $debug
+    if /^Error:.*/.match(line)
+      puts line
+      return false
+    end
+  end while not m=/[\s]*([+-]?[0-9a-fA-F]*)[\s]*\*\*2[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line)
+  a_ = m[1].to_i(16)
+  c_ = m[2].to_i(16)
+  line.chomp!
+  if(a_== a && c_ == (a**2))
+    $logfile.printf("[pass]: %s\n", line)
+    return true
+  else
+    $logfile.printf("[fail (%s%s)]: %s", (a==a_)?"":"a", (c_==a**2)?"":"c",line)
+    $logfile.printf(" ; should %s **2 = %s\n", a.to_s(16), (a**2).to_s(16))
+    return false
+  end
+  return false
+end
+
+################################################################################
+# reduce_test                                                                  #
+################################################################################
+
+def reduce_test(a,b)
+  begin
+    line = $sp.gets()
+    line = "" if line==nil
+    puts("DBG got: "+line) if $debug
+    if /^Error:.*/.match(line)
+      puts line
+      return false
+    end
+  end while not /[\s]*enter a:[\s]*/.match(line)
+  $sp.print(a.to_s(16)+" ")
+  begin
+    line = $sp.gets()
+    line = "" if line==nil
+    puts("DBG got: "+line) if $debug
+    if /^Error:.*/.match(line)
+      puts line
+      return false
+    end
+  end while not /[\s]*enter b:[\s]*/.match(line)
+  $sp.print(b.to_s(16)+" ")
+  line=''
+  begin
+    line_tmp = $sp.gets()
+    line_tmp = '' if line_tmp==nil
+    line += line_tmp
+    puts("DBG got: "+line) if $debug
+    if /^Error:.*/.match(line)
+      puts line
+      return false
+    end
+  end while not m=/[\s]*([+-]?[0-9a-fA-F]*)[\s]+%[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]+)/.match(line)
+  a_ = m[1].to_i(16)
+  b_ = m[2].to_i(16)
+  c_ = m[3].to_i(16)
+  line.chomp!
+  if(a_== a && b_ == b && c_ == (a%b))
+    $logfile.printf("[pass]: %s\n", line)
+    return true
+  else
+    $logfile.printf("[fail (%s%s%s)]: %s", (a==a_)?"":"a", (b==b_)?"":"b", (c_==a%b)?"":"c",line)
+    $logfile.printf(" ; should %s %% %s = %s\n", a.to_s(16), b.to_s(16), (a%b).to_s(16))
+    return false
+  end
+  return false
+end
+
+################################################################################
+# expmod_test                                                                  #
+################################################################################
+
+def expmod_test(a,b,c)
+  begin
+    line = $sp.gets()
+    line = "" if line==nil
+    puts("DBG got: "+line) if $debug
+    if /^Error:.*/.match(line)
+      puts line
+      return false
+    end
+  end while not /[\s]*enter a:[\s]*/.match(line)
+  $sp.print(a.to_s(16)+" ")
+  begin
+    line = $sp.gets()
+    line = "" if line==nil
+    puts("DBG got: "+line) if $debug
+    if /^Error:.*/.match(line)
+      puts line
+      return false
+    end
+  end while not /[\s]*enter b:[\s]*/.match(line)
+  $sp.print(b.to_s(16)+" ")
+  begin
+    line = $sp.gets()
+    line = "" if line==nil
+    puts("DBG got: "+line) if $debug
+    if /^Error:.*/.match(line)
+      puts line
+      return false
+    end
+  end while not /[\s]*enter c:[\s]*/.match(line)
+  $sp.print(c.to_s(16)+" ")
+  line=''
+  begin
+    line_tmp = $sp.gets()
+    line_tmp = '' if line_tmp==nil
+    line += line_tmp
+    puts("DBG got: "+line) if $debug
+    if /^Error:.*/.match(line)
+      puts line
+      return false
+    end
+  end while not m=/[\s]*([+-]?[0-9a-fA-F]*)\*\*([+-]?[0-9a-fA-F]*)[\s]+%[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]+)/.match(line)
+  a_ = m[1].to_i(16)
+  b_ = m[2].to_i(16)
+  c_ = m[3].to_i(16)
+  d_ = m[4].to_i(16)
+  line.chomp!
+  if(a_== a && b_ == b && c_ == c && d_ ==expmod(a,b,c) )
+    $logfile.printf("[pass]: %s\n", line)
+    return true
+  else
+    $logfile.printf("[fail (%s%s%s%s)]: %s", (a==a_)?'':'a', (b==b_)?'':'b', (c_==c)?'':'c', (d_==expmod(a,b,c))?'':'d',line)
+    $logfile.printf(" ; should %s**%s %% %s = %s\n", a.to_s(16), b.to_s(16), c.to_s(16), expmod(a,b,c).to_s(16))
+    return false
+  end
+  return false
+end
+
+################################################################################
+# gcdext_test                                                                  #
+################################################################################
+
+def gcdext_test(a,b)
+  begin
+    line = $sp.gets()
+    line = "" if line==nil
+    puts("DBG got: "+line) if $debug
+    if /^Error:.*/.match(line)
+      puts line
+      return false
+    end
+  end while not /[\s]*enter a:[\s]*/.match(line)
+  $sp.print(a.to_s(16)+" ")
+  begin
+    line = $sp.gets()
+    line = "" if line==nil
+    puts("DBG got: "+line) if $debug
+    if /^Error:.*/.match(line)
+      puts line
+      return false
+    end
+  end while not /[\s]*enter b:[\s]*/.match(line)
+  $sp.print(b.to_s(16)+" ")
+  line=''
+  begin
+    line_tmp = $sp.gets()
+    line_tmp = '' if line_tmp==nil
+    line = ''  if line.end_with?('\n')
+    line += line_tmp
+    puts("DBG got: "+line) if $debug
+    if /^Error:.*/.match(line)
+      puts line
+      return false
+    end
+  end while not m=/gcdext\([\s]*([+-]?[0-9a-fA-F]*)[\s]*,[\s]*([+-]?[0-9a-fA-F]*)[\s]*\)[\s]*=> a = ([+-]?[0-9a-fA-F]+); b = ([+-]?[0-9a-fA-F]+); gcd = ([+-]?[0-9a-fA-F]+)/.match(line)
+  a_ = m[1].to_i(16)
+  b_ = m[2].to_i(16)
+  c_ = m[3].to_i(16)
+  d_ = m[4].to_i(16)
+  e_ = m[5].to_i(16)
+  line.chomp!
+  line.gsub!("\r",'')
+  line.gsub!("\n",'')
+  ref = gcdext(a,b)
+  if(a_== a && b_ == b && c_ == ref[1] && d_ == ref[2] && e_== ref[0])
+    $logfile.printf("[pass]: %s\n", line)
+    return true
+  else
+    $logfile.printf("[fail (%s%s%s%s%s)]: %s", (a==a_)?'':'a', (b==b_)?'':'b', 
+       (c_==ref[1])?'':'c', (d_==ref[2])?'':'d', (e_==ref[0])?'':'e', line)
+    $logfile.printf(" ; should gcdext( %s, %s) => a = %s; b = %s; gcd = %s\n",
+       a.to_s(16), b.to_s(16), ref[1].to_s(16), ref[2].to_s(16), ref[0].to_s(16))
+    return false
+  end
+  return false
+end
+
+################################################################################
+# run_test_add                                                                 #
+################################################################################
+
+def run_test_add(skip=0)
+  length_a_B = skip+1
+  length_b_B = skip+1
+  begin
+    $size = length_a_B
+    (0..16).each do |i|
+      s_a = rand(2)*2-1
+      s_b = rand(2)*2-1
+      a = rand(256**length_a_B) * s_a
+      b = rand(256**length_a_B) * s_b
+      v = add_test(a, b)
+      screen_progress(v)
+      v = add_test(b, a)
+      screen_progress(v)
+    end
+    (0..16).each do |i|
+      s_a = rand(2)-1
+      s_b = rand(2)-1
+      b_size = rand(length_b_B+1)
+      a = rand(256**length_a_B) * s_a
+      b = rand(256**b_size) * s_b
+      v = add_test(a, b)
+      screen_progress(v)      
+      v = add_test(b, a)
+      screen_progress(v)
+
+    end
+    length_a_B += 1
+    length_b_B += 1
+  end while length_a_B<4096/8
+end
+
+################################################################################
+# run_test_mul                                                                 #
+################################################################################
+
+def run_test_mul(skip=0)
+  length_a_B = skip+1
+  length_b_B = skip+1
+  begin
+    $size = length_a_B
+    (0..16).each do |i|
+      s_a = rand(2)*2-1
+      s_b = rand(2)*2-1
+      a = rand(256**length_a_B) * s_a
+      b = rand(256**length_a_B) * s_b
+      v = mul_test(a, b)
+      screen_progress(v)
+      v = mul_test(b, a)
+      screen_progress(v)
+    end
+    (0..16).each do |i|
+      s_a = rand(2)-1
+      s_b = rand(2)-1
+      b_size = rand(length_b_B+1)
+      a = rand(256**length_a_B) * s_a
+      b = rand(256**b_size) * s_b
+      v = mul_test(a, b)
+      screen_progress(v)      
+      v = mul_test(b, a)
+      screen_progress(v)
+    end
+    length_a_B += 1
+    length_b_B += 1
+  end while length_a_B<4096/8
+end
+
+################################################################################
+# run_test_square                                                              #
+################################################################################
+
+def run_test_square(skip=0)
+  length_a_B = skip+1
+  begin
+    $size = length_a_B
+    (0..16).each do |i|
+      a = rand(256**length_a_B)
+      v = square_test(a)
+      screen_progress(v)
+    end
+    length_a_B += 1
+  end while length_a_B<4096/8
+end
+
+################################################################################
+# run_test_reduce                                                              #
+################################################################################
+
+def run_test_reduce(skip=0)
+  length_a_B = skip+1
+  length_b_B = skip+1
+  begin
+    $size = length_a_B
+    (0..16).each do |i|
+      a = rand(256**length_a_B)
+      b = rand(256**length_a_B)+1
+      v = reduce_test(a, b)
+      screen_progress(v)
+      end
+    (0..16).each do |i|
+      b_size = rand(length_b_B+1)
+      a = rand(256**length_a_B)
+      b = rand(256**b_size)+1 
+      v = reduce_test(a, b)
+      screen_progress(v)      
+      end
+    length_a_B += 1
+    length_b_B += 1
+  end while length_a_B<4096/8
+end
+
+################################################################################
+# run_test_expmod                                                              #
+################################################################################
+
+def run_test_expmod(skip=0)
+  length_a_B = skip+1
+  length_b_B = skip+1
+  length_c_B = skip+1
+  begin
+    $size = length_a_B
+    (0..16).each do |i|
+      a = rand(256**length_a_B)
+      b = rand(256**length_b_B)+1
+      c = rand(256**length_c_B)+1
+      v = expmod_test(a, b, c)
+      screen_progress(v)
+      end
+    (0..16).each do |i|
+      b_size = rand(length_b_B+1)
+      a = rand(256**length_a_B)
+      b = rand(256**b_size)+1 
+      c = rand(256**b_size)+1
+      v = expmod_test(a, b, c)
+      screen_progress(v)      
+      end
+    length_a_B += 1
+    length_b_B += 1
+  end while length_a_B<4096/8
+end
+
+################################################################################
+# run_test_gcdext                                                              #
+################################################################################
+
+def run_test_gcdext(skip=0)
+  length_a_B = skip+1
+  length_b_B = skip+1
+  begin
+    $size = length_a_B
+    (0..16).each do |i|
+      a = rand(256**length_a_B)
+      b = rand(256**length_a_B)+1
+      v = gcdext_test(a, b)
+      $logfile.flush()
+      screen_progress(v)
+      end
+    (0..16).each do |i|
+      b_size = rand(length_b_B+1)
+      a = rand(256**length_a_B)
+      b = rand(256**b_size)+1 
+      v = gcdext_test(a, b)
+      $logfile.flush()
+      screen_progress(v)      
+      end
+    length_a_B += 1
+    length_b_B += 1
+  end while length_a_B<4096/8
+end
+
+################################################################################
+# MAIN                                                                         #
+################################################################################
+
+opts = Getopt::Std.getopts("s:f:i:a:hd")
+
+conf = Hash.new
+conf = readconfigfile("/etc/testport.conf", conf)
+conf = readconfigfile("~/.testport.conf", conf)
+conf = readconfigfile("testport.conf", conf)
+conf = readconfigfile(opts["f"], conf) if opts["f"]
+
+#puts conf.inspect
+
+puts("serial port interface version: " + SerialPort::VERSION);
+$linewidth = 64
+$linepos = 0
+$testno = 0
+params = { "baud"       => conf["PORT"]["baud"].to_i,
+            "data_bits" => conf["PORT"]["databits"].to_i,
+            "stop_bits" => conf["PORT"]["stopbits"].to_i,
+            "parity"    => SerialPort::NONE }
+params["paraty"] = SerialPort::ODD   if conf["PORT"]["paraty"].downcase == "odd"
+params["paraty"] = SerialPort::EVEN  if conf["PORT"]["paraty"].downcase == "even"
+params["paraty"] = SerialPort::MARK  if conf["PORT"]["paraty"].downcase == "mark"
+params["paraty"] = SerialPort::SPACE if conf["PORT"]["paraty"].downcase == "space"
+
+puts("\nPort: "+conf["PORT"]["port"]+"@"    +
+                params["baud"].to_s      +
+                " "                      +
+                params["data_bits"].to_s +
+                conf["PORT"]["paraty"][0,1].upcase +
+                params["stop_bits"].to_s +
+                "\n")
+
+$sp = SerialPort.new(conf["PORT"]["port"], params)
+
+$sp.read_timeout=1000; # 5 minutes
+$sp.flow_control = SerialPort::SOFT
+
+reset_system()
+
+if opts['d']
+  $debug = true
+end
+
+logfilename = conf['PORT']['testlogbase']+'bigint.txt'
+if File.exists?(logfilename)
+  i=1
+  begin
+    logfilename = sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',i,'.txt')
+    i+=1
+  end while(File.exists?(logfilename))
+  while(i>2) do
+    File.move(sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',i-2,'.txt'), 
+              sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',i-1,'.txt'), true)
+    i-=1
+  end
+    File.move(sprintf('%s%s', conf['PORT']['testlogbase'],'bigint.txt'), 
+              sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',1,'.txt'), true)
+  logfilename = conf['PORT']['testlogbase']+'bigint.txt' 
+end
+$logfile = File.open(logfilename, 'w')
+printf("logfile: %s\n", logfilename)
+
+$logfile.printf("bigint test from: %s\n", Time.now.to_s)
+$logfile.printf("skip = %s\n", opts['s']) if opts['s']
+$logfile.printf("seed = 0x%X\n", 0xdeadbeef)
+
+tests = Hash.new
+tests['a'] = proc {|x| run_test_add(x) }
+tests['m'] = proc {|x| run_test_mul(x) }
+tests['s'] = proc {|x| run_test_square(x) }
+tests['r'] = proc {|x| run_test_reduce(x) }
+tests['e'] = proc {|x| run_test_expmod(x) }
+tests['g'] = proc {|x| run_test_gcdext(x) }
+init_str = Hash.new
+init_str['a'] = 'add-test'
+init_str['m'] = 'mul-test'
+init_str['s'] = 'square-test'
+init_str['r'] = 'reduce-test'
+init_str['e'] = 'expmod-test'
+init_str['g'] = 'gcdext-test'
+
+srand(0xdeadbeef)
+
+if opts['a']
+  opts['a'].each_char do |x|
+    if tests[x]
+      puts init_str[x]
+      init_system(init_str[x])
+      tests[x].call(opts['s']?opts['s'].to_i():0) 
+    else
+      puts "no test defiened for '#{x}'"
+    end  
+  end
+else
+  'amsre'.each_char do |x|
+    if tests[x]
+      puts init_str[x]
+      init_system(init_str[x])
+      tests[x].call(opts['s']?opts['s'].to_i():0) 
+    else
+      puts "no test defiened for '#{x}'"
+    end  
+  end
+end
+
+
+$logile.close()
diff --git a/host/bitslice2asm.rb b/host/bitslice2asm.rb
new file mode 100644 (file)
index 0000000..9c70c05
--- /dev/null
@@ -0,0 +1,26 @@
+#!/usr/bin/ruby
+#
+#
+
+while(!$stdin.eof) do
+line = $stdin.readline
+
+if match = /[\s]*((T|IN|OUT)[0-9]{1,2})[\s]*=[\s]*((T|IN|OUT)[0-9]{1,2})[\s]*([|^&])[\s]*((T|IN|OUT)[0-9]{1,2})[\s]*;/.match(line)
+       puts("    mov "+match[1]+", "+match[3])
+       case match[5]
+               when '|'
+                       conductor = "or  "
+               when '^'
+                       conductor = "eor "
+               when '&'
+                       conductor = "and "
+               else
+                       fprintf($stderr,"ERROR")
+       end
+       puts("    "+conductor+match[1]+", "+match[6])
+
+else
+       puts(line)
+end
+
+end
diff --git a/host/cmacvs_test.rb b/host/cmacvs_test.rb
new file mode 100644 (file)
index 0000000..839d04a
--- /dev/null
@@ -0,0 +1,359 @@
+#!/usr/bin/ruby
+# cmacvs_test.rb
+=begin
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008, 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+=end
+
+$debug = true
+$debug = false
+require 'rubygems'
+require 'serialport'
+require 'getopt/std'
+
+$buffer_size = 0
+$conffile_check = Hash.new
+$conffile_check.default = 0
+
+################################################################################
+# readconfigfile                                                               #
+################################################################################
+
+def readconfigfile(fname, conf)
+  return conf if $conffile_check[fname]==1
+  $conffile_check[fname]=1
+  section = "default"
+  if not File.exists?(fname)
+    return conf
+  end
+  file = File.open(fname, "r")
+  until file.eof
+    line = file.gets()
+       next if /[\s]*#/.match(line)
+       if m=/\[[\s]*([^\s]*)[\s]*\]/.match(line)
+         section=m[1]
+         conf[m[1]] = Hash.new
+         next
+       end
+       next if not /=/.match(line)
+       m=/[\s]*([^\s]*)[\s]*=[\s]*([^\s]*)/.match(line)
+       if m[1]=="include"
+         Dir.glob(m[2]){ |fn| conf = readconfigfile(fn, conf) }
+       else
+         conf[section][m[1]] = m[2]
+       end
+  end
+  file.close()
+  return conf
+end
+
+################################################################################
+# reset_system                                                                 #
+################################################################################
+
+def reset_system
+  $sp.print("exit\r")
+  sleep 0.1
+  $sp.print("exit\r")
+  sleep 0.1
+end
+
+################################################################################
+# scan_system                                                                  #
+################################################################################
+
+def scan_system
+  algos = Hash.new
+  $sp.print("cmacvs_list\r")
+  while true
+    line=$sp.gets()
+    return algos if /^>$/.match(line)
+    if m = /[\*\ ]([a-z]):[\s]*([a-zA-Z0-9+_-]+)/.match(line)
+      algos[m[2]]=m[1]
+    end
+  end
+end
+
+################################################################################
+# init_system                                                                  #
+################################################################################
+
+def init_system(algo_select, algo_id)
+  $sp.print("echo off \r")
+  print("DBG i: " + "echo off \r"+"\n") if $debug
+ sleep 1
+  $sp.print("cmacvs_set #{algo_select}\r")
+  print("DBG i: " + "cmacvs_set #{$algo_select} \r"+"\n") if $debug
+  sleep 1
+  $sp.print("cmacvs_test#{algo_id} \r")
+  print("DBG i: " + "cmacvs_test#{algo_id} \r"+"\n") if $debug
+  begin
+    line=$sp.gets()
+  end while not m=/buffer_size[\s]*=[\s]*0x([0-9A-Fa-f]*)/.match(line)
+  $buffer_size = m[1].to_i(16)
+end
+
+################################################################################
+# get_md                                                                       #
+################################################################################
+
+def get_mac
+  begin
+    line = $sp.gets()
+       line = "" if line==nil
+       puts("DBG got: "+line) if $debug
+  end while not /[\s]*Mac[\s]*=.*/.match(line)
+  return line
+end
+
+################################################################################
+# get_result                                                                   #
+################################################################################
+
+def get_result
+  begin
+    line = $sp.gets()
+    line = "" if line==nil
+    puts("DBG got: "+line) if $debug
+  end while not /[\s]*Result[\s]*=.*/.match(line)
+  puts "DBG i: got result: "+line if $debug
+  return line
+end
+
+################################################################################
+# send_md                                                                      #
+################################################################################
+
+def send_test(klen, mlen, tlen, key, msg, mac=nil)
+  $sp.printf("Klen = %s\n\r", klen)
+  $sp.printf("Mlen = %s\n\r", mlen)
+  $sp.printf("Tlen = %s\n\r", tlen)
+  $sp.printf("Key = %s\n\r",  key)
+  $sp.print("Msg = ")
+  for i in 0..msg.length-1
+    $sp.print(msg[i].chr)
+#   print("DBG s: "+ md_string[i].chr) if $debug
+#   sleep(0.001)
+    if((i%($buffer_size*2)==0)&&(i!=0))
+      begin
+      line=$sp.gets()
+      end while not /\./.match(line)
+    end
+  end
+  $sp.printf("Mac = %s\n\r",  mac) if mac
+end
+
+################################################################################
+# get_next_kv_pair                                                             #
+################################################################################
+
+def get_next_kv_pair(file)
+  loop do
+    return nil if file.eof
+    lb = file.gets()
+    m=lb.match(/[\s]*([\w\d_-]*)[\s]*=[\s]*([\w\d_-]*)/)
+    puts "DBG i: found #{m[1]} with value #{m[2]}" if m && $debug
+    return [m[1],m[2]] if m
+  end
+end
+
+################################################################################
+# run_test_gen                                                                 #
+################################################################################
+
+def run_test_gen(filename, skip=0)
+  nerrors = 0
+  line=1
+  if not File.exist?(filename)
+       puts("ERROR file "+filename+" does not exist!")
+       return nerrors
+  end
+  pos = 0
+  file = File.new(filename, "r");
+  until file.eof
+    params = Hash.new
+    begin
+      m = get_next_kv_pair(file)
+      return nerrors if m==nil
+      params[m[0]] = m[1]
+    end until m[0]=='Mac'
+    if(skip>0)
+         skip -= 1
+         redo
+       end
+    puts("DBG sending: ") if $debug
+         send_test(params['Klen'], params['Mlen'], params['Tlen'], params['Key'], params['Msg'])
+         avr_md = get_mac()
+    a = params['Mac'];
+         b = (/[\s]*Mac[\s]*=[\s]*([0-9a-fA-F]*).*/.match(avr_md))[1];
+       a.upcase!
+       b.upcase!
+         printf("\n%4d (%4d) [%5d]: ", line, (line-1)*$linewidth, params['Count']) if (pos%$linewidth==0 and $linewidth!=0)
+         line += 1               if (pos%$linewidth==0 and $linewidth!=0)
+         #sleep(1)
+         #putc((a==b)?'*':'!')
+       if(a==b)
+           putc('*')
+       else
+           putc('!')
+        #  printf("<%d>",len)
+           printf("\nError @%05d: %s [should]\n           != %s [is]- ",  params['Count'].to_i , a, b)
+           nerrors += 1
+         end
+         pos += 1
+  end
+  file.close()
+  return nerrors
+end
+
+################################################################################
+# run_test_ver                                                                 #
+################################################################################
+
+def run_test_ver(filename, skip=0)
+  nerrors = 0
+  line=1
+  if not File.exist?(filename)
+    puts("ERROR file "+filename+" does not exist!")
+    return nerrors
+  end
+  pos = 0
+  file = File.new(filename, "r");
+  until file.eof
+    params = Hash.new
+    begin
+      m = get_next_kv_pair(file)
+      return nerrors if m==nil
+      params[m[0]] = m[1]
+    end until m[0]=='Result'
+    if(skip>0)
+      skip -= 1
+      redo
+    end
+    puts("DBG sending: ") if $debug
+    send_test(params['Klen'], params['Mlen'], params['Tlen'], params['Key'], params['Msg'], params['Mac'])
+    avr_res = get_result()
+    a = params['Result'].match(/[\s]*([PF])/)[1];
+    b = /[\s]*Result[\s]*=[\s]*([PF])/.match(avr_res)[1];
+    a.upcase!
+    b.upcase!
+    printf("\n%4d (%4d) [%5d]: ", line, (line-1)*$linewidth, params['Count']) if (pos%$linewidth==0 and $linewidth!=0)
+    line += 1               if (pos%$linewidth==0 and $linewidth!=0)
+    #sleep(1)
+    #putc((a==b)?'*':'!')
+    if(a==b)
+      putc('*')
+    else
+      putc('!')
+   #  printf("<%d>",len)
+      printf("\nError @%05d: %s [should]\n           != %s [is]- ",  params['Count'].to_i , a, b)
+      nerrors += 1
+    end
+    pos += 1
+  end
+  file.close()
+  return nerrors
+end
+
+################################################################################
+# MAIN                                                                         #
+################################################################################
+
+opts = Getopt::Std.getopts("s:f:i:j:hdca")
+
+conf = Hash.new
+conf = readconfigfile("/etc/testport.conf", conf)
+conf = readconfigfile("~/.testport.conf", conf)
+conf = readconfigfile("testport.conf", conf)
+conf = readconfigfile(opts["f"], conf) if opts["f"]
+
+#puts conf.inspect
+
+puts("serial port interface version: " + SerialPort::VERSION);
+$linewidth = 64
+params = { "baud"       => conf["PORT"]["baud"].to_i,
+            "data_bits" => conf["PORT"]["databits"].to_i,
+            "stop_bits" => conf["PORT"]["stopbits"].to_i,
+            "parity"    => SerialPort::NONE }
+params["paraty"] = SerialPort::ODD   if conf["PORT"]["paraty"].downcase == "odd"
+params["paraty"] = SerialPort::EVEN  if conf["PORT"]["paraty"].downcase == "even"
+params["paraty"] = SerialPort::MARK  if conf["PORT"]["paraty"].downcase == "mark"
+params["paraty"] = SerialPort::SPACE if conf["PORT"]["paraty"].downcase == "space"
+
+puts("\nPort: "+conf["PORT"]["port"]+"@"    +
+                params["baud"].to_s      +
+                " "                      +
+                params["data_bits"].to_s +
+                conf["PORT"]["paraty"][0,1].upcase +
+                params["stop_bits"].to_s +
+                "\n")
+
+$sp = SerialPort.new(conf["PORT"]["port"], params)
+
+$sp.read_timeout=1000; # 5 minutes
+$sp.flow_control = SerialPort::SOFT
+
+reset_system()
+algos=scan_system()
+#puts algos.inspect
+
+if opts["d"]
+  $debug = true
+end
+
+if opts["s"]
+  algos_rev = algos.invert
+  algo_tasks = Array.new
+  opts["s"].each_byte{ |x|
+    if algos_rev[x.chr]
+      algo_tasks << [algos_rev[x.chr],x.chr]
+    end
+  }
+else
+  algo_tasks=algos.sort
+end
+
+algo_tasks.each do |algoa|
+  algo = algoa[0]
+  if conf[algo]==nil
+    puts("No test-set defined for #{algo} \r\n")
+    next
+  else
+       i=0
+       i = opts["j"] if opts["j"]
+       logfile=File.open(conf["PORT"]["testlogbase"]+algo+".txt", "a")
+       while conf[algo]["file_#{i}"] != nil
+         puts("Testing #{algo} with #{conf[algo]["file_#{i}"]}")
+         reset_system()
+         init_system(algoa[1], (conf[algo]["file_#{i}_test"]=='gen')?'1':'2')
+         skip=0
+         skip=opts["i"].to_i if opts["i"]
+    nerrors=run_test_gen(conf[algo]["file_#{i}"], skip) if conf[algo]["file_#{i}_test"]=='gen'
+    nerrors=run_test_ver(conf[algo]["file_#{i}"], skip) if conf[algo]["file_#{i}_test"]=='ver'
+           if nerrors == 0
+        puts("\n[ok]")
+        logfile.puts("[ok] "+conf[algo]["file_#{i}"]+ " ("+Time.now.to_s()+")")
+      else
+        puts("\n[errors: "+ nerrors.to_s() +"]")
+        logfile.puts("[error] "+nerrors.to_s+" "+conf[algo]["file_#{i}"]+ " ("+Time.now.to_s()+")")
+      end
+      i += 1
+    end
+    logfile.close()
+  end
+end
+
+
diff --git a/host/create-algo-impl-relation.rb b/host/create-algo-impl-relation.rb
new file mode 100644 (file)
index 0000000..554e8fe
--- /dev/null
@@ -0,0 +1,93 @@
+#!/usr/bin/ruby 
+# create-algo-impl-relation.rb
+=begin
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008, 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+=end
+
+SPEED_DIR = 'speed_log/'
+SIZE_DIR  = 'size_log/'
+OUT_DIR = 'algo_implementation/'
+
+$debug = false
+require 'rubygems'
+require 'getopt/std'
+require 'ftools'
+
+def get_module_names(finname)
+  ret = Array.new
+  f = File.open(finname, 'r')
+  f.gets # first line is ignored
+  while(l=f.gets())
+    if m=l.match(/[\s]([^\s]*)$/)
+      ret << m[1]
+    end
+  end
+  f.close()
+  return ret
+end
+
+
+def mkalgoimplrelation_file(foutname, finname, algos)
+  if algos==nil
+    puts "ERROR: algos==nil! fout=#{foutname} fin=#{finname}"
+    return
+  end
+  if File.exists?(foutname)
+    puts "File #{foutname} already exists!"
+    return
+  end
+  modules = get_module_names(finname).join(' ')
+  f = File.open(foutname, 'w')
+  algos.each do |algo|
+    f.puts(algo+': '+modules)
+  end
+  f.close()
+end
+
+
+if not File.directory?(SPEED_DIR) 
+  puts "ERROR: #{SPEED_DIR} is no directory!"
+  return -1
+end
+
+if not File.directory?(SIZE_DIR) 
+  puts "ERROR: #{SIZE_DIR} is no directory!"
+  return -1
+end
+
+if not File.directory?(OUT_DIR) 
+  puts "ERROR: #{OUT_DIR} is no directory!"
+  return -1
+end
+
+list = Dir.entries(SPEED_DIR)
+algo_list = Hash.new
+list.each do |entry|
+  if m=entry.match(/([^.]*)\.([^.]*)\.txt/)
+    algo_list[m[2]] = Array.new if algo_list[m[2]]==nil
+    algo_list[m[2]] << m[1]
+  end
+end
+
+list = Dir.entries(SIZE_DIR)
+list.each do |entry|
+  if m=entry.match(/([^.]*)\.size/)
+    mkalgoimplrelation_file(OUT_DIR+m[1]+'.algos', SIZE_DIR+entry, algo_list[m[1]])
+  end
+end
+
+
diff --git a/host/data2wiki.rb b/host/data2wiki.rb
new file mode 100644 (file)
index 0000000..932d263
--- /dev/null
@@ -0,0 +1,162 @@
+#!/usr/bin/ruby
+# performnce to wiki
+
+=begin
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+=end
+
+=begin
+ === Twister-256 performance === 
+    type:                     hash
+    hashsize (bits):           256
+    ctxsize (bytes):            80
+    blocksize (bits):          512
+    init (cycles):             425
+    nextBlock (cycles):      36535
+    lastBlock (cycles):       8071
+    ctx2hash (cycles):       19431
+
+   text    data     bss     dec     hex filename
+   6801      32       0    6833    1ab1 bin/bmw_c/bmw_small.o
+=end
+
+def get_size_string(impl, algo)
+  fmap = File.open('algo_implementation/'+impl+'.algos', 'r')
+  fsize = File.open('size_log/'+impl+'.size', 'r')
+  modules = nil
+  while l=fmap.gets
+    if m=l.match(/^([^:]*):(.*)$/)
+      if m[1] == algo
+        modules = m[2].split(/[\s]+/)
+      end
+    end
+  end
+  if modules==nil
+    puts("ERROR: no module list found for #{impl}/#{algo} !")
+    return nil
+  end
+  fmap.close()
+  str = ''
+  sum = 0
+  lb = fsize.gets()
+  while lb = fsize.gets()
+    m = lb.match(/[\s]*([\w]*)[\s]*([\w]*)[\s]*([\w]*)[\s]*([\w]*)[\s]*([\w]*)[\s]*([\w_\/-]*)/)
+    name = m[6]+'.o'
+    if modules.include?(name)
+      str += "<br> \n" + name+': '+m[4]
+      sum += m[4].to_i
+    end
+  end
+  fsize.close()
+  return sum
+end
+
+def process_hashfunction(fin, name, impl)
+  lb = fin.readline()
+  m = lb.match(/hashsize \(bits\):[\s]*([\d]*)/)
+  if(!m)
+       printf("unexpected string %s\n", lb)
+  end
+  hashsize = m[1].to_i()
+  lb = fin.readline()
+  m = lb.match(/ctxsize \(bytes\):[\s]*([\d]+)/)
+  ctxsize = m[1].to_i()
+  lb = fin.readline()
+  m = lb.match(/blocksize \(bits\):[\s]*([\d]+)/)
+  blocksize = m[1].to_i()
+  lb = fin.readline()
+  m = lb.match(/init \(cycles\):[\s]*([\d]+)/)
+  inittime = m[1].to_i()
+  lb = fin.readline()
+  m = lb.match(/nextBlock \(cycles\):[\s]*([\d]+)/)
+  nextblocktime = m[1].to_i()  
+  lb = fin.readline()
+  m = lb.match(/lastBlock \(cycles\):[\s]*([\d]+)/)
+  lastblocktime = m[1].to_i()
+  lb = fin.readline()
+  m = lb.match(/ctx2hash \(cycles\):[\s]*([\d]+)/)
+  convtime = m[1].to_i()
+  begin
+    lb = fin.gets()
+  end until lb==nil || m = lb.match(/init \(bytes\):[\s]*([\d]*)/)
+  if lb
+    initstack = m[1].to_i()
+    lb = fin.readline()
+    m = lb.match(/nextBlock \(bytes\):[\s]*([\d]*)/)
+    nextblockstack = m[1].to_i()
+    lb = fin.readline()
+    m = lb.match(/lastBlock \(bytes\):[\s]*([\d]*)/)
+    lastblockstack = m[1].to_i()
+    lb = fin.readline()
+    m = lb.match(/ctx2hash \(bytes\):[\s]*([\d]*)/)
+    convstack = m[1].to_i()
+    s1 = (initstack>nextblockstack)?initstack:nextblockstack
+    s2 = (lastblockstack>convstack)?lastblockstack:convstack
+    stack = (s1>s2)?s1:s2  
+  else
+    stack = 0
+  end  
+  size = get_size_string(impl, name)
+  printf("| %20s || %3s || %3s || %6d || %7d || %7d || %7d || %7d ||" +
+         " %7d || %7d || %9.2f || %7d || || || \n|-\n" , 
+        name, $lang, $lang, size, ctxsize, stack, hashsize, blocksize, 
+           inittime, nextblocktime, nextblocktime.to_f/(blocksize/8),
+               lastblocktime+convtime)
+end
+
+
+$handlers = Hash.new
+$handlers.default = 0
+$handlers["hashfunction"] = 1 #process_hashfunction
+
+def process_file(fname)
+  fin = File.open(fname, "r")
+  $lang = "asm"
+  $lang = "C" if fname.match(/_c.txt$/)
+  impl = fname.match(/([^.]*).txt$/)[1]
+  begin
+    begin
+         if fin.eof()
+               return
+         end
+      lb = fin.readline()
+    end while !m=lb.match(/=== (.*) performance ===/)
+    name = m[1];
+    lb = fin.readline()
+    m = lb.match(/type:[\s]*([\w]*)/)
+    type = m[1]
+    if $handlers[type] != 0
+    #  handlers[type](fin, name)
+    #  puts "DBG: process "+'-'+name+'-'+impl
+      process_hashfunction(fin, name, impl)
+    else
+      printf("ERROR: unsupported type: %s !\n", type)
+    end        
+  end while(true)
+  fin.close()
+end
+
+for i in (0..ARGV.size-1)
+  process_file(ARGV[i])
+end
+
+
+
+
+
+
+
diff --git a/host/find_tv.rb b/host/find_tv.rb
new file mode 100644 (file)
index 0000000..3b61bc8
--- /dev/null
@@ -0,0 +1,117 @@
+#!/usr/bin/ruby 
+# shavs_test.rb
+=begin
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+=end
+
+require 'find'
+
+def read_record(file)
+  record = Hash.new
+  lb = file.gets() until /[\s]*Set[\s]*[\d]+[\s]*,[\s]*vector#[\s]*[\d]+[\s]*:[\s]*/.match(lb)
+  term=false
+  lastkey=nil
+  begin
+    term = true
+    lb=file.gets();
+       if m=/[\s]*([^=]+)[\s]*=[\s]*(.*)/.match(lb)
+         lastkey=m[1]
+         record[m[1]] = m[2]
+         term = false
+       else
+         if m=/[\s]*([0-9a-fA-F]+)[\s]*/.match(lb) and lastkey!=nil
+           record[lastkey] += m[1]
+               term = false
+         end
+       end
+  end until term
+  record
+end
+
+def check_match(fname1, fname2)
+  r1 = Hash.new
+  r2 = Hash.new
+  if File.directory?(fname1)
+    return false
+  end
+  if File.directory?(fname2)
+    return false
+  end
+  file1 = File.new(fname1, "r");
+  file2 = File.new(fname2, "r");
+  r1 = read_record(file1)
+  r2 = read_record(file2)
+  return r1==r2
+end
+
+def get_params_from_fn(fname)
+  params = Array.new
+  if not p = /[^\.]*\.(([\d]+)\.*).*/.match(fname)
+    return params
+  end
+  params = p[1].split(/\./)
+  return params
+end
+
+def get_params_from_fn2(fname)
+  params = Array.new
+  if not p = /[^\.]*\.((-([\d]+))*\.).*/.match(fname)
+    return params
+  end
+  params = p[1].split(/\./)
+  return params
+end
+
+def find_files(fname1, afnames)
+  files = Array.new
+  params = Array.new
+  params = get_params_from_fn(fname1)
+  afnames.each{ |fn|
+    p = get_params_from_fn2(fn)
+       puts("#{params} ?=  #{p}")
+    if params.eql?(p)
+         files << fn
+       end
+  }
+  return files
+end
+
+
+if ARGV.size<2 or File.directory?(ARGV[0]) or (File.directory?(ARGV[1])==false)
+  STDERR.print <<EOF
+  Usage: ruby #{$0} file directory [formatstring]
+   
+EOF
+  exit(1)
+end
+
+fmt=String.new
+if ARGV.size>=3
+  fmt=ARGV[2]
+else
+  fmt = "%s --> %s\n"
+end
+files = Array.new
+files = Dir.entries(ARGV[1])
+files.each{ |fn|
+  if check_match(ARGV[0], ARGV[1]+fn) 
+       printf(fmt, ARGV[0].to_s, ARGV[1]+fn.to_s)
+       puts ""
+#      puts("#{ARGV[0]} --> #{ARGV[1]+fn}")
+  end
+}
+
diff --git a/host/fix-wiki-size.rb b/host/fix-wiki-size.rb
new file mode 100644 (file)
index 0000000..53a480e
--- /dev/null
@@ -0,0 +1,82 @@
+#!/usr/bin/ruby
+# performnce to wiki
+
+=begin
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+=end
+
+
+require 'rubygems'
+require 'getopt/std'
+
+=begin
+|             Blake-28 ||   C ||   C 
+| 10916<br> 
+blake_small: 3494<br> 
+blake_large: 7142<br> 
+blake_common: 256<br> 
+memxor: 24 
+|   53 || ||  224 ||  512 ||    386 ||  71362 || 1115.03 ||  71893 || || || 
+|-
+
+=end
+
+
+def fix_file(fin, fout, supress)
+  loop do
+    return if fin.eof()
+    comp = Array.new
+    i = 0
+    lb1 = fin.readline()
+    lb2 = fin.readline()
+    begin
+      comp[i] = fin.readline()
+      i += 1
+    end until comp[i-1].match(/^\|/)
+    sum = 0
+    (i-1).times{ |j| sum += comp[j].match(/[^:]*:[\s]*([\d]*)/)[1].to_i}
+    fout.print(lb1.chomp)
+    if supress
+      fout.printf(" || %d |%s", sum, comp.last)    
+    else
+      fout.printf("\n| %d <br>\n", sum)
+      comp.each{ |s| fout.puts(s)}
+    end
+    begin
+      lb1 = fin.readline()
+      fout.puts(lb1)
+    end until lb1.match(/^\|\-/)
+  end
+end
+
+################################################################################
+# MAIN                                                                         #
+################################################################################
+
+fin = STDIN
+fout = STDOUT
+
+opts = Getopt::Std.getopts("s")
+
+fin  = File.open(ARGV[0], "r") if ARGV.size > 0
+fout = File.open(ARGV[1], "w") if ARGV.size > 1
+
+fix_file(fin, fout, opts["s"])
+
+fin.close  if ARGV.size > 0
+fout.close if ARGV.size > 1
+
diff --git a/host/gcdext-test.rb b/host/gcdext-test.rb
new file mode 100644 (file)
index 0000000..705b42a
--- /dev/null
@@ -0,0 +1,97 @@
+#!/usr/bin/ruby
+# gcdext-test.rb
+=begin
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008, 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+=end
+
+$debug = true
+$debug = false
+require 'rubygems'
+require 'serialport'
+require 'getopt/std'
+require 'ftools'
+require 'date'
+
+def gcdext(x,y)
+  g=1
+  i=0
+  while(x&1==0 && y&1==0) do
+    x>>=1
+    y>>=1
+    g<<=1
+    i+=1
+  end
+  printf("DBG: initshift = %04X\n", i)
+  u=x; v=y; a=1; b=0; c=0; d=1
+  begin
+    printf(" while u%%2==0; u = %X\n", u)
+    printf("DBG: (10) a = %s\n", a.to_s(16).upcase)
+    printf("DBG: (10) b = %s\n", b.to_s(16).upcase)
+    printf("DBG: (10) c = %s\n", c.to_s(16).upcase)
+    printf("DBG: (10) d = %s\n", d.to_s(16).upcase)
+    while(u&1==0) do
+      if(a%2==1 || b%2==1)
+        a += y
+        b -= x
+      end
+      u>>=1; a>>=1; b>>=1
+    end
+    printf(" while v%%2==0; v = %X\n", v)
+    printf("DBG: (20) a = %s\n", a.to_s(16).upcase)
+    printf("DBG: (20) b = %s\n", b.to_s(16).upcase)
+    printf("DBG: (20) c = %s\n", c.to_s(16).upcase)
+    printf("DBG: (20) d = %s\n", d.to_s(16).upcase)
+    while(v&1==0) do
+      if(c%2==1 || d%2==1)
+        c += y
+    #    printf("DBG: (qq) b = %s\n", b.to_s(16).upcase)
+        d -= x
+      end
+      printf("DBG: (xx) d = %s\n", d.to_s(16).upcase) 
+      v>>=1; c>>=1; d>>=1;
+    end
+    
+    printf(" if u>=v ...\n")
+    printf("DBG: (30) a = %s\n", a.to_s(16).upcase)
+    printf("DBG: (30) b = %s\n", b.to_s(16).upcase)
+    printf("DBG: (30) c = %s\n", c.to_s(16).upcase)
+    printf("DBG: (30) d = %s\n", d.to_s(16).upcase)
+
+    if(u>=v)
+      u -= v; a-=c; b-=d
+    else
+      v -= u; c-=a; d-=b
+    end
+  end while(u!=0)
+  return[g*v, c, d]
+end
+
+
+if ARGV.length==2
+  a = ARGV[0].to_i
+  b = ARGV[1].to_i
+else
+  # CD319349, 9EFD76CC
+  # 1609000771, 6fac577d72
+  a = 0x1609000771
+  b = 0x6fac577d72
+end
+r = gcdext(a, b)
+printf("gcdext( %s, %s) => a = %s; b = %s; gcd = %s\n",
+  a.to_s(16),b.to_s(16),r[1].to_s(16),r[2].to_s(16),r[0].to_s(16))
+
+
diff --git a/host/get_performance.rb b/host/get_performance.rb
new file mode 100644 (file)
index 0000000..b78ba99
--- /dev/null
@@ -0,0 +1,165 @@
+#!/usr/bin/ruby 
+# get_performance.rb
+=begin
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008, 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+=end
+
+$debug = false
+require 'rubygems'
+require 'serialport'
+require 'getopt/std'
+$conffile_check = Hash.new
+$conffile_check.default = 0
+
+################################################################################
+# readconfigfile                                                               #
+################################################################################
+
+def readconfigfile(fname, conf)
+  return conf if $conffile_check[fname]==1
+  $conffile_check[fname]=1
+  section = "default"
+  if not File.exists?(fname)
+    return conf
+  end
+  file = File.open(fname, "r")
+  until file.eof
+    line = file.gets()
+  next if /[\s]*#/.match(line)
+  if m=/\[[\s]*([^\s]*)[\s]*\]/.match(line)
+    section=m[1]
+    conf[m[1]] = Hash.new
+    next
+  end
+  next if not /=/.match(line)
+  m=/[\s]*([^\s]*)[\s]*=[\s]*([^\s]*)/.match(line)
+  if m[1]=="include"
+    Dir.glob(m[2]){ |fn| conf = readconfigfile(fn, conf) }
+  else
+      conf[section][m[1]] = m[2]
+  end
+  end
+  file.close()
+  return conf
+end
+
+################################################################################
+# read_line                                                                    #
+################################################################################
+
+def read_line(error_msg=true)
+  i=$extended_wait
+  begin
+    s = $sp.gets()
+  end until s or i==0
+  if s==nil
+    puts("ERROR: read timeout!\n") if error_msg
+       return nil
+  end  
+  s.gsub(/\006/, '');  
+end
+
+################################################################################
+# readPerformanceVector                                                        #
+################################################################################
+
+def readPerformanceVector(param)
+  lb=""
+  fname=""
+  fout=0
+  begin
+    lb = read_line()
+    if lb.match(/End of performance figures/)
+      return false
+         end
+       if m=lb.match(/=== (.*) performance ===/) 
+         fout.close if fout!=0
+         fname=$dir+m[1]
+         fname+="."+param if param != ""
+         fname+=".txt"
+         fout = File.open(fname, "w+")
+         printf("> %s \n", fname)      
+         fout.write(lb)
+      else
+         if fout!=0 && lb!=""
+           fout.write(lb)
+         end   
+       end
+  end while true
+end
+
+################################################################################
+# MAIN                                                                         #
+################################################################################
+
+
+opts = Getopt::Std.getopts("f:c:t:a:d")
+
+conf = Hash.new
+conf = readconfigfile("/etc/testport.conf", conf)
+conf = readconfigfile("~/.testport.conf", conf)
+conf = readconfigfile("testport.conf", conf)
+conf = readconfigfile(opts["f"], conf) if opts["f"]
+
+#puts conf.inspect
+
+puts("serial port interface version: " + SerialPort::VERSION);
+$linewidth = 64
+params = { "baud"       => conf["PORT"]["baud"].to_i,
+            "data_bits" => conf["PORT"]["databits"].to_i,
+            "stop_bits" => conf["PORT"]["stopbits"].to_i,
+            "parity"    => SerialPort::NONE }
+params["paraty"] = SerialPort::ODD   if conf["PORT"]["paraty"].downcase == "odd"
+params["paraty"] = SerialPort::EVEN  if conf["PORT"]["paraty"].downcase == "even"
+params["paraty"] = SerialPort::MARK  if conf["PORT"]["paraty"].downcase == "mark"
+params["paraty"] = SerialPort::SPACE if conf["PORT"]["paraty"].downcase == "space"
+
+puts("\nPort: "+conf["PORT"]["port"]+"@"    +
+                params["baud"].to_s      +
+                " "                      +
+                params["data_bits"].to_s +
+                conf["PORT"]["paraty"][0,1].upcase +
+                params["stop_bits"].to_s +
+                "\n")
+
+$sp = SerialPort.new(conf["PORT"]["port"], params)
+
+$sp.read_timeout=1000; # 5 minutes
+$sp.flow_control = SerialPort::SOFT
+=begin
+if ARGV.size < 1
+  STDERR.print <<EOF
+  Usage: ruby #{$0} -c command [-t target_dir] [-a additional specifier]
+EOF
+  exit(1)
+end
+=end
+
+command=opts['c']+"\r";
+$dir=(opts['t'])?opts['t']:"";
+param=(opts['a'])?opts['a']:"";
+
+$linewidth = 16
+$extended_wait=100;
+$sp.write(command);
+
+while(readPerformanceVector(param))
+end
+
+exit(0);
+
+
diff --git a/host/get_primes.rb b/host/get_primes.rb
new file mode 100644 (file)
index 0000000..14884d1
--- /dev/null
@@ -0,0 +1,52 @@
+#!/usr/bin/ruby 
+# get_primes.rb
+=begin
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+=end
+
+$primes = [2,3,5]
+
+def check_prime(a)
+  q = Math.sqrt(a)
+  $primes.each{ |p|
+    return true if p>q 
+       return false if a%p==0
+  }
+  return true
+end
+
+def find_primes(n)
+  a = $primes.last+2
+  while $primes.size < n
+    if check_prime(a)
+         $primes << a
+       end  
+       a += 2
+  end
+end
+
+if ARGV.size!=1
+  STDERR.print <<EOF
+  Usage: ruby #{$0} n
+   
+EOF
+  exit(1)
+end
+
+find_primes(ARGV[0].to_i);
+print($primes.join(', '))
+puts("")
diff --git a/host/get_test.rb b/host/get_test.rb
new file mode 100644 (file)
index 0000000..337ef3f
--- /dev/null
@@ -0,0 +1,128 @@
+#!/usr/bin/ruby 
+# get_test.rb
+=begin
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008, 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+=end
+
+require 'serialport'
+
+def read_line(error_msg=true)
+  s = $sp.gets()
+  if s==nil
+    puts("ERROR: read timeout!\n") if error_msg
+       return nil
+  end  
+  s.gsub(/\006/, '');  
+end
+
+def readTestVector(param)
+  fname=$dir;
+  lb="";
+  buffer="";
+  set=0;
+  vector=0;
+  begin
+    lb = read_line(false)
+       if (m=/unknown command/.match(lb) || m=/[Ee][Rr]{2}[Oo][Rr]/.match(lb))
+      puts("ERROR: "+lb);
+      exit(2);
+    end
+    if(lb==nil)
+      return false;
+    end
+  end while(m=/\*+/.match(lb));
+  
+  buffer += lb;
+  begin
+    lb = read_line()
+    if(lb==nil)
+      return false;
+    end
+    buffer+=lb;
+  end while(m=/\*.*/.match(lb));
+
+  while(!(m=/Test vectors/.match(lb))) 
+    m=/[^:]*:[\s]([A-Za-z0-9_-]*)/.match(lb);
+    if(m) 
+      fname+=m[1]+".";
+    end
+    return false if lb==nil
+    buffer+=lb;
+    lb = read_line();
+  end
+  if(param!="")
+    fname+=param+".";
+  end
+  puts("-> "+fname+"txt");
+  file=File.new(fname+"txt", "w");
+    buffer+=lb;
+    file.write(buffer);
+    begin
+      if (m=/Test\ vectors\ \-\-\ set[\s]+([0-9]+)/.match(lb))
+       set=m[1].to_i;
+       print("\nSet "+m[1]+":");
+      end
+      if (m=/Set [0-9]*, vector#[\s]*([0-9]+):/.match(lb))
+        vector=m[1].to_i;
+       #print(" "+m[1]);
+       if(vector!=0 && vector % $linewidth==0)
+         print("\n      ")
+       end
+        printf(" %4u", vector);
+      end
+      lb=read_line();
+      if(lb==nil)
+        file.close();
+        return false;
+      end
+      file.write(lb);
+    end while(!m=/End of test vectors/.match(lb));
+    puts("\n");
+  file.close();
+  return true
+end
+
+
+if ARGV.size < 5
+  STDERR.print <<EOF
+  Usage: ruby #{$0} port bps nbits stopb command [target_dir] [additional specifier]
+EOF
+  exit(1)
+end
+
+command=ARGV[4]+"\r";
+$dir=(ARGV.size>=6)?ARGV[5]:"";
+param=(ARGV.size>=7)?ARGV[6]:"";
+
+puts("\nPort: "+ARGV[0]+ "@"+ARGV[1]+" "+ARGV[2]+"N"+ARGV[3]+"\n");
+$linewidth = 16
+$sp = SerialPort.new(ARGV[0], ARGV[1].to_i, ARGV[2].to_i, ARGV[3].to_i, SerialPort::NONE);
+$sp.read_timeout=1000; # 1 secound
+$extended_wait=100;
+$sp.write(command);
+
+if(readTestVector(param)==false)
+  puts("ERROR: test seems not to be implemented");
+  exit(3);
+end
+
+while(readTestVector(param))
+end
+
+exit(0);
+
+
diff --git a/host/karatsuba.rb b/host/karatsuba.rb
new file mode 100644 (file)
index 0000000..1ea4257
--- /dev/null
@@ -0,0 +1,39 @@
+#!/usr/bin/ruby
+# bigint_test.rb
+=begin
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008, 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+=end
+
+$debug = true
+$debug = false
+require 'rubygems'
+require 'serialport'
+require 'getopt/std'
+require 'ftools'
+require 'date'
+$buffer_size = 0
+$conffile_check = Hash.new
+$conffile_check.default = 0
+
+def karatsuba_verbose(a,b)
+  a_s = a.to_s(16)
+  b_s = b.to_s(16)
+  len_a = floor((a_s.length+1)/2)
+  len_b = floor((b_s.length+1)/2)
+  n=floor((((len_a>len_b)?len_a:len_b)+1)/2)
+  
+end
\ No newline at end of file
diff --git a/host/nessie_check.rb b/host/nessie_check.rb
new file mode 100644 (file)
index 0000000..33eb4a3
--- /dev/null
@@ -0,0 +1,124 @@
+#!/usr/bin/ruby
+# nessie_check.rb
+=begin
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+=end
+
+def skip_header(file)
+  begin
+    l = file.gets().strip
+  end until /[*]{10,}.*/.match(l)
+  begin
+    l = file.gets().strip
+  end until /[*]{10,}.*/.match(l)
+  begin
+    l = file.gets().strip
+  end until /[=]{5,}.*/.match(l)
+  begin
+    l = file.gets().strip
+  end until /[=]{5,}.*/.match(l)
+end
+
+def get_next_assign(file, i)
+  key = String.new
+  value = String.new
+  if($last_assign[i]==nil)
+    begin
+         return nil if file.eof
+      l = file.gets().strip()
+    end until m=/[\s]*([\w]*)[\s]*=[\s]*([0-9a-fA-F]*).*/.match(l)
+       value = m[2]
+       key = m[1]
+       begin
+         return nil if file.eof
+         l = file.gets().strip()
+         if not /[^=]+=[^=]+/.match(l)
+           value += l if /^[0-9A-Fa-f]{5}/.match(l)
+         end
+    end until /[^=]+=[^=]+/.match(l)
+       $last_assign[i] = l
+  else
+    m=/[\s]*([\w]*)[\s]*=[\s]*([0-9a-fA-F]*).*/.match($last_assign[i])
+       value = m[2]
+       key = m[1]
+       begin
+         return nil if file.eof
+         l = file.gets().strip()
+         if not /[^=]+=[^=]+/.match(l)
+           value += l if /^[0-9A-Fa-f]{5}/.match(l)
+         end
+    end until /[^=]+=[^=]+/.match(l)
+       $last_assign[i] = l
+  end
+  return [key, value]
+end
+
+def compare(fname1, fname2)
+  file1 = File.new(fname1, "r")
+  file2 = File.new(fname2, "r")
+  skip_header(file1)
+  skip_header(file2)
+  pos=0
+  begin
+#      puts("checking set")
+    a = get_next_assign(file1, 0)
+    b = get_next_assign(file2, 1)
+       return if(a==nil or b==nil)
+       if not $quiet
+      puts("") if pos%$linewidth==0 and pos!=0
+         putc((a==b)?'*':'!')
+      pos +=1
+       end
+       if(a!=b and a!=nil and b!=nil)
+         $error += 1
+#        puts("a key: "+a[0]+" value: "+a[1])
+#        puts("b key: "+b[0]+" value: "+b[1])
+       end
+  end until a==nil or b==nil
+end
+
+$error = 0
+$linewidth=64
+$last_assign=[nil, nil]
+
+if ARGV.size<2 or ARGV.size>3
+  STDERR.print <<EOF
+  Usage: ruby #{$0} [-q|-v] file1 file2
+EOF
+  exit(1)
+end
+$quiet = false
+if ARGV.size==3
+  f1 = ARGV[1]
+  f2 = ARGV[2]
+  if ARGV[0]=="-q"
+    $quiet=true
+  end
+else
+  f1 = ARGV[0]
+  f2 = ARGV[1]
+end
+
+puts("compare("+f1+", "+f2+")")
+compare(f1, f2)
+if $error!=0
+  puts("[failed] ("+$error.to_s()+")")
+else
+  puts("[ok]")
+end
+
+exit($error)
diff --git a/host/optimize_shift.rb b/host/optimize_shift.rb
new file mode 100644 (file)
index 0000000..0cc277e
--- /dev/null
@@ -0,0 +1,100 @@
+#!/usr/bin/ruby 
+# shavs_test.rb
+=begin
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+=end
+
+shift_values = [ 5, 36, 13, 58, 26, 53, 11, 59, 
+                56, 28, 46, 44, 20, 35, 42, 50,
+               
+                           38, 48, 34, 26, 33, 39, 29, 33, 
+                30, 20, 14, 12, 49, 27, 26, 51,
+                50, 43, 15, 58,  8, 41, 11, 39,
+                53, 31, 27,  7, 42, 14,  9, 35,
+               
+                           55, 25, 33, 34, 28, 17, 58, 47,
+                43, 25,  8, 43,  7,  6,  7, 49,
+                37, 46, 18, 25, 47, 18, 32, 27,
+                40, 13, 57, 60, 48, 25, 45, 58,
+                16, 14, 21, 44, 51, 43, 19, 37,
+                22, 13, 12,  9,  9, 42, 18, 48,
+                38, 52, 32, 59, 35, 40,  2, 53,
+                12, 57, 54, 34, 41, 15, 56, 56 ]
+
+def transform_shift(value)
+  byteshift = (value+3)/8
+  singleshift = value%8
+  if singleshift>4
+ #   byteshift += 1
+       singleshift -= 8
+  end
+  return [singleshift, byteshift]
+end
+
+def transform_singleshift(value)
+  if(value>=0)
+    return value
+  end
+  return 0x08+(value*-1)
+end
+
+bs_hist = Hash.new
+bs_hist.default = 0
+ss_hist = Hash.new
+ss_hist.default = 0
+shift_values.each{|v|
+  
+  a = transform_shift(v)
+  printf("%2d = %2d * 8 %+2d\n", v, a[1], a[0])
+  bs_hist[a[1]] += 1
+  ss_hist[a[0]] += 1
+}
+
+puts("byteshift histogram:")
+for i in 0..7
+  printf("%d: %4d\n", i, bs_hist[i])
+ end
+
+puts("singleshift histogram:")
+for i in -3..4
+  printf("%+d: %4d\n", i, ss_hist[i])
+ end
+
+puts "\ntransformed:"
+(0..shift_values.length-1).each{|i|
+  puts " for 256 bit:" if i==0
+  puts " for 512 bit:" if i==16
+  puts " for 1024 bit:" if i==16+32
+  
+  a = transform_shift(shift_values[i])
+  a[0] = transform_singleshift(a[0])
+  printf("0x%01x%01x, ", a[1], a[0])
+  puts("") if (i%8==7)
+}
+
+
+puts "\ntransformed (decryption):"
+(0..shift_values.length-1).each{|i|
+  puts " for 256 bit:" if i==0
+  puts " for 512 bit:" if i==16
+  puts " for 1024 bit:" if i==16+32
+  
+  a = transform_shift(shift_values[(i/8)*8+7-(i%8)])
+  a[0] = transform_singleshift(a[0])
+  printf("0x%01x%01x, ", a[1], a[0])
+  puts("") if (i%8==7)
+}
diff --git a/host/shavs_test2.rb b/host/shavs_test2.rb
new file mode 100644 (file)
index 0000000..ab90192
--- /dev/null
@@ -0,0 +1,305 @@
+#!/usr/bin/ruby
+# shavs_test.rb
+=begin
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008, 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+=end
+
+$debug = true
+$debug = false
+require 'rubygems'
+require 'serialport'
+require 'getopt/std'
+
+$buffer_size = 0
+$conffile_check = Hash.new
+$conffile_check.default = 0
+
+################################################################################
+# readconfigfile                                                               #
+################################################################################
+
+def readconfigfile(fname, conf)
+  return conf if $conffile_check[fname]==1
+  $conffile_check[fname]=1
+  section = "default"
+  if not File.exists?(fname)
+    return conf
+  end
+  file = File.open(fname, "r")
+  until file.eof
+    line = file.gets()
+       next if /[\s]*#/.match(line)
+       if m=/\[[\s]*([^\s]*)[\s]*\]/.match(line)
+         section=m[1]
+         conf[m[1]] = Hash.new
+         next
+       end
+       next if not /=/.match(line)
+       m=/[\s]*([^\s]*)[\s]*=[\s]*([^\s]*)/.match(line)
+       if m[1]=="include"
+         Dir.glob(m[2]){ |fn| conf = readconfigfile(fn, conf) }
+       else
+         conf[section][m[1]] = m[2]
+       end
+  end
+  file.close()
+  return conf
+end
+
+################################################################################
+# reset_system                                                                 #
+################################################################################
+
+def reset_system
+  $sp.print("exit\r")
+  sleep 0.1
+  $sp.print("exit\r")
+  sleep 0.1
+end
+
+################################################################################
+# scan_system                                                                  #
+################################################################################
+
+def scan_system
+  algos = Hash.new
+  $sp.print("shavs_list\r")
+  while true
+    line=$sp.gets()
+    return algos if /^>$/.match(line)
+    if m = /[\*\ ]([a-z]):[\s]*([a-zA-Z0-9+_-]+)/.match(line)
+      algos[m[2]]=m[1]
+    end
+  end
+end
+
+################################################################################
+# init_system                                                                  #
+################################################################################
+
+def init_system(algo_select)
+  $sp.print("echo off \r")
+  print("DBG i: " + "echo off \r"+"\n") if $debug
+ sleep 0.1
+  $sp.print("shavs_set #{algo_select}\r")
+  print("DBG i: " + "shavs_set #{$algo_select} \r"+"\n") if $debug
+  sleep 0.1
+  $sp.print("shavs_test1 \r")
+  print("DBG i: " + "shavs_test1 \r"+"\n") if $debug
+  begin
+    line=$sp.gets()
+  end while not m=/buffer_size[\s]*=[\s]*0x([0-9A-Fa-f]*)/.match(line)
+  $buffer_size = m[1].to_i(16)
+end
+
+################################################################################
+# get_md                                                                       #
+################################################################################
+
+def get_md
+  begin
+    line = $sp.gets()
+       line = "" if line==nil
+       puts("DBG got: "+line) if $debug
+  end while not /[\s]*MD[\s]*=.*/.match(line)
+  return line
+end
+
+################################################################################
+# send_md                                                                      #
+################################################################################
+
+def send_md(md_string)
+  $sp.print("Msg = ")
+  for i in 0..md_string.length-1
+    $sp.print(md_string[i].chr)
+#      print("DBG s: "+ md_string[i].chr) if $debug
+#   sleep(0.001)
+       if((i%($buffer_size*2)==0)&&(i!=0))
+         begin
+               line=$sp.gets()
+         end while not /\./.match(line)
+       end
+  end
+end
+
+################################################################################
+# run_test                                                                     #
+################################################################################
+
+def run_test(filename, skip=0)
+  nerrors = 0
+  line=1
+  if not File.exist?(filename)
+       puts("ERROR file "+filename+" does not exist!")
+       return nerrors
+  end
+  pos = 0
+  file = File.new(filename, "r");
+  until file.eof
+    begin
+      lb=file.gets()
+#        printf("DBG info: file read: %s", lb)
+    end while not (file.eof or (/[\s]*Len[\s]*=/.match(lb)))
+#      puts("got ya")
+       if file.eof
+         file.close()
+         return nerrors
+       end
+       len = /[\s]*Len[\s]*=[\s]*([0-9]*)/.match(lb)[1].to_i
+       if(skip>0)
+         skip -= 1
+         redo
+       end
+    puts("DBG sending: "+lb) if $debug
+       $sp.print(lb.strip)
+       $sp.print("\r")
+    begin
+         lb=file.gets()
+    end while not (file.eof or (m=/[\s]*Msg[\s]*=[\s]*([0-9a-fA-F]*)/.match(lb)))
+    return if file.eof
+    puts("DBG sending: "+lb) if $debug
+       send_md(m[1])
+       avr_md = get_md()
+    begin
+         lb=file.gets()
+    end while not /[\s]*MD[\s]*=.*/.match(lb)
+       a = (/[\s]*MD[\s]*=[\s]*([0-9a-fA-F]*).*/.match(lb))[1];
+       b = (/[\s]*MD[\s]*=[\s]*([0-9a-fA-F]*).*/.match(avr_md))[1];
+       a.upcase!
+       b.upcase!
+       printf("\n%4d (%4d) [%5d]: ", line, (line-1)*$linewidth, len) if (pos%$linewidth==0 and $linewidth!=0)
+       line += 1               if (pos%$linewidth==0 and $linewidth!=0)
+       #sleep(1)
+       #putc((a==b)?'*':'!')
+       if(a==b)
+         putc('*')
+       else
+         putc('!')
+       #  printf("<%d>",len)
+         printf("\nError @%05d: %s [should]\n           != %s [is]- ",len, a, b)
+         nerrors += 1
+       end
+       pos += 1
+  end
+  file.close()
+  return nerrors
+end
+
+
+################################################################################
+# MAIN                                                                         #
+################################################################################
+
+opts = Getopt::Std.getopts("s:f:i:j:hdca")
+
+conf = Hash.new
+conf = readconfigfile("/etc/testport.conf", conf)
+conf = readconfigfile("~/.testport.conf", conf)
+conf = readconfigfile("testport.conf", conf)
+conf = readconfigfile(opts["f"], conf) if opts["f"]
+
+#puts conf.inspect
+
+puts("serial port interface version: " + SerialPort::VERSION);
+$linewidth = 64
+params = { "baud"       => conf["PORT"]["baud"].to_i,
+            "data_bits" => conf["PORT"]["databits"].to_i,
+            "stop_bits" => conf["PORT"]["stopbits"].to_i,
+            "parity"    => SerialPort::NONE }
+params["paraty"] = SerialPort::ODD   if conf["PORT"]["paraty"].downcase == "odd"
+params["paraty"] = SerialPort::EVEN  if conf["PORT"]["paraty"].downcase == "even"
+params["paraty"] = SerialPort::MARK  if conf["PORT"]["paraty"].downcase == "mark"
+params["paraty"] = SerialPort::SPACE if conf["PORT"]["paraty"].downcase == "space"
+
+puts("\nPort: "+conf["PORT"]["port"]+"@"    +
+                params["baud"].to_s      +
+                " "                      +
+                params["data_bits"].to_s +
+                conf["PORT"]["paraty"][0,1].upcase +
+                params["stop_bits"].to_s +
+                "\n")
+
+$sp = SerialPort.new(conf["PORT"]["port"], params)
+
+$sp.read_timeout=1000; # 5 minutes
+$sp.flow_control = SerialPort::SOFT
+
+reset_system()
+algos=scan_system()
+#puts algos.inspect
+
+if opts["d"]
+  $debug = true
+end
+
+if opts["s"]
+  algos_rev = algos.invert
+  algo_tasks = Array.new
+  opts["s"].each_byte{ |x|
+    if algos_rev[x.chr]
+      algo_tasks << [algos_rev[x.chr],x.chr]
+    end
+  }
+else
+  algo_tasks=algos.sort
+end
+
+algo_tasks.each do |algoa|
+  algo = algoa[0]
+  if conf[algo]==nil
+    puts("No test-set defined for #{algo} \r\n")
+    next
+  else
+       i=0
+       i = opts["j"] if opts["j"]
+       logfile=File.open(conf["PORT"]["testlogbase"]+algo+".txt", "a")
+       while conf[algo]["file_#{i}"] != nil
+         puts("Testing #{algo} with #{conf[algo]["file_#{i}"]}")
+         reset_system()
+         init_system(algoa[1])
+         skip=0
+         skip=opts["i"].to_i if opts["i"]
+         nerrors=run_test(conf[algo]["file_#{i}"], skip)
+      if nerrors == 0
+        puts("\n[ok]")
+        logfile.puts("[ok] "+conf[algo]["file_#{i}"]+ " ("+Time.now.to_s()+")")
+      else
+        puts("\n[errors: "+ nerrors.to_s() +"]")
+        logfile.puts("[error] "+nerrors.to_s+" "+conf[algo]["file_#{i}"]+ " ("+Time.now.to_s()+")")
+      end
+      i += 1
+    end
+    logfile.close()
+  end
+end
+
+=begin
+nerrors = 0
+for i in (5..(ARGV.size-1))
+  nerrors = run_test(ARGV[i])
+  if nerrors == 0
+    puts("\n[ok]")
+  else
+    puts("\n[errors: "+ nerrors.to_s() +"]")
+  end
+end
+ $sp.print("EXIT\r");
+
+#exit(0);
+=end
+
diff --git a/host/test.rb b/host/test.rb
new file mode 100644 (file)
index 0000000..a99c56e
--- /dev/null
@@ -0,0 +1,14 @@
+def a(n)
+  return (-n-65+512)%512
+end
+
+def b(n)
+  return (n+a(n)+65)%512
+end
+
+for i in (0..512)
+  puts("") if(i%32==0)
+  printf("%3d", b(i))
+end
+
+irb
diff --git a/host/threefish_helper.rb b/host/threefish_helper.rb
new file mode 100644 (file)
index 0000000..b15a26b
--- /dev/null
@@ -0,0 +1,28 @@
+#!/usr/bin/ruby
+#
+
+(0..19).each { |s|
+  printf("0x%s%s, ", ((s+0)%5).to_s,((s+1)%5).to_s)
+  printf("0x%s%s, ", ((s+2)%5).to_s,((s+3)%5).to_s)
+}
+
+puts("\n or (5)\n")
+(0..19+3).each { |s|
+  printf("0x%02x, ", ((s%5)*8))
+}
+
+puts("\n or (9)\n")
+(0..19+7).each { |s|
+  printf("0x%02x, ", ((s%9)*8))
+}
+
+puts("\n or (17)\n")
+(0..21+15).each { |s|
+  printf("0x%02x, ", ((s%17)*8))
+}
+
+
+puts("\n (3)\n")
+(0..24).each { |s|
+  printf("0x%02x, ", ((s%3)*8))
+}
diff --git a/host/threefish_helper_rc.rb b/host/threefish_helper_rc.rb
new file mode 100644 (file)
index 0000000..a7a47a2
--- /dev/null
@@ -0,0 +1,233 @@
+#!/usr/bin/ruby
+# threefish_helper_rc.rb
+=begin
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+=end
+
+
+def convert(value)
+  byteshift = (value+3)/8
+  bitshift = value-byteshift*8
+#  printf("%d --> %d,%d\n", value,byteshift,bitshift)
+  if bitshift<0
+    bitshift *= -1
+    bitshift += 0x08
+  end
+  ret = byteshift*16+bitshift
+  return ret
+end
+
+r00 = [14, 52, 23,  5, 25, 46, 58, 32]
+r01 = [16, 57, 40, 37, 33, 12, 22, 32]
+
+r10 = [46, 33, 17, 44, 39, 13, 25,  8]
+r11 = [36, 27, 49,  9, 30, 50, 29, 35]
+r12 = [19, 14, 36, 54, 34, 10, 39, 56]
+r13 = [37, 42, 39, 56, 24, 17, 43, 22]
+
+r20 = [24, 38, 33,  5, 41, 16, 31,  9]
+r21 = [13, 19,  4, 20,  9, 34, 44, 48]
+r22 = [ 8, 10, 51, 48, 37, 56, 47, 35]
+r23 = [47, 55, 13, 41, 31, 51, 46, 52]
+r24 = [ 8, 49, 34, 47, 12,  4, 19, 23]
+r25 = [17, 18, 41, 28, 47, 53, 42, 31]
+r26 = [22, 23, 59, 16, 44, 42, 44, 37]
+r27 = [37, 52, 17, 25, 30, 41, 25, 20]
+
+#################################################
+
+printf("threefish256_rc0:  .byte ")
+r00.each{ |x| printf("0x%2.2x, ",convert(x))}
+puts("")
+
+printf("threefish256_rc1:  .byte ")
+r01.each{ |x| printf("0x%2.2x, ",convert(x))}
+puts("\n\n")
+
+#################################################
+
+printf("threefish512_rc0:  .byte ")
+r10.each{ |x| printf("0x%2.2x, ",convert(x))}
+puts("")
+
+printf("threefish512_rc1:  .byte ")
+r11.each{ |x| printf("0x%2.2x, ",convert(x))}
+puts("")
+
+printf("threefish512_rc2:  .byte ")
+r12.each{ |x| printf("0x%2.2x, ",convert(x))}
+puts("")
+
+printf("threefish512_rc3:  .byte ")
+r13.each{ |x| printf("0x%2.2x, ",convert(x))}
+puts("\n\n")
+
+#################################################
+
+printf("threefish1024_rc0:  .byte ")
+r20.each{ |x| printf("0x%2.2x, ",convert(x))}
+puts("")
+
+printf("threefish1024_rc1:  .byte ")
+r21.each{ |x| printf("0x%2.2x, ",convert(x))}
+puts("")
+
+printf("threefish1024_rc2:  .byte ")
+r22.each{ |x| printf("0x%2.2x, ",convert(x))}
+puts("")
+
+printf("threefish1024_rc3:  .byte ")
+r23.each{ |x| printf("0x%2.2x, ",convert(x))}
+puts("")
+
+printf("threefish1024_rc4:  .byte ")
+r24.each{ |x| printf("0x%2.2x, ",convert(x))}
+puts("")
+
+printf("threefish1024_rc5:  .byte ")
+r25.each{ |x| printf("0x%2.2x, ",convert(x))}
+puts("")
+
+printf("threefish1024_rc6:  .byte ")
+r26.each{ |x| printf("0x%2.2x, ",convert(x))}
+puts("")
+
+printf("threefish1024_rc7:  .byte ")
+r27.each{ |x| printf("0x%2.2x, ",convert(x))}
+puts("\n\n")
+
+#################################################
+
+puts("REVERSE")
+
+printf(" uint8_t rc0[8] = { ")
+8.times{ |x| printf("%2.2d, ",r00[(7 - x)]) }
+puts("")
+
+printf(" uint8_t rc1[8] = { ")
+8.times{ |x| printf("%2.2d, ",r01[(7 - x)]) }
+puts("")
+
+printf("threefish256_rc0:  .byte ")
+8.times{ |x| printf("0x%2.2x, ",convert(r00[(7 - x)]) ) }
+puts("")
+
+printf("threefish256_rc1:  .byte ")
+8.times{ |x| printf("0x%2.2x, ",convert(r01[(7 - x)]) ) }
+puts("\n\n")
+
+#################################################
+
+printf(" uint8_t rc0[8] = { ")
+8.times{ |x| printf("%2.2d, ",r10[(7 - x)]) }
+puts("")
+
+printf(" uint8_t rc1[8] = { ")
+8.times{ |x| printf("%2.2d, ",r11[(7 - x)]) }
+puts("")
+
+printf(" uint8_t rc2[8] = { ")
+8.times{ |x| printf("%2.2d, ",r12[(7 - x)]) }
+puts("")
+
+printf(" uint8_t rc3[8] = { ")
+8.times{ |x| printf("%2.2d, ",r13[(7 - x)]) }
+puts("")
+
+
+printf("threefish512_rc0:  .byte ")
+8.times{ |x| printf("0x%2.2x, ",convert(r10[(7 - x)]) ) }
+puts("")
+
+printf("threefish512_rc1:  .byte ")
+8.times{ |x| printf("0x%2.2x, ",convert(r11[(7 - x)]) ) }
+puts("")
+
+printf("threefish512_rc2:  .byte ")
+8.times{ |x| printf("0x%2.2x, ",convert(r12[(7 - x)]) ) }
+puts("")
+
+printf("threefish512_rc3:  .byte ")
+8.times{ |x| printf("0x%2.2x, ",convert(r13[(7 - x)]) ) }
+puts("\n\n")
+
+#################################################
+
+printf(" uint8_t rc0[8] = { ")
+8.times{ |x| printf("%2.2d, ",r20[(7 - x)]) }
+puts("")
+
+printf(" uint8_t rc1[8] = { ")
+8.times{ |x| printf("%2.2d, ",r21[(7 - x)]) }
+puts("")
+
+printf(" uint8_t rc2[8] = { ")
+8.times{ |x| printf("%2.2d, ",r22[(7 - x)]) }
+puts("")
+
+printf(" uint8_t rc3[8] = { ")
+8.times{ |x| printf("%2.2d, ",r23[(7 - x)]) }
+puts("")
+
+printf(" uint8_t rc4[8] = { ")
+8.times{ |x| printf("%2.2d, ",r24[(7 - x)]) }
+puts("")
+
+printf(" uint8_t rc5[8] = { ")
+8.times{ |x| printf("%2.2d, ",r25[(7 - x)]) }
+puts("")
+
+printf(" uint8_t rc6[8] = { ")
+8.times{ |x| printf("%2.2d, ",r26[(7 - x)]) }
+puts("")
+
+printf(" uint8_t rc7[8] = { ")
+8.times{ |x| printf("%2.2d, ",r27[(7 - x)]) }
+puts("")
+
+printf("threefish1024_rc0:  .byte ")
+8.times{ |x| printf("0x%2.2x, ",convert(r20[(7 - x)]) ) }
+puts("")
+
+printf("threefish1024_rc1:  .byte ")
+8.times{ |x| printf("0x%2.2x, ",convert(r21[(7 - x)]) ) }
+puts("")
+
+printf("threefish1024_rc2:  .byte ")
+8.times{ |x| printf("0x%2.2x, ",convert(r22[(7 - x)]) ) }
+puts("")
+
+printf("threefish1024_rc3:  .byte ")
+8.times{ |x| printf("0x%2.2x, ",convert(r23[(7 - x)]) ) }
+puts("")
+
+printf("threefish1024_rc4:  .byte ")
+8.times{ |x| printf("0x%2.2x, ",convert(r24[(7 - x)]) ) }
+puts("")
+
+printf("threefish1024_rc5:  .byte ")
+8.times{ |x| printf("0x%2.2x, ",convert(r25[(7 - x)]) ) }
+puts("")
+
+printf("threefish1024_rc6:  .byte ")
+8.times{ |x| printf("0x%2.2x, ",convert(r26[(7 - x)]) ) }
+puts("")
+
+printf("threefish1024_rc7:  .byte ")
+8.times{ |x| printf("0x%2.2x, ",convert(r27[(7 - x)]) ) }
+puts("\n\n")
+
diff --git a/keccak/keccak.c b/keccak/keccak.c
new file mode 100644 (file)
index 0000000..f8e78dc
--- /dev/null
@@ -0,0 +1,259 @@
+/* keecak.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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 <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include "memxor.h"
+#include "keccak.h"
+
+#ifdef DEBUG
+#  undef DEBUG
+#endif
+
+#define DEBUG 0
+
+#if DEBUG
+#include "cli.h"
+
+void keccak_dump_state(uint64_t a[5][5]){
+       uint8_t i,j;
+       for(i=0; i<5; ++i){
+               cli_putstr("\r\n");
+               cli_putc('0'+i);
+               cli_putstr(": ");
+               for(j=0; j<5; ++j){
+                       cli_hexdump_rev(&(a[i][j]), 8);
+                       cli_putc(' ');
+               }
+       }
+}
+
+void keccak_dump_ctx(keccak_ctx_t* ctx){
+       keccak_dump_state(ctx->a);
+       cli_putstr("\r\nDBG: r: ");
+       cli_hexdump_rev(&(ctx->r), 2);
+       cli_putstr("\t c: ");
+       cli_hexdump_rev(&(ctx->c), 2);
+       cli_putstr("\t d: ");
+       cli_hexdump(&(ctx->d), 1);
+       cli_putstr("\t bs: ");
+       cli_hexdump(&(ctx->bs), 1);
+}
+
+#endif
+
+static const uint64_t rc[] = {
+       0x0000000000000001LL, 0x0000000000008082LL,
+       0x800000000000808ALL, 0x8000000080008000LL,
+       0x000000000000808BLL, 0x0000000080000001LL,
+       0x8000000080008081LL, 0x8000000000008009LL,
+       0x000000000000008ALL, 0x0000000000000088LL,
+       0x0000000080008009LL, 0x000000008000000ALL,
+       0x000000008000808BLL, 0x800000000000008BLL,
+       0x8000000000008089LL, 0x8000000000008003LL,
+       0x8000000000008002LL, 0x8000000000000080LL,
+       0x000000000000800ALL, 0x800000008000000ALL,
+       0x8000000080008081LL, 0x8000000000008080LL,
+       0x0000000080000001LL, 0x8000000080008008LL
+};
+
+uint64_t rotl64(uint64_t a, uint8_t r){
+        return (a<<r)|(a>>(64-r));
+}
+
+static const uint8_t r[5][5] = {
+               {  0, 36,  3, 41, 18 },
+               {  1, 44, 10, 45,  2 },
+               { 62,  6, 43, 15, 61 },
+               { 28, 55, 25, 21, 56 },
+               { 27, 20, 39,  8, 14 }
+};
+
+void keccak_round(uint64_t a[5][5], uint8_t rci){
+       uint64_t b[5][5];
+       uint8_t i,j;
+       /* theta */
+       for(i=0; i<5; ++i){
+               b[i][0] = a[0][i] ^ a[1][i] ^ a[2][i] ^ a[3][i] ^ a[4][i];
+       }
+       for(i=0; i<5; ++i){
+               b[i][1] = b[(4+i)%5][0] ^ rotl64(b[(i+1)%5][0], 1);
+       }
+       for(i=0; i<5; ++i){
+               for(j=0; j<5; ++j){
+                       a[j][i] ^= b[i][1];
+               }
+       }
+#if DEBUG
+       cli_putstr("\r\nAfter theta:");
+       keccak_dump_state(a);
+#endif
+       /* rho & pi */
+       for(i=0; i<5; ++i){
+               for(j=0; j<5; ++j){
+                       b[(2*i+3*j)%5][j] = rotl64(a[j][i], r[i][j]);
+               }
+       }
+#if DEBUG
+       cli_putstr("\r\n--- after rho & pi ---");
+       keccak_dump_state(a);
+#endif
+       /* chi */
+       for(i=0; i<5; ++i){
+               for(j=0; j<5; ++j){
+                       a[j][i] =  b[j][i] ^ ((~(b[j][(i+1)%5]))&(b[j][(i+2)%5]));
+               }
+       }
+#if DEBUG
+       cli_putstr("\r\nAfter chi:");
+       keccak_dump_state(a);
+#endif
+       /* iota */
+       uint64_t t;
+       t= rc[rci];
+       a[0][0] ^= t;
+#if DEBUG
+       cli_putstr("\r\nAfter iota:");
+       keccak_dump_state(a);
+#endif
+}
+
+void keccak_f1600(uint64_t a[5][5]){
+       uint8_t i=0;
+       do{
+#if DEBUG
+               cli_putstr("\r\n\r\n--- Round ");
+               cli_hexdump(&i, 1);
+               cli_putstr(" ---");
+#endif
+               keccak_round(a, i);
+       }while(++i<24);
+}
+
+void keccak_nextBlock(keccak_ctx_t* ctx, const void* block){
+       memxor(ctx->a, block, ctx->bs);
+       keccak_f1600(ctx->a);
+}
+
+void keccak_lastBlock(keccak_ctx_t* ctx, const void* block, uint16_t length_b){
+       while(length_b>=ctx->r){
+               keccak_nextBlock(ctx, block);
+               block = (uint8_t*)block + ctx->bs;
+               length_b -=  ctx->r;
+       }
+       uint8_t tmp[ctx->bs];
+       uint8_t pad[3];
+       memset(tmp, 0x00, ctx->bs);
+       memcpy(tmp, block, (length_b+7)/8);
+       /* appand 1 */
+       if(length_b&7){
+               /* we have some single bits */
+               uint8_t t;
+               t = tmp[length_b/8]>>(8-(length_b&7));
+               t |= 0x01<<(length_b&7);
+               tmp[length_b/8] = t;
+       }else{
+               tmp[length_b/8] = 0x01;
+       }
+       pad[0] = ctx->d;
+       pad[1] = ctx->bs;
+       pad[2] = 0x01;
+       if(length_b/8+1+3<=ctx->bs){
+               memcpy(tmp+length_b/8+1, pad, 3);
+       }else{
+               if(length_b/8+1+2<=ctx->bs){
+                       memcpy(tmp+length_b/8+1, pad, 2);
+                       keccak_nextBlock(ctx, tmp);
+                       memset(tmp, 0x00, ctx->bs);
+                       tmp[0]=0x01;
+               }else{
+                       if(length_b/8+1+1<=ctx->bs){
+                               memcpy(tmp+length_b/8+1, pad, 1);
+                               keccak_nextBlock(ctx, tmp);
+                               memset(tmp, 0x00, ctx->bs);
+                               tmp[0] = ctx->bs;
+                               tmp[1] = 0x01;
+                       }else{
+                               keccak_nextBlock(ctx, tmp);
+                               memset(tmp, 0x00, ctx->bs);
+                               tmp[0] = ctx->d;
+                               tmp[1] = ctx->bs;
+                               tmp[2] = 0x01;
+                       }
+               }
+       }
+       keccak_nextBlock(ctx, tmp);
+}
+
+void keccak_ctx2hash(void* dest, uint16_t length_b, keccak_ctx_t* ctx){
+       while(length_b>=ctx->r){
+               memcpy(dest, ctx->a, ctx->bs);
+               dest = (uint8_t*)dest + ctx->bs;
+               length_b -= ctx->r;
+               keccak_f1600(ctx->a);
+       }
+       memcpy(dest, ctx->a, (length_b+7)/8);
+}
+
+void keccak224_ctx2hash(void* dest, keccak_ctx_t* ctx){
+       keccak_ctx2hash(dest, 224, ctx);
+}
+
+void keccak256_ctx2hash(void* dest, keccak_ctx_t* ctx){
+       keccak_ctx2hash(dest, 256, ctx);
+}
+
+void keccak384_ctx2hash(void* dest, keccak_ctx_t* ctx){
+       keccak_ctx2hash(dest, 384, ctx);
+}
+
+void keccak512_ctx2hash(void* dest, keccak_ctx_t* ctx){
+       keccak_ctx2hash(dest, 512, ctx);
+}
+
+/*
+1. SHA3-224: âŒŠKeccak[r = 1152, c = 448, d = 28]⌋224
+2. SHA3-256: âŒŠKeccak[r = 1088, c = 512, d = 32]⌋256
+3. SHA3-384: âŒŠKeccak[r = 832, c = 768, d = 48]⌋384
+4. SHA3-512: âŒŠKeccak[r = 576, c = 1024, d = 64]⌋512
+*/
+void keccak_init(uint16_t r, uint16_t c, uint8_t d, keccak_ctx_t* ctx){
+       memset(ctx->a, 0x00, 5*5*8);
+       ctx->r = r;
+       ctx->c = c;
+       ctx->d = d;
+       ctx->bs = (uint8_t)(r/8);
+}
+
+void keccak224_init(keccak_ctx_t* ctx){
+       keccak_init(1152, 448, 28, ctx);
+}
+
+void keccak256_init(keccak_ctx_t* ctx){
+       keccak_init(1088, 512, 32, ctx);
+}
+
+void keccak384_init(keccak_ctx_t* ctx){
+       keccak_init( 832, 768, 48, ctx);
+}
+
+void keccak512_init(keccak_ctx_t* ctx){
+       keccak_init( 576, 1024, 64, ctx);
+}
diff --git a/keccak/keccak.h b/keccak/keccak.h
new file mode 100644 (file)
index 0000000..ff17657
--- /dev/null
@@ -0,0 +1,56 @@
+/* keccak.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+
+#ifndef KECCAK_H_
+#define KECCAK_H_
+
+#include <stdint.h>
+
+#define KECCAK224_BLOCKSIZE 1152
+#define KECCAK224_BLOCKSIZE_B (KECCAK224_BLOCKSIZE/8)
+#define KECCAK256_BLOCKSIZE 1088
+#define KECCAK256_BLOCKSIZE_B (KECCAK256_BLOCKSIZE/8)
+#define KECCAK384_BLOCKSIZE  832
+#define KECCAK384_BLOCKSIZE_B (KECCAK384_BLOCKSIZE/8)
+#define KECCAK512_BLOCKSIZE  576
+#define KECCAK512_BLOCKSIZE_B (KECCAK512_BLOCKSIZE/8)
+
+typedef struct{
+       uint64_t a[5][5];
+       uint16_t r, c;
+       uint8_t  d, bs;
+} keccak_ctx_t;
+
+
+void keccak_init(uint16_t r, uint16_t c, uint8_t d, keccak_ctx_t* ctx);
+void keccak224_init(keccak_ctx_t* ctx);
+void keccak256_init(keccak_ctx_t* ctx);
+void keccak384_init(keccak_ctx_t* ctx);
+void keccak512_init(keccak_ctx_t* ctx);
+
+void keccak_nextBlock(keccak_ctx_t* ctx, const void* block);
+void keccak_lastBlock(keccak_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void keccak_ctx2hash(void* dest, uint16_t length_b, keccak_ctx_t* ctx);
+void keccak224_ctx2hash(void* dest, keccak_ctx_t* ctx);
+void keccak256_ctx2hash(void* dest, keccak_ctx_t* ctx);
+void keccak384_ctx2hash(void* dest, keccak_ctx_t* ctx);
+void keccak512_ctx2hash(void* dest, keccak_ctx_t* ctx);
+
+#endif /* KECCAK_H_ */
diff --git a/keccak/memxor.c b/keccak/memxor.c
new file mode 100644 (file)
index 0000000..7485b3e
--- /dev/null
@@ -0,0 +1,12 @@
+#include <stdint.h>
+
+#include "memxor.h"
+
+void memxor(void* dest, const void* src, uint16_t n){
+  while(n--){
+    *((uint8_t*)dest) ^= *((uint8_t*)src);
+    dest = (uint8_t*)dest +1;
+    src  = (uint8_t*)src  +1;
+  }
+}
+
diff --git a/keccak/memxor.h b/keccak/memxor.h
new file mode 100644 (file)
index 0000000..a62a616
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef MEMXOR_H_
+#define MEMXOR_H_
+#include <stdint.h>
+
+void memxor(void* dest, const void* src, uint16_t n);
+
+#endif
diff --git a/md5/md5.c b/md5/md5.c
new file mode 100644 (file)
index 0000000..5df1df2
--- /dev/null
+++ b/md5/md5.c
@@ -0,0 +1,185 @@
+/* md5.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/* 
+ * \file       md5.c
+ * \author     Daniel Otte
+ * \date       2006-07-31
+ * \license GPLv3 or later
+ * \brief   Implementation of the MD5 hash algorithm as described in RFC 1321
+ * 
+ */
+
+ #include "md5.h"
+ #include "md5_sbox.h"
+ #include "cli.h" 
+ #include <stdint.h>
+ #include <string.h>
+ #undef DEBUG
+void md5_init(md5_ctx_t *s){
+       s->counter = 0;
+       s->a[0] = 0x67452301;
+       s->a[1] = 0xefcdab89;
+       s->a[2] = 0x98badcfe;
+       s->a[3] = 0x10325476;
+}
+
+static 
+uint32_t md5_F(uint32_t x, uint32_t y, uint32_t z){
+       return ((x&y)|((~x)&z));
+}
+
+static
+uint32_t md5_G(uint32_t x, uint32_t y, uint32_t z){
+       return ((x&z)|((~z)&y));
+}
+
+static
+uint32_t md5_H(uint32_t x, uint32_t y, uint32_t z){
+       return (x^y^z);
+}
+
+static
+uint32_t md5_I(uint32_t x, uint32_t y, uint32_t z){
+       return (y ^ (x | (~z)));
+}
+
+typedef uint32_t md5_func_t(uint32_t, uint32_t, uint32_t);
+
+#define ROTL32(x,n) (((x)<<(n)) | ((x)>>(32-(n))))  
+
+static
+void md5_core(uint32_t* a, void* block, uint8_t as, uint8_t s, uint8_t i, uint8_t fi){
+       uint32_t t;
+       md5_func_t* funcs[]={md5_F, md5_G, md5_H, md5_I};
+       as &= 0x3;
+       /* a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+#ifdef DEBUG
+       char funcc[]={'*', '-', '+', '~'};
+       cli_putstr("\r\n DBG: md5_core [");
+       cli_putc(funcc[fi]);
+       cli_hexdump(&as, 1); cli_putc(' ');
+       cli_hexdump(&k, 1); cli_putc(' ');
+       cli_hexdump(&s, 1); cli_putc(' ');
+       cli_hexdump(&i, 1); cli_putc(']');
+#endif 
+       t = a[as] + funcs[fi](a[(as+1)&3], a[(as+2)&3], a[(as+3)&3]) 
+           + *((uint32_t*)block) + pgm_read_dword(md5_T+i) ;
+       a[as]=a[(as+1)&3] + ROTL32(t, s);
+}
+
+void md5_nextBlock(md5_ctx_t *state, const void* block){
+       uint32_t        a[4];
+       uint8_t         m,n,i=0;
+       /* this requires other mixed sboxes */
+#ifdef DEBUG
+       cli_putstr("\r\n DBG: md5_nextBlock: block:\r\n");
+       cli_hexdump(block, 16); cli_putstr("\r\n");
+       cli_hexdump(block+16, 16);      cli_putstr("\r\n");
+       cli_hexdump(block+32, 16);      cli_putstr("\r\n");
+       cli_hexdump(block+48, 16);      cli_putstr("\r\n");
+#endif 
+       
+       a[0]=state->a[0];
+       a[1]=state->a[1];
+       a[2]=state->a[2];
+       a[3]=state->a[3];
+       
+       /* round 1 */
+       uint8_t s1t[]={7,12,17,22}; // 1,-1   1,4   2,-1   3,-2
+       for(m=0;m<4;++m){
+               for(n=0;n<4;++n){
+                       md5_core(a, &(((uint32_t*)block)[m*4+n]), 4-n, s1t[n],i++,0);
+               }
+       }
+       /* round 2 */
+       uint8_t s2t[]={5,9,14,20}; // 1,-3   1,1   2,-2   2,4
+       for(m=0;m<4;++m){
+               for(n=0;n<4;++n){
+                       md5_core(a, &(((uint32_t*)block)[(1+m*4+n*5)&0xf]), 4-n, s2t[n],i++,1);
+               }
+       }
+       /* round 3 */
+       uint8_t s3t[]={4,11,16,23}; // 0,4   1,3   2,0   3,-1
+       for(m=0;m<4;++m){
+               for(n=0;n<4;++n){
+                       md5_core(a, &(((uint32_t*)block)[(5-m*4+n*3)&0xf]), 4-n, s3t[n],i++,2);
+               }
+       }
+       /* round 4 */
+       uint8_t s4t[]={6,10,15,21}; // 1,-2   1,2   2,-1   3,-3
+       for(m=0;m<4;++m){
+               for(n=0;n<4;++n){
+                       md5_core(a, &(((uint32_t*)block)[(0-m*4+n*7)&0xf]), 4-n, s4t[n],i++,3);
+               }
+       }
+       state->a[0] += a[0];
+       state->a[1] += a[1];
+       state->a[2] += a[2];
+       state->a[3] += a[3];
+       state->counter++;
+}
+
+void md5_lastBlock(md5_ctx_t *state, const void* block, uint16_t length_b){
+       uint16_t l;
+       uint8_t b[64];
+       while (length_b >= 512){
+               md5_nextBlock(state, block);
+               length_b -= 512;
+               block = ((uint8_t*)block) + 512/8;
+       }
+       memset(b, 0, 64);
+       memcpy(b, block, length_b/8);
+       /* insert padding one */
+       l=length_b/8;
+       if(length_b%8){
+               uint8_t t;
+               t = ((uint8_t*)block)[l];
+               t |= (0x80>>(length_b%8));
+               b[l]=t;
+       }else{
+               b[l]=0x80;
+       }
+       /* insert length value */
+       if(l+sizeof(uint64_t) >= 512/8){
+               md5_nextBlock(state, b);
+               state->counter--;
+               memset(b, 0, 64-8);
+       }
+       *((uint64_t*)&b[64-sizeof(uint64_t)]) = (state->counter * 512) + length_b;
+       md5_nextBlock(state, b);
+}
+
+void md5_ctx2hash(md5_hash_t* dest, const md5_ctx_t* state){
+       memcpy(dest, state->a, MD5_HASH_BYTES);
+}
+
+void md5(md5_hash_t* dest, const void* msg, uint32_t length_b){
+       md5_ctx_t ctx;
+       md5_init(&ctx);
+       while(length_b>=MD5_BLOCK_BITS){
+               md5_nextBlock(&ctx, msg);
+               msg = (uint8_t*)msg + MD5_BLOCK_BYTES;
+               length_b -= MD5_BLOCK_BITS;
+       }
+       md5_lastBlock(&ctx, msg, length_b);
+       md5_ctx2hash(dest, &ctx);
+}
+
diff --git a/md5/md5.h b/md5/md5.h
new file mode 100644 (file)
index 0000000..6b65c4a
--- /dev/null
+++ b/md5/md5.h
@@ -0,0 +1,55 @@
+/* md5.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/* 
+ * File:       md5.h
+ * Author:     Daniel Otte
+ * Date:       31.07.2006
+ * License: GPL
+ * Description: Implementation of the MD5 hash algorithm as described in RFC 1321
+ * 
+ */
+
+
+#ifndef MD5_H_
+#define MD5_H_
+
+#include <stdint.h>
+
+
+#define MD5_HASH_BITS  128
+#define MD5_HASH_BYTES (MD5_HASH_BITS/8)
+#define MD5_BLOCK_BITS 512
+#define MD5_BLOCK_BYTES (MD5_BLOCK_BITS/8)
+
+
+typedef struct md5_ctx_st {
+       uint32_t a[4];
+       uint32_t counter;
+} md5_ctx_t;
+
+typedef uint8_t md5_hash_t[MD5_HASH_BYTES];
+
+void md5_init(md5_ctx_t *s);
+void md5_nextBlock(md5_ctx_t *state, const void* block);
+void md5_lastBlock(md5_ctx_t *state, const void* block, uint16_t length);
+void md5_ctx2hash(md5_hash_t* dest, const md5_ctx_t* state);
+void md5(md5_hash_t* dest, const void* msg, uint32_t length_b);
+
+#endif /*MD5_H_*/
diff --git a/md5/md5_sbox.h b/md5/md5_sbox.h
new file mode 100644 (file)
index 0000000..597b3db
--- /dev/null
@@ -0,0 +1,40 @@
+/* md5_sbox.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+#ifndef MD5_SBOX_H_
+#define MD5_SBOX_H_
+
+#include <stdint.h>
+#include <avr/pgmspace.h>
+
+uint32_t md5_T[] PROGMEM = {
+       0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 
+       0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 
+       0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 
+       0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 
+       0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 
+       0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 
+       0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 
+       0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 
+       0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 
+       0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 
+       0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 
+       0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 
+       0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };
+
+#endif /*MD5_SBOX_H_*/
diff --git a/mkfiles/001_bcal_std.mk b/mkfiles/001_bcal_std.mk
new file mode 100644 (file)
index 0000000..7045a5f
--- /dev/null
@@ -0,0 +1,2 @@
+BCAL_STD = nessie_common.o nessie_bc_test.o performance_test.o \
+           bcal-basic.o bcal-performance.o keysize_descriptor.o 
diff --git a/mkfiles/001_cli_std.mk b/mkfiles/001_cli_std.mk
new file mode 100644 (file)
index 0000000..59a9e77
--- /dev/null
@@ -0,0 +1,2 @@
+CLI_STD =  cli.o hexdigit_tab.o dbz_strings.o string-extras.o uart_i.o \
+           sysclock.o hw_gptm.o dump.o startup.o circularbytebuffer.o
diff --git a/mkfiles/001_hfal_std.mk b/mkfiles/001_hfal_std.mk
new file mode 100644 (file)
index 0000000..5604944
--- /dev/null
@@ -0,0 +1,3 @@
+HFAL_STD = nessie_common.o nessie_hash_test.o performance_test.o \
+           hfal-basic.o hfal-performance.o hfal-nessie.o hfal-test.o shavs.o 
+           
diff --git a/mkfiles/blake_c.mk b/mkfiles/blake_c.mk
new file mode 100644 (file)
index 0000000..c79b89b
--- /dev/null
@@ -0,0 +1,12 @@
+# Makefile for Blake
+ALGO_NAME := BLAKE_C
+
+# comment out the following line for removement of Blake from the build process
+HASHES += $(ALGO_NAME)
+
+$(ALGO_NAME)_DIR      := blake/
+$(ALGO_NAME)_OBJ      := blake_small.o blake_large.o blake_common.o memxor.o
+$(ALGO_NAME)_TEST_BIN := main-blake-test.o hfal_blake_small.o hfal_blake_large.o $(CLI_STD) $(HFAL_STD)
+$(ALGO_NAME)_NESSIE_TEST      := test nessie
+$(ALGO_NAME)_PERFORMANCE_TEST := performance
+
diff --git a/mkfiles/bmw_c.mk b/mkfiles/bmw_c.mk
new file mode 100644 (file)
index 0000000..03a1e9e
--- /dev/null
@@ -0,0 +1,12 @@
+# Makefile for BlueMidnightWish
+ALGO_NAME := BMW_C
+
+# comment out the following line for removement of BlueMidnightWish from the build process
+HASHES += $(ALGO_NAME)
+
+$(ALGO_NAME)_DIR      := bmw/
+$(ALGO_NAME)_OBJ      := bmw_small.o bmw_large.o memxor.o
+$(ALGO_NAME)_TEST_BIN := main-bmw-test.o hfal_bmw_small.o hfal_bmw_large.o $(CLI_STD) $(HFAL_STD)
+$(ALGO_NAME)_NESSIE_TEST      := test nessie
+$(ALGO_NAME)_PERFORMANCE_TEST := performance
+
diff --git a/mkfiles/bmw_c_speed.mk b/mkfiles/bmw_c_speed.mk
new file mode 100644 (file)
index 0000000..6e3d546
--- /dev/null
@@ -0,0 +1,12 @@
+# Makefile for BlueMidnightWish
+ALGO_NAME := BMW_C_SPEED
+
+# comment out the following line for removement of BlueMidnightWish from the build process
+HASHES += $(ALGO_NAME)
+
+$(ALGO_NAME)_DIR      := bmw/
+$(ALGO_NAME)_OBJ      := bmw_small_speed.o bmw_large.o memxor.o
+$(ALGO_NAME)_TEST_BIN := main-bmw-test.o hfal_bmw_small.o hfal_bmw_large.o $(CLI_STD) $(HFAL_STD)
+$(ALGO_NAME)_NESSIE_TEST      := test nessie
+$(ALGO_NAME)_PERFORMANCE_TEST := performance
+
diff --git a/mkfiles/cubehash_c.mk b/mkfiles/cubehash_c.mk
new file mode 100644 (file)
index 0000000..7ed0169
--- /dev/null
@@ -0,0 +1,12 @@
+# Makefile for CubeHash 
+ALGO_NAME := CUBEHASH_C
+
+# comment out the following line for removement of CubeHash from the build process
+HASHES += $(ALGO_NAME)
+
+$(ALGO_NAME)_DIR      := cubehash/
+$(ALGO_NAME)_OBJ      := cubehash.o memxor.o
+$(ALGO_NAME)_TEST_BIN := main-cubehash-test.o hfal_cubehash.o  $(CLI_STD) $(HFAL_STD)
+$(ALGO_NAME)_NESSIE_TEST      := test nessie
+$(ALGO_NAME)_PERFORMANCE_TEST := performance
+
diff --git a/mkfiles/echo_c.mk b/mkfiles/echo_c.mk
new file mode 100644 (file)
index 0000000..87d9846
--- /dev/null
@@ -0,0 +1,12 @@
+# Makefile for ECHO 
+ALGO_NAME := ECHO_C
+
+# comment out the following line for removement of ECHO from the build process
+HASHES += $(ALGO_NAME)
+
+$(ALGO_NAME)_DIR      := echo/
+$(ALGO_NAME)_OBJ      := echo.o memxor.o aes_enc_round.o aes_sbox.o gf256mul.o
+$(ALGO_NAME)_TEST_BIN := main-echo-test.o hfal_echo.o  $(CLI_STD) $(HFAL_STD)
+$(ALGO_NAME)_NESSIE_TEST      := test nessie
+$(ALGO_NAME)_PERFORMANCE_TEST := performance
+
diff --git a/mkfiles/groestl_c.mk b/mkfiles/groestl_c.mk
new file mode 100644 (file)
index 0000000..7d63a0d
--- /dev/null
@@ -0,0 +1,12 @@
+# Makefile for Grøstl
+ALGO_NAME := GROESTL_C
+
+# comment out the following line for removement of Grøstl from the build process
+HASHES += $(ALGO_NAME)
+
+$(ALGO_NAME)_DIR      := groestl/
+$(ALGO_NAME)_OBJ      := groestl_small.o groestl_large.o memxor.o aes_sbox.o gf256mul.o
+$(ALGO_NAME)_TEST_BIN := hfal_groestl_large.o hfal_groestl_small.o main-groestl-test.o $(CLI_STD) $(HFAL_STD)
+$(ALGO_NAME)_NESSIE_TEST      := test nessie
+$(ALGO_NAME)_PERFORMANCE_TEST := performance
+
diff --git a/mkfiles/keccak_c.mk b/mkfiles/keccak_c.mk
new file mode 100644 (file)
index 0000000..2041438
--- /dev/null
@@ -0,0 +1,12 @@
+# Makefile for Keccak
+ALGO_NAME := KECCAK_C
+
+# comment out the following line for removement of Keccak from the build process
+HASHES += $(ALGO_NAME)
+
+$(ALGO_NAME)_DIR      := keccak/
+$(ALGO_NAME)_OBJ      := keccak.o memxor.o
+$(ALGO_NAME)_TEST_BIN := main-keccak-test.o hfal_keccak.o  $(CLI_STD) $(HFAL_STD)
+$(ALGO_NAME)_NESSIE_TEST      := test nessie
+$(ALGO_NAME)_PERFORMANCE_TEST := performance
+
diff --git a/mkfiles/sha1_c.mk b/mkfiles/sha1_c.mk
new file mode 100644 (file)
index 0000000..4fef34b
--- /dev/null
@@ -0,0 +1,12 @@
+# Makefile for SHA1
+ALGO_NAME := SHA1_C
+
+# comment out the following line for removement of SHA1 from the build process
+HASHES += $(ALGO_NAME)
+
+$(ALGO_NAME)_DIR      := sha1/
+$(ALGO_NAME)_OBJ      := sha1.o
+$(ALGO_NAME)_TEST_BIN := main-sha1-test.o hfal_sha1.o $(CLI_STD) $(HFAL_STD)
+$(ALGO_NAME)_NESSIE_TEST      := "nessie"
+$(ALGO_NAME)_PERFORMANCE_TEST := "performance"
+
diff --git a/mkfiles/sha256_c.mk b/mkfiles/sha256_c.mk
new file mode 100644 (file)
index 0000000..1caf822
--- /dev/null
@@ -0,0 +1,12 @@
+# Makefile for SHA256
+ALGO_NAME := SHA256_C
+
+# comment out the following line for removement of SHA256 from the build process
+HASHES += $(ALGO_NAME)
+
+$(ALGO_NAME)_DIR      := sha256/
+$(ALGO_NAME)_OBJ      := sha256.o
+$(ALGO_NAME)_TEST_BIN := main-sha256-test.o $(CLI_STD) $(HFAL_STD) hfal_sha256.o 
+$(ALGO_NAME)_NESSIE_TEST      := "nessie"
+$(ALGO_NAME)_PERFORMANCE_TEST := "performance"
+
diff --git a/mkfiles/shabal_c.mk b/mkfiles/shabal_c.mk
new file mode 100644 (file)
index 0000000..d55c033
--- /dev/null
@@ -0,0 +1,12 @@
+# Makefile for Shabal
+ALGO_NAME := SHABAL_C
+
+# comment out the following line for removement of Shabal from the build process
+HASHES += $(ALGO_NAME)
+
+$(ALGO_NAME)_DIR      := shabal/
+$(ALGO_NAME)_OBJ      := shabal.o shabal192.o shabal224.o shabal256.o shabal384.o shabal512.o
+$(ALGO_NAME)_TEST_BIN := main-shabal-test.o hfal_shabal.o $(CLI_STD) $(HFAL_STD)
+$(ALGO_NAME)_NESSIE_TEST      := test nessie
+$(ALGO_NAME)_PERFORMANCE_TEST := performance
+
diff --git a/mkfiles/skein_c.mk b/mkfiles/skein_c.mk
new file mode 100644 (file)
index 0000000..676a024
--- /dev/null
@@ -0,0 +1,13 @@
+# Makefile for Skein
+ALGO_NAME := SKEIN_C
+
+# comment out the following line for removement of Skein from the build process
+HASHES += $(ALGO_NAME)
+
+$(ALGO_NAME)_DIR      := skein/
+$(ALGO_NAME)_OBJ      := threefish256_enc.o threefish512_enc.o threefish1024_enc.o threefish_mix_c.o\
+                         ubi256.o ubi512.o ubi1024.o memxor.o skein256.o skein512.o skein1024.o
+$(ALGO_NAME)_TEST_BIN := main-skein-test.o hfal_skein256.o hfal_skein512.o hfal_skein1024.o $(CLI_STD) $(HFAL_STD)
+$(ALGO_NAME)_NESSIE_TEST      := test nessie
+$(ALGO_NAME)_PERFORMANCE_TEST := performance
+
diff --git a/openocd.cfg b/openocd.cfg
new file mode 100644 (file)
index 0000000..a6c10ea
--- /dev/null
@@ -0,0 +1,7 @@
+source [find /usr/local/share/openocd/scripts/interface/luminary-icdi.cfg]
+source [find /usr/local/share/openocd/scripts/target/lm3s9b9x.cfg]
+# GDB can also flash my flash!
+gdb_memory_map enable
+gdb_flash_program enabe
+jtag_khz 500
+#source [find /usr/local/share/openocd/scripts/target/lm3s9b9x.cfg]
diff --git a/sha1/sha1.c b/sha1/sha1.c
new file mode 100644 (file)
index 0000000..f944d5a
--- /dev/null
@@ -0,0 +1,217 @@
+/* sha1.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file       sha1.c
+ * \author     Daniel Otte
+ * \date       2006-10-08
+ * \license GPLv3 or later
+ * \brief SHA-1 implementation.
+ *
+ */
+
+#include <string.h> /* memcpy & co */
+#include <stdint.h>
+#include "sha1.h"
+
+#ifdef DEBUG
+#  undef DEBUG
+#endif
+
+#define LITTLE_ENDIAN
+
+/********************************************************************************************************/
+
+/**
+ * \brief initialises given SHA-1 context
+ *
+ */
+void sha1_init(sha1_ctx_t *state){
+       state->h[0] = 0x67452301;
+       state->h[1] = 0xefcdab89;
+       state->h[2] = 0x98badcfe;
+       state->h[3] = 0x10325476;
+       state->h[4] = 0xc3d2e1f0;
+       state->length = 0;
+}
+
+/********************************************************************************************************/
+/* some helping functions */
+const
+uint32_t rotl32(uint32_t n, uint8_t bits){
+       return ((n<<bits) | (n>>(32-bits)));
+}
+
+const
+uint32_t change_endian32(uint32_t x){
+       return (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8));
+}
+
+
+/* three SHA-1 inner functions */
+const
+uint32_t ch(uint32_t x, uint32_t y, uint32_t z){
+       return ((x&y)^((~x)&z));
+}
+
+const
+uint32_t maj(uint32_t x, uint32_t y, uint32_t z){
+       return ((x&y)^(x&z)^(y&z));
+}
+
+const
+uint32_t parity(uint32_t x, uint32_t y, uint32_t z){
+       return ((x^y)^z);
+}
+
+/********************************************************************************************************/
+/**
+ * \brief "add" a block to the hash
+ * This is the core function of the hash algorithm. To understand how it's working
+ * and what thoese variables do, take a look at FIPS-182. This is an "alternativ" implementation
+ */
+
+#define MASK 0x0000000f
+
+typedef uint32_t (*pf_t)(uint32_t x, uint32_t y, uint32_t z);
+
+void sha1_nextBlock (sha1_ctx_t *state, const void* block){
+       uint32_t a[5];
+       uint32_t w[16];
+       uint32_t temp;
+       uint8_t t,s,fi, fib;
+       pf_t f[] = {ch,parity,maj,parity};
+       uint32_t k[4]={ 0x5a827999,
+                                       0x6ed9eba1,
+                                       0x8f1bbcdc,
+                                       0xca62c1d6};
+
+       /* load the w array (changing the endian and so) */
+       for(t=0; t<16; ++t){
+               w[t] = change_endian32(((uint32_t*)block)[t]);
+       }
+
+#if DEBUG
+       uint8_t dbgi;
+       for(dbgi=0; dbgi<16; ++dbgi){
+               cli_putstr("\r\nBlock:");
+               cli_hexdump(&dbgi, 1);
+               cli_putc(':');
+               cli_hexdump(&(w[dbgi]) ,4);
+       }
+#endif
+
+       /* load the state */
+       memcpy(a, state->h, 5*sizeof(uint32_t));
+
+
+       /* the fun stuff */
+       for(fi=0,fib=0,t=0; t<=79; ++t){
+               s = t & MASK;
+               if(t>=16){
+                       w[s] = rotl32( w[(s+13)&MASK] ^ w[(s+8)&MASK] ^
+                                w[(s+ 2)&MASK] ^ w[s] ,1);
+               }
+
+               uint32_t dtemp;
+               temp = rotl32(a[0],5) + (dtemp=f[fi](a[1],a[2],a[3])) + a[4] + k[fi] + w[s];
+               memmove(&(a[1]), &(a[0]), 4*sizeof(uint32_t)); /* e=d; d=c; c=b; b=a; */
+               a[0] = temp;
+               a[2] = rotl32(a[2],30); /* we might also do rotr32(c,2) */
+               fib++;
+               if(fib==20){
+                       fib=0;
+                       fi = (fi+1)%4;
+               }
+       }
+
+       /* update the state */
+       for(t=0; t<5; ++t){
+               state->h[t] += a[t];
+       }
+       state->length += 512;
+}
+
+/********************************************************************************************************/
+
+void sha1_lastBlock(sha1_ctx_t *state, const void* block, uint16_t length){
+       uint8_t lb[SHA1_BLOCK_BYTES]; /* local block */
+       while(length>=SHA1_BLOCK_BITS){
+               sha1_nextBlock(state, block);
+               length -= SHA1_BLOCK_BITS;
+               block = (uint8_t*)block + SHA1_BLOCK_BYTES;
+       }
+       state->length += length;
+       memset(lb, 0, SHA1_BLOCK_BYTES);
+       memcpy (lb, block, (length+7)>>3);
+
+       /* set the final one bit */
+       lb[length>>3] |= 0x80>>(length & 0x07);
+
+       if (length>512-64-1){ /* not enouth space for 64bit length value */
+               sha1_nextBlock(state, lb);
+               state->length -= 512;
+               memset(lb, 0, SHA1_BLOCK_BYTES);
+       }
+       /* store the 64bit length value */
+#if defined LITTLE_ENDIAN
+               /* this is now rolled up */
+       uint8_t i;
+       for (i=0; i<8; ++i){
+               lb[56+i] = ((uint8_t*)&(state->length))[7-i];
+       }
+#elif defined BIG_ENDIAN
+       *((uint64_t)&(lb[56])) = state->length;
+#endif
+       sha1_nextBlock(state, lb);
+}
+
+/********************************************************************************************************/
+
+void sha1_ctx2hash (sha1_hash_t *dest, sha1_ctx_t *state){
+#if defined LITTLE_ENDIAN
+       uint8_t i;
+       for(i=0; i<5; ++i){
+               ((uint32_t*)dest)[i] = change_endian32(state->h[i]);
+       }
+#elif BIG_ENDIAN
+       if (dest != state->h)
+               memcpy(dest, state->h, SHA1_HASH_BITS/8);
+#else
+# error unsupported endian type!
+#endif
+}
+
+/********************************************************************************************************/
+/**
+ *
+ *
+ */
+void sha1 (sha1_hash_t *dest, const void* msg, uint32_t length){
+       sha1_ctx_t s;
+       sha1_init(&s);
+       while(length & (~0x0001ff)){ /* length>=512 */
+               sha1_nextBlock(&s, msg);
+               msg = (uint8_t*)msg + SHA1_BLOCK_BITS/8; /* increment pointer to next block */
+               length -= SHA1_BLOCK_BITS;
+       }
+       sha1_lastBlock(&s, msg, length);
+       sha1_ctx2hash(dest, &s);
+}
+
+
diff --git a/sha1/sha1.h b/sha1/sha1.h
new file mode 100644 (file)
index 0000000..6675d20
--- /dev/null
@@ -0,0 +1,117 @@
+/* sha1.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file       sha1.h
+ * \author     Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date       2006-10-08
+ * \license GPLv3 or later
+ * \brief   SHA-1 declaration.
+ * \ingroup SHA-1
+ * 
+ */
+#ifndef SHA1_H_
+#define SHA1_H_
+
+#include <stdint.h>
+/** \def SHA1_HASH_BITS
+ * definees the size of a SHA-1 hash in bits 
+ */
+
+/** \def SHA1_HASH_BYTES
+ * definees the size of a SHA-1 hash in bytes 
+ */
+
+/** \def SHA1_BLOCK_BITS
+ * definees the size of a SHA-1 input block in bits 
+ */
+
+/** \def SHA1_BLOCK_BYTES
+ * definees the size of a SHA-1 input block in bytes 
+ */
+#define SHA1_HASH_BITS  160
+#define SHA1_HASH_BYTES (SHA1_HASH_BITS/8)
+#define SHA1_BLOCK_BITS 512
+#define SHA1_BLOCK_BYTES (SHA1_BLOCK_BITS/8)
+
+/** \typedef sha1_ctx_t
+ * \brief SHA-1 context type
+ * 
+ * A vatiable of this type may hold the state of a SHA-1 hashing process
+ */
+typedef struct {
+       uint32_t h[5];
+       uint64_t length;
+} sha1_ctx_t;
+
+/** \typedef sha1_hash_t
+ * \brief hash value type
+ * A variable of this type may hold a SHA-1 hash value 
+ */
+typedef uint8_t sha1_hash_t[SHA1_HASH_BITS/8];
+
+/** \fn sha1_init(sha1_ctx_t *state)
+ * \brief initializes a SHA-1 context
+ * This function sets a ::sha1_ctx_t variable to the initialization vector
+ * for SHA-1 hashing.
+ * \param state pointer to the SHA-1 context variable
+ */
+void sha1_init(sha1_ctx_t *state);
+
+/** \fn sha1_nextBlock(sha1_ctx_t *state, const void* block)
+ *  \brief process one input block
+ * This function processes one input block and updates the hash context 
+ * accordingly
+ * \param state pointer to the state variable to update
+ * \param block pointer to the message block to process
+ */
+void sha1_nextBlock (sha1_ctx_t *state, const void* block);
+
+/** \fn sha1_lastBlock(sha1_ctx_t *state, const void* block, uint16_t length_b)
+ * \brief processes the given block and finalizes the context
+ * This function processes the last block in a SHA-1 hashing process.
+ * The block should have a maximum length of a single input block.
+ * \param state pointer to the state variable to update and finalize
+ * \param block pointer to themessage block to process
+ * \param length_b length of the message block in bits  
+ */
+void sha1_lastBlock (sha1_ctx_t *state, const void* block, uint16_t length_b);
+
+/** \fn sha1_ctx2hash(sha1_hash_t *dest, sha1_ctx_t *state)
+ * \brief convert a state variable into an actual hash value
+ * Writes the hash value corresponding to the state to the memory pointed by dest.
+ * \param dest pointer to the hash value destination
+ * \param state pointer to the hash context
+ */ 
+void sha1_ctx2hash (sha1_hash_t *dest, sha1_ctx_t *state);
+
+/** \fn sha1(sha1_hash_t *dest, const void* msg, uint32_t length_b)
+ * \brief hashing a message which in located entirely in RAM
+ * This function automatically hashes a message which is entirely in RAM with
+ * the SHA-1 hashing algorithm.
+ * \param dest pointer to the hash value destination
+ * \param msg  pointer to the message which should be hashed
+ * \param length_b length of the message in bits
+ */ 
+void sha1(sha1_hash_t *dest, const void* msg, uint32_t length_b);
+
+
+
+#endif /*SHA1_H_*/
diff --git a/sha256/sha256.c b/sha256/sha256.c
new file mode 100644 (file)
index 0000000..83b3a43
--- /dev/null
@@ -0,0 +1,238 @@
+/* sha256.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file               sha256.c
+ * \author             Daniel Otte
+ * \date               16.05.2006
+ *
+ * \par License:
+ *     GPL
+ *
+ * \brief SHA-256 implementation.
+ *
+ *
+ */
+
+#include <stdint.h>
+#include <string.h> /* for memcpy, memmove, memset */
+#include "sha256.h"
+
+#define LITTLE_ENDIAN
+
+#if defined LITTLE_ENDIAN
+#elif defined BIG_ENDIAN
+#else
+       #error specify endianess!!!
+#endif
+
+
+/*************************************************************************/
+
+const
+uint32_t sha256_init_vector[]={
+       0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
+    0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 };
+
+
+/*************************************************************************/
+
+/**
+ * \brief \c sh256_init initialises a sha256 context for hashing.
+ * \c sh256_init c initialises the given sha256 context for hashing
+ * @param state pointer to a sha256 context
+ * @return none
+ */
+void sha256_init(sha256_ctx_t *state){
+       state->length=0;
+       memcpy(state->h, sha256_init_vector, 8*4);
+}
+
+/*************************************************************************/
+
+/**
+ * rotate x right by n positions
+ */
+uint32_t rotr32( uint32_t x, uint8_t n){
+       return ((x>>n) | (x<<(32-n)));
+}
+
+
+/*************************************************************************/
+
+// #define CHANGE_ENDIAN32(x) (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8))
+
+uint32_t change_endian32(uint32_t x){
+       return (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8));
+}
+
+
+/*************************************************************************/
+
+/* sha256 functions as macros for speed and size, cause they are called only once */
+
+#define CH(x,y,z)  (((x)&(y)) ^ ((~(x))&(z)))
+#define MAJ(x,y,z) (((x)&(y)) ^ ((x)&(z)) ^ ((y)&(z)))
+
+#define SIGMA0(x) (rotr32((x),2) ^ rotr32((x),13) ^ rotr32((x),22))
+#define SIGMA1(x) (rotr32((x),6) ^ rotr32((x),11) ^ rotr32((x),25))
+#define SIGMA_a(x) (rotr32((x),7)  ^ rotr32((x),18) ^ ((x)>>3))
+#define SIGMA_b(x) (rotr32((x),17) ^ rotr32((x),19) ^ ((x)>>10))
+
+const
+uint32_t k[]={
+       0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+       0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+       0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+       0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+       0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+       0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+       0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+       0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+
+/*************************************************************************/
+
+/**
+ * block must be, 512, Bit = 64, Byte, long !!!
+ */
+void sha256_nextBlock (sha256_ctx_t *state, const void* block){
+       uint32_t w[64]; /* this is 256, byte, large, */
+       uint8_t  i;
+       uint32_t a[8],t1,t2;
+
+       /* init w */
+#if defined LITTLE_ENDIAN
+               for (i=0; i<16; ++i){
+                       w[i]= change_endian32(((uint32_t*)block)[i]);
+               }
+#elif defined BIG_ENDIAN
+               memcpy((void*)w, block, 64);
+#endif
+               for (i=16; i<64; ++i){
+                       w[i] = SIGMA_b(w[i-2]) + w[i-7] + SIGMA_a(w[i-15]) + w[i-16];
+               }
+
+       /* init working variables */
+               memcpy((void*)a,(void*)(state->h), 8*4);
+
+       /* do the, fun stuff, */
+               for (i=0; i<64; ++i){
+                       t1 = a[7] + SIGMA1(a[4]) + CH(a[4],a[5],a[6]) + k[i] + w[i];
+                       t2 = SIGMA0(a[0]) + MAJ(a[0],a[1],a[2]);
+                       memmove(&(a[1]), &(a[0]), 7*4);         /* a[7]=a[6]; a[6]=a[5]; a[5]=a[4]; a[4]=a[3]; a[3]=a[2]; a[2]=a[1]; a[1]=a[0]; */
+                       a[4] += t1;
+                       a[0] = t1 + t2;
+               }
+
+       /* update, the, state, */
+               for (i=0; i<8; ++i){
+                       state->h[i] += a[i];
+               }
+               state->length += 512;
+}
+
+
+/*************************************************************************/
+
+/**
+ * \brief function to process the last block being hashed
+ * @param state Pointer to the context in which this block should be processed.
+ * @param block Pointer to the message wich should be hashed.
+ * @param length is the length of only THIS block in BITS not in bytes!
+ *  bits are big endian, meaning high bits come first.
+ *     if you have a message with bits at the end, the byte must be padded with zeros
+ */
+void sha256_lastBlock(sha256_ctx_t *state, const void* block, uint16_t length){
+       uint8_t lb[SHA256_BLOCK_BITS/8]; /* local block */
+       while(length>=SHA256_BLOCK_BITS){
+               sha256_nextBlock(state, block);
+               length -= SHA256_BLOCK_BITS;
+               block = (uint8_t*)block+SHA256_BLOCK_BYTES;
+       }
+
+       state->length += length;
+       memcpy (&(lb[0]), block, length/8);
+
+       /* set the final one bit */
+       if (length & 0x7){ // if we have single bits at the end
+               lb[length/8] = ((uint8_t*)(block))[length/8];
+       } else {
+               lb[length/8] = 0;
+       }
+       lb[length/8] |= 0x80>>(length & 0x7);
+       length =(length >> 3) + 1; /* from now on length contains the number of BYTES in lb*/
+       /* pad with zeros */
+       if (length>64-8){ /* not enouth space for 64bit length value */
+               memset((void*)(&(lb[length])), 0, 64-length);
+               sha256_nextBlock(state, lb);
+               state->length -= 512;
+               length = 0;
+       }
+       memset((void*)(&(lb[length])), 0, 56-length);
+       /* store the 64bit length value */
+#if defined LITTLE_ENDIAN
+               /* this is now rolled up */
+       uint8_t i;
+       for (i=1; i<=8; ++i){
+               lb[55+i] = (uint8_t)(state->length>>(64- 8*i));
+       }
+#elif defined BIG_ENDIAN
+       *((uint64_t)&(lb[56])) = state->length;
+#endif
+       sha256_nextBlock(state, lb);
+}
+
+
+/*************************************************************************/
+
+/*
+ * length in bits!
+ */
+void sha256(sha256_hash_t *dest, const void* msg, uint32_t length){ /* length could be choosen longer but this is for ÂµC */
+       sha256_ctx_t s;
+       sha256_init(&s);
+       while(length >= SHA256_BLOCK_BITS){
+               sha256_nextBlock(&s, msg);
+               msg = (uint8_t*)msg + SHA256_BLOCK_BITS/8;
+               length -= SHA256_BLOCK_BITS;
+       }
+       sha256_lastBlock(&s, msg, length);
+       sha256_ctx2hash(dest,&s);
+}
+
+
+
+/*************************************************************************/
+
+void sha256_ctx2hash(sha256_hash_t *dest, const sha256_ctx_t *state){
+#if defined LITTLE_ENDIAN
+       uint8_t i;
+       for(i=0; i<8; ++i){
+               ((uint32_t*)dest)[i] = change_endian32(state->h[i]);
+       }
+#elif BIG_ENDIAN
+       if (dest != state->h)
+               memcpy(dest, state->h, SHA256_HASH_BITS/8);
+#else
+# error unsupported endian type!
+#endif
+}
+
+
diff --git a/sha256/sha256.h b/sha256/sha256.h
new file mode 100644 (file)
index 0000000..ca91926
--- /dev/null
@@ -0,0 +1,122 @@
+/* sha256.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file       sha256.h
+ * \author  Daniel Otte 
+ * \date    2006-05-16
+ * \license    GPLv3 or later
+ * 
+ */
+
+#ifndef SHA256_H_
+#define SHA256_H_
+
+#define __LITTLE_ENDIAN__
+
+
+#include <stdint.h>
+
+/** \def SHA256_HASH_BITS
+ * defines the size of a SHA-256 hash value in bits
+ */
+
+/** \def SHA256_HASH_BYTES
+ * defines the size of a SHA-256 hash value in bytes
+ */
+
+/** \def SHA256_BLOCK_BITS
+ * defines the size of a SHA-256 input block in bits
+ */
+
+/** \def SHA256_BLOCK_BYTES
+ * defines the size of a SHA-256 input block in bytes
+ */
+
+#define SHA256_HASH_BITS  256
+#define SHA256_HASH_BYTES (SHA256_HASH_BITS/8)
+#define SHA256_BLOCK_BITS 512
+#define SHA256_BLOCK_BYTES (SHA256_BLOCK_BITS/8)
+
+/** \typedef sha256_ctx_t
+ * \brief SHA-256 context type
+ * 
+ * A variable of this type may hold the state of a SHA-256 hashing process
+ */
+typedef struct {
+       uint32_t h[8];
+       uint64_t length;
+} sha256_ctx_t;
+
+/** \typedef sha256_hash_t
+ * \brief SHA-256 hash value type
+ * 
+ * A variable of this type may hold the hash value produced by the
+ * sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state) function.
+ */
+typedef uint8_t sha256_hash_t[SHA256_HASH_BYTES];
+
+/** \fn void sha256_init(sha256_ctx_t *state)
+ * \brief initialize a SHA-256 context
+ * 
+ * This function sets a ::sha256_ctx_t to the initial values for hashing.
+ * \param state pointer to the SHA-256 hashing context
+ */
+void sha256_init(sha256_ctx_t *state);
+
+/** \fn void sha256_nextBlock (sha256_ctx_t* state, const void* block)
+ * \brief update the context with a given block
+ * 
+ * This function updates the SHA-256 hash context by processing the given block
+ * of fixed length.
+ * \param state pointer to the SHA-256 hash context
+ * \param block pointer to the block of fixed length (512 bit = 64 byte)
+ */
+void sha256_nextBlock (sha256_ctx_t* state, const void* block);
+
+/** \fn void sha256_lastBlock(sha256_ctx_t* state, const void* block, uint16_t length_b)
+ * \brief finalize the context with the given block 
+ * 
+ * This function finalizes the SHA-256 hash context by processing the given block
+ * of variable length.
+ * \param state pointer to the SHA-256 hash context
+ * \param block pointer to the block of fixed length (512 bit = 64 byte)
+ * \param length_b the length of the block in bits
+ */
+void sha256_lastBlock(sha256_ctx_t* state, const void* block, uint16_t length_b);
+
+/** \fn void sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state)
+ * \brief convert the hash state into the hash value
+ * This function reads the context and writes the hash value to the destination
+ * \param dest pointer to the location where the hash value should be written
+ * \param state pointer to the SHA-256 hash context
+ */
+void sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state);
+
+/** \fn void sha256(sha256_hash_t* dest, const void* msg, uint32_t length_b)
+ * \brief simple SHA-256 hashing function for direct hashing
+ * 
+ * This function automatically hashes a given message of arbitary length with
+ * the SHA-256 hashing algorithm.
+ * \param dest pointer to the location where the hash value is going to be written to
+ * \param msg pointer to the message thats going to be hashed
+ * \param length_b length of the message in bits
+ */
+void sha256(sha256_hash_t* dest, const void* msg, uint32_t length_b);
+
+#endif /*SHA256_H_*/
diff --git a/shabal/shabal.c b/shabal/shabal.c
new file mode 100644 (file)
index 0000000..8972760
--- /dev/null
@@ -0,0 +1,121 @@
+/* shabal.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    shabal.c
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-04-17
+ * \license GPLv3 or later
+ * 
+ */
+
+#include <stdint.h>
+#include "shabal.h"
+#include <string.h>
+
+#define SHABAL_O1 13
+#define SHABAL_O2  9
+#define SHABAL_O3  6
+
+
+static inline
+uint32_t shabal_u(uint32_t a){
+       return (a<<1)+a; /* a*3 */
+}
+
+static inline
+uint32_t shabal_v(uint32_t a){
+       return (a<<2)+a; /* a*5 */
+}
+
+#define ROTL32(a,n) (((a)<<(n))|((a)>>(32-(n))))
+
+static
+void shabal_p(shabal_ctx_t* ctx, const void* m){
+       uint8_t i,j;
+       for(i=0;i<16;++i){
+               ctx->b[i] = ROTL32(ctx->b[i],17);
+       }
+       for(j=0;j<SHABAL_P;j++){
+               for(i=0;i<16;++i){
+                       ctx->a[(i+j*16)%SHABAL_R] = 
+                               shabal_u(ctx->a[(i+j*16)%SHABAL_R] 
+                                       ^ shabal_v(ROTL32(ctx->a[(i+j*16+SHABAL_R-1)%SHABAL_R],15))
+                                   ^ ctx->c[(8-i+16)%16])
+                               ^ ctx->b[(i+SHABAL_O1)%16]
+                               ^ ((ctx->b[(i+SHABAL_O2)%16]) & ~(ctx->b[(i+SHABAL_O3)%16]))
+                               ^ ((uint32_t*)m)[i];
+                       ctx->b[i] = ROTL32(ctx->b[i], 1) ^ ~(ctx->a[(i+j*16)%SHABAL_R]);
+               }
+       }
+       
+       for(j=0;j<36;++j){
+               ctx->a[j%SHABAL_R] += ctx->c[(j+3)%16];
+       }
+}
+
+void shabal_nextBlock(shabal_ctx_t* ctx, const void* block){
+       uint8_t i;
+       uint32_t* t;
+       for(i=0;i<16;++i){
+               ctx->b[i] += ((uint32_t*)block)[i];
+       }
+       ctx->a[0] ^= ctx->w.w32[0];
+       ctx->a[1] ^= ctx->w.w32[1];
+       shabal_p(ctx, block);
+       for(i=0;i<16;++i){
+               ctx->c[i] -= ((uint32_t*)block)[i];
+       }
+       ctx->w.w64++;
+       t = ctx->c;
+       ctx->c = ctx->b;
+       ctx->b = t;
+}
+
+void shabal_lastBlock(shabal_ctx_t* ctx, const void* block, uint16_t length_b){
+       uint8_t i,j;
+       uint32_t* t;
+       uint8_t buffer[64];
+       while(length_b>=SHABAL_BLOCKSIZE){
+               shabal_nextBlock(ctx, block);
+               block = (uint8_t*)block + SHABAL_BLOCKSIZE_B;
+               length_b -= SHABAL_BLOCKSIZE;
+       }
+       memset(buffer, 0, 64);
+       memcpy(buffer, block, (length_b+7)/8);
+       buffer[length_b/8] |= 0x80>>(length_b%8);
+       
+       for(i=0;i<16;++i){
+               ctx->b[i] += ((uint32_t*)buffer)[i];
+       }
+
+       for(j=0; j<4;++j){
+               ctx->a[0] ^= ctx->w.w32[0];
+               ctx->a[1] ^= ctx->w.w32[1];
+               shabal_p(ctx, buffer);
+               t = ctx->c;
+               ctx->c = ctx->b;
+               ctx->b = t;
+       }
+        
+}
+
+void shabal_ctx2hash(void* dest, const shabal_ctx_t* ctx, uint16_t outlength_b){
+       memcpy(dest, &(ctx->c[16-outlength_b/32]), outlength_b/8);
+}
diff --git a/shabal/shabal.h b/shabal/shabal.h
new file mode 100644 (file)
index 0000000..fab23a1
--- /dev/null
@@ -0,0 +1,75 @@
+/* shabal.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    shabal.h
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-04-17
+ * \license GPLv3 or later
+ * 
+ */
+
+#ifndef SHABAL_H_
+#define SHABAL_H_
+
+#include <stdint.h>
+
+#define SHABAL_BLOCKSIZE 512
+#define SHABAL_BLOCKSIZE_B ((SHABAL_BLOCKSIZE+7)/8)
+
+#define SHABAL_R 12
+#define SHABAL_P  3
+
+typedef struct{
+       union{
+               uint64_t w64;
+               uint32_t w32[2];
+       } w; /* the counter */
+       uint32_t *b;
+       uint32_t *c;
+       uint32_t a[SHABAL_R];
+       uint32_t b_buffer[16];
+       uint32_t c_buffer[16];
+}shabal_ctx_t;
+
+
+void shabal192_init(shabal_ctx_t* ctx);
+void shabal224_init(shabal_ctx_t* ctx);
+void shabal256_init(shabal_ctx_t* ctx);
+void shabal384_init(shabal_ctx_t* ctx);
+void shabal512_init(shabal_ctx_t* ctx);
+
+void shabal_nextBlock(shabal_ctx_t* ctx, const void* block);
+void shabal_lastBlock(shabal_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void shabal192_ctx2hash(void* dest, const shabal_ctx_t* ctx);
+void shabal224_ctx2hash(void* dest, const shabal_ctx_t* ctx);
+void shabal256_ctx2hash(void* dest, const shabal_ctx_t* ctx);
+void shabal384_ctx2hash(void* dest, const shabal_ctx_t* ctx);
+void shabal512_ctx2hash(void* dest, const shabal_ctx_t* ctx);
+
+void shabal192(void* dest, void* msg, uint32_t length_b);
+void shabal224(void* dest, void* msg, uint32_t length_b);
+void shabal256(void* dest, void* msg, uint32_t length_b);
+void shabal384(void* dest, void* msg, uint32_t length_b);
+void shabal512(void* dest, void* msg, uint32_t length_b);
+
+void shabal_ctx2hash(void* dest, const shabal_ctx_t* ctx, uint16_t outlength_b);
+
+#endif /* SHABAL_H_ */
diff --git a/shabal/shabal192.c b/shabal/shabal192.c
new file mode 100644 (file)
index 0000000..3eda567
--- /dev/null
@@ -0,0 +1,79 @@
+/* shabal192.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    shabal192.c
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-04-27
+ * \license GPLv3 or later
+ * 
+ */
+
+#include <stdint.h>
+#include "shabal.h"
+#include <string.h>
+
+const uint32_t shabal192_iv[] = {
+       /* A */
+       0xFD749ED4, 0xB798E530, 0x33904B6F, 0x46BDA85E,
+       0x076934B4, 0x454B4058, 0x77F74527, 0xFB4CF465,
+    0x62931DA9, 0xE778C8DB, 0x22B3998E, 0xAC15CFB9,
+       /* B */
+       0x58BCBAC4, 0xEC47A08E, 0xAEE933B2, 0xDFCBC824,
+       0xA7944804, 0xBF65BDB0, 0x5A9D4502, 0x59979AF7,
+    0xC5CEA54E, 0x4B6B8150, 0x16E71909, 0x7D632319,
+       0x930573A0, 0xF34C63D1, 0xCAF914B4, 0xFDD6612C,
+       /* C */
+       0x61550878, 0x89EF2B75, 0xA1660C46, 0x7EF3855B,
+       0x7297B58C, 0x1BC67793, 0x7FB1C723, 0xB66FC640,
+    0x1A48B71C, 0xF0976D17, 0x088CE80A, 0xA454EDF3,
+       0x1C096BF4, 0xAC76224B, 0x5215781C, 0xCD5D2669
+};
+
+void shabal192_init(shabal_ctx_t* ctx){
+       uint8_t i;
+       ctx->b = ctx->b_buffer;
+       ctx->c = ctx->c_buffer;
+       ctx->w.w64 = 1LL;
+       for(i=0;i<SHABAL_R;++i){
+               ctx->a[i] = shabal192_iv[i];
+       }
+       for(i=0;i<16;++i){
+               ctx->b[i] = shabal192_iv[SHABAL_R+i];
+       }
+       for(i=0;i<16;++i){
+               ctx->c[i] = shabal192_iv[SHABAL_R+16+i];
+       }
+}
+
+void shabal192_ctx2hash(void* dest, const shabal_ctx_t* ctx){
+       shabal_ctx2hash(dest, ctx, 192);
+}
+
+void shabal192(void* dest, void* msg, uint32_t length_b){
+       shabal_ctx_t ctx;
+       shabal192_init(&ctx);
+       while(length_b>=SHABAL_BLOCKSIZE){
+               shabal_nextBlock(&ctx, msg);
+               msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
+               length_b -= SHABAL_BLOCKSIZE;
+       }
+       shabal_lastBlock(&ctx, msg, length_b);
+       shabal192_ctx2hash(dest, &ctx);
+}
diff --git a/shabal/shabal224.c b/shabal/shabal224.c
new file mode 100644 (file)
index 0000000..535e244
--- /dev/null
@@ -0,0 +1,79 @@
+/* shabal224.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    shabal224.c
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-04-27
+ * \license GPLv3 or later
+ * 
+ */
+
+#include <stdint.h>
+#include "shabal.h"
+#include <string.h>
+
+const uint32_t shabal224_iv[] = {
+       /* A */
+       0xA5201467, 0xA9B8D94A, 0xD4CED997, 0x68379D7B, 
+       0xA7FC73BA, 0xF1A2546B, 0x606782BF, 0xE0BCFD0F,
+       0x2F25374E, 0x069A149F, 0x5E2DFF25, 0xFAECF061,
+       /* B */ 
+       0xEC9905D8, 0xF21850CF, 0xC0A746C8, 0x21DAD498,
+       0x35156EEB, 0x088C97F2, 0x26303E40, 0x8A2D4FB5,
+    0xFEEE44B6, 0x8A1E9573, 0x7B81111A, 0xCBC139F0, 
+       0xA3513861, 0x1D2C362E, 0x918C580E, 0xB58E1B9C,
+       /* C */
+       0xE4B573A1, 0x4C1A0880, 0x1E907C51, 0x04807EFD, 
+       0x3AD8CDE5, 0x16B21302, 0x02512C53, 0x2204CB18,
+    0x99405F2D, 0xE5B648A1, 0x70AB1D43, 0xA10C25C2, 
+       0x16F1AC05, 0x38BBEB56, 0x9B01DC60, 0xB1096D83
+};
+
+void shabal224_init(shabal_ctx_t* ctx){
+       uint8_t i;
+       ctx->b = ctx->b_buffer;
+       ctx->c = ctx->c_buffer;
+       ctx->w.w64 = 1LL;
+       for(i=0;i<SHABAL_R;++i){
+               ctx->a[i] = shabal224_iv[i];
+       }
+       for(i=0;i<16;++i){
+               ctx->b[i] = shabal224_iv[SHABAL_R+i];
+       }
+       for(i=0;i<16;++i){
+               ctx->c[i] = shabal224_iv[SHABAL_R+16+i];
+       }
+}
+
+void shabal224_ctx2hash(void* dest, const shabal_ctx_t* ctx){
+       shabal_ctx2hash(dest, ctx, 224);
+}
+
+void shabal224(void* dest, void* msg, uint32_t length_b){
+       shabal_ctx_t ctx;
+       shabal224_init(&ctx);
+       while(length_b>=SHABAL_BLOCKSIZE){
+               shabal_nextBlock(&ctx, msg);
+               msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
+               length_b -= SHABAL_BLOCKSIZE;
+       }
+       shabal_lastBlock(&ctx, msg, length_b);
+       shabal224_ctx2hash(dest, &ctx);
+}
diff --git a/shabal/shabal256.c b/shabal/shabal256.c
new file mode 100644 (file)
index 0000000..48c796a
--- /dev/null
@@ -0,0 +1,79 @@
+/* shabal256.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    shabal256.c
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-04-27
+ * \license GPLv3 or later
+ * 
+ */
+
+#include <stdint.h>
+#include "shabal.h"
+#include <string.h>
+
+const uint32_t shabal256_iv[] = {
+       /* A */ 
+       0x52F84552, 0xE54B7999, 0x2D8EE3EC, 0xB9645191, 
+       0xE0078B86, 0xBB7C44C9, 0xD2B5C1CA, 0xB0D2EB8C,
+       0x14CE5A45, 0x22AF50DC, 0xEFFDBC6B, 0xEB21B74A,
+       /* B */ 
+       0xB555C6EE, 0x3E710596, 0xA72A652F, 0x9301515F, 
+       0xDA28C1FA, 0x696FD868, 0x9CB6BF72, 0x0AFE4002,
+    0xA6E03615, 0x5138C1D4, 0xBE216306, 0xB38B8890, 
+       0x3EA8B96B, 0x3299ACE4, 0x30924DD4, 0x55CB34A5,
+       /* C */ 
+       0xB405F031, 0xC4233EBA, 0xB3733979, 0xC0DD9D55,
+       0xC51C28AE, 0xA327B8E1, 0x56C56167, 0xED614433,
+       0x88B59D60, 0x60E2CEBA, 0x758B4B8B, 0x83E82A7F, 
+       0xBC968828, 0xE6E00BF7, 0xBA839E55, 0x9B491C60
+};
+
+void shabal256_init(shabal_ctx_t* ctx){
+       uint8_t i;
+       ctx->b = ctx->b_buffer;
+       ctx->c = ctx->c_buffer;
+       ctx->w.w64 = 1LL;
+       for(i=0;i<SHABAL_R;++i){
+               ctx->a[i] = shabal256_iv[i];
+       }
+       for(i=0;i<16;++i){
+               ctx->b[i] = shabal256_iv[SHABAL_R+i];
+       }
+       for(i=0;i<16;++i){
+               ctx->c[i] = shabal256_iv[SHABAL_R+16+i];
+       }
+}
+
+void shabal256_ctx2hash(void* dest, const shabal_ctx_t* ctx){
+       shabal_ctx2hash(dest, ctx, 256);
+}
+
+void shabal256(void* dest, void* msg, uint32_t length_b){
+       shabal_ctx_t ctx;
+       shabal256_init(&ctx);
+       while(length_b>=SHABAL_BLOCKSIZE){
+               shabal_nextBlock(&ctx, msg);
+               msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
+               length_b -= SHABAL_BLOCKSIZE;
+       }
+       shabal_lastBlock(&ctx, msg, length_b);
+       shabal256_ctx2hash(dest, &ctx);
+}
diff --git a/shabal/shabal384.c b/shabal/shabal384.c
new file mode 100644 (file)
index 0000000..223858b
--- /dev/null
@@ -0,0 +1,79 @@
+/* shabal384.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    shabal384.c
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-04-27
+ * \license GPLv3 or later
+ * 
+ */
+
+#include <stdint.h>
+#include "shabal.h"
+#include <string.h>
+
+const uint32_t shabal384_iv[] = {
+       /* A */ 
+       0xC8FCA331, 0xE55C504E, 0x003EBF26, 0xBB6B8D83, 
+       0x7B0448C1, 0x41B82789, 0x0A7C9601, 0x8D659CFF,
+       0xB6E2673E, 0xCA54C77B, 0x1460FD7E, 0x3FCB8F2D,
+       /* B */ 
+       0x527291FC, 0x2A16455F, 0x78E627E5, 0x944F169F, 
+       0x1CA6F016, 0xA854EA25, 0x8DB98ABE, 0xF2C62641,
+    0x30117DCB, 0xCF5C4309, 0x93711A25, 0xF9F671B8, 
+       0xB01D2116, 0x333F4B89, 0xB285D165, 0x86829B36,
+       /* C */ 
+       0xF764B11A, 0x76172146, 0xCEF6934D, 0xC6D28399, 
+       0xFE095F61, 0x5E6018B4, 0x5048ECF5, 0x51353261,
+    0x6E6E36DC, 0x63130DAD, 0xA9C69BD6, 0x1E90EA0C, 
+       0x7C35073B, 0x28D95E6D, 0xAA340E0D, 0xCB3DEE70
+};
+
+void shabal384_init(shabal_ctx_t* ctx){
+       uint8_t i;
+       ctx->b = ctx->b_buffer;
+       ctx->c = ctx->c_buffer;
+       ctx->w.w64 = 1LL;
+       for(i=0;i<SHABAL_R;++i){
+               ctx->a[i] = shabal384_iv[i];
+       }
+       for(i=0;i<16;++i){
+               ctx->b[i] = shabal384_iv[SHABAL_R+i];
+       }
+       for(i=0;i<16;++i){
+               ctx->c[i] = shabal384_iv[SHABAL_R+16+i];
+       }
+}
+
+void shabal384_ctx2hash(void* dest, const shabal_ctx_t* ctx){
+       shabal_ctx2hash(dest, ctx, 384);
+}
+
+void shabal384(void* dest, void* msg, uint32_t length_b){
+       shabal_ctx_t ctx;
+       shabal384_init(&ctx);
+       while(length_b>=SHABAL_BLOCKSIZE){
+               shabal_nextBlock(&ctx, msg);
+               msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
+               length_b -= SHABAL_BLOCKSIZE;
+       }
+       shabal_lastBlock(&ctx, msg, length_b);
+       shabal384_ctx2hash(dest, &ctx);
+}
diff --git a/shabal/shabal512.c b/shabal/shabal512.c
new file mode 100644 (file)
index 0000000..df56871
--- /dev/null
@@ -0,0 +1,79 @@
+/* shabal512.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    shabal512.c
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-04-27
+ * \license GPLv3 or later
+ * 
+ */
+
+#include <stdint.h>
+#include "shabal.h"
+#include <string.h>
+
+const uint32_t shabal512_iv[] = {
+       /* A */ 
+       0x20728DFD, 0x46C0BD53, 0xE782B699, 0x55304632, 
+       0x71B4EF90, 0x0EA9E82C, 0xDBB930F1, 0xFAD06B8B,
+       0xBE0CAE40, 0x8BD14410, 0x76D2ADAC, 0x28ACAB7F,
+       /* B */ 
+       0xC1099CB7, 0x07B385F3, 0xE7442C26, 0xCC8AD640, 
+       0xEB6F56C7, 0x1EA81AA9, 0x73B9D314, 0x1DE85D08,
+       0x48910A5A, 0x893B22DB, 0xC5A0DF44, 0xBBC4324E, 
+       0x72D2F240, 0x75941D99, 0x6D8BDE82, 0xA1A7502B,
+       /* C */
+       0xD9BF68D1, 0x58BAD750, 0x56028CB2, 0x8134F359, 
+       0xB5D469D8, 0x941A8CC2, 0x418B2A6E, 0x04052780,
+       0x7F07D787, 0x5194358F, 0x3C60D665, 0xBE97D79A, 
+       0x950C3434, 0xAED9A06D, 0x2537DC8D, 0x7CDB5969,
+};
+
+void shabal512_init(shabal_ctx_t* ctx){
+       uint8_t i;
+       ctx->b = ctx->b_buffer;
+       ctx->c = ctx->c_buffer;
+       ctx->w.w64 = 1LL;
+       for(i=0;i<SHABAL_R;++i){
+               ctx->a[i] = shabal512_iv[i];
+       }
+       for(i=0;i<16;++i){
+               ctx->b[i] = shabal512_iv[SHABAL_R+i];
+       }
+       for(i=0;i<16;++i){
+               ctx->c[i] = shabal512_iv[SHABAL_R+16+i];
+       }
+}
+
+void shabal512_ctx2hash(void* dest, const shabal_ctx_t* ctx){
+       shabal_ctx2hash(dest, ctx, 512);
+}
+
+void shabal512(void* dest, void* msg, uint32_t length_b){
+       shabal_ctx_t ctx;
+       shabal512_init(&ctx);
+       while(length_b>=SHABAL_BLOCKSIZE){
+               shabal_nextBlock(&ctx, msg);
+               msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
+               length_b -= SHABAL_BLOCKSIZE;
+       }
+       shabal_lastBlock(&ctx, msg, length_b);
+       shabal512_ctx2hash(dest, &ctx);
+}
diff --git a/shabal/shabal_shorttest.log.ps b/shabal/shabal_shorttest.log.ps
new file mode 100644 (file)
index 0000000..ecb1048
--- /dev/null
@@ -0,0 +1,713 @@
+%!PS-Adobe-3.0
+%%BoundingBox: 24 24 571 818
+%%Title: Enscript Output
+%%For: 
+%%Creator: GNU enscript 1.6.4
+%%CreationDate: Mon Apr 27 00:59:17 2009
+%%Orientation: Portrait
+%%Pages: (atend)
+%%DocumentMedia: A4 595 842 0 () ()
+%%DocumentNeededResources: (atend)
+%%EndComments
+%%BeginProlog
+%%BeginResource: procset Enscript-Prolog 1.6 4
+%
+% Procedures.
+%
+
+/_S {  % save current state
+  /_s save def
+} def
+/_R {  % restore from saved state
+  _s restore
+} def
+
+/S {   % showpage protecting gstate
+  gsave
+  showpage
+  grestore
+} bind def
+
+/MF {  % fontname newfontname -> -     make a new encoded font
+  /newfontname exch def
+  /fontname exch def
+
+  /fontdict fontname findfont def
+  /newfont fontdict maxlength dict def
+
+  fontdict {
+    exch
+    dup /FID eq {
+      % skip FID pair
+      pop pop
+    } {
+      % copy to the new font dictionary
+      exch newfont 3 1 roll put
+    } ifelse
+  } forall
+
+  newfont /FontName newfontname put
+
+  % insert only valid encoding vectors
+  encoding_vector length 256 eq {
+    newfont /Encoding encoding_vector put
+  } if
+
+  newfontname newfont definefont pop
+} def
+
+/MF_PS { % fontname newfontname -> -   make a new font preserving its enc
+  /newfontname exch def
+  /fontname exch def
+
+  /fontdict fontname findfont def
+  /newfont fontdict maxlength dict def
+
+  fontdict {
+    exch
+    dup /FID eq {
+      % skip FID pair
+      pop pop
+    } {
+      % copy to the new font dictionary
+      exch newfont 3 1 roll put
+    } ifelse
+  } forall
+
+  newfont /FontName newfontname put
+
+  newfontname newfont definefont pop
+} def
+
+/SF { % fontname width height -> -     set a new font
+  /height exch def
+  /width exch def
+
+  findfont
+  [width 0 0 height 0 0] makefont setfont
+} def
+
+/SUF { % fontname width height -> -    set a new user font
+  /height exch def
+  /width exch def
+
+  /F-gs-user-font MF
+  /F-gs-user-font width height SF
+} def
+
+/SUF_PS { % fontname width height -> - set a new user font preserving its enc
+  /height exch def
+  /width exch def
+
+  /F-gs-user-font MF_PS
+  /F-gs-user-font width height SF
+} def
+
+/M {moveto} bind def
+/s {show} bind def
+
+/Box { % x y w h -> -                  define box path
+  /d_h exch def /d_w exch def /d_y exch def /d_x exch def
+  d_x d_y  moveto
+  d_w 0 rlineto
+  0 d_h rlineto
+  d_w neg 0 rlineto
+  closepath
+} def
+
+/bgs { % x y height blskip gray str -> -       show string with bg color
+  /str exch def
+  /gray exch def
+  /blskip exch def
+  /height exch def
+  /y exch def
+  /x exch def
+
+  gsave
+    x y blskip sub str stringwidth pop height Box
+    gray setgray
+    fill
+  grestore
+  x y M str s
+} def
+
+/bgcs { % x y height blskip red green blue str -> -  show string with bg color
+  /str exch def
+  /blue exch def
+  /green exch def
+  /red exch def
+  /blskip exch def
+  /height exch def
+  /y exch def
+  /x exch def
+
+  gsave
+    x y blskip sub str stringwidth pop height Box
+    red green blue setrgbcolor
+    fill
+  grestore
+  x y M str s
+} def
+
+% Highlight bars.
+/highlight_bars {      % nlines lineheight output_y_margin gray -> -
+  gsave
+    setgray
+    /ymarg exch def
+    /lineheight exch def
+    /nlines exch def
+
+    % This 2 is just a magic number to sync highlight lines to text.
+    0 d_header_y ymarg sub 2 sub translate
+
+    /cw d_output_w cols div def
+    /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
+
+    % for each column
+    0 1 cols 1 sub {
+      cw mul /xp exch def
+
+      % for each rows
+      0 1 nrows 1 sub {
+        /rn exch def
+        rn lineheight mul neg /yp exch def
+        rn nlines idiv 2 mod 0 eq {
+         % Draw highlight bar.  4 is just a magic indentation.
+         xp 4 add yp cw 8 sub lineheight neg Box fill
+       } if
+      } for
+    } for
+
+  grestore
+} def
+
+% Line highlight bar.
+/line_highlight {      % x y width height gray -> -
+  gsave
+    /gray exch def
+    Box gray setgray fill
+  grestore
+} def
+
+% Column separator lines.
+/column_lines {
+  gsave
+    .1 setlinewidth
+    0 d_footer_h translate
+    /cw d_output_w cols div def
+    1 1 cols 1 sub {
+      cw mul 0 moveto
+      0 d_output_h rlineto stroke
+    } for
+  grestore
+} def
+
+% Column borders.
+/column_borders {
+  gsave
+    .1 setlinewidth
+    0 d_footer_h moveto
+    0 d_output_h rlineto
+    d_output_w 0 rlineto
+    0 d_output_h neg rlineto
+    closepath stroke
+  grestore
+} def
+
+% Do the actual underlay drawing
+/draw_underlay {
+  ul_style 0 eq {
+    ul_str true charpath stroke
+  } {
+    ul_str show
+  } ifelse
+} def
+
+% Underlay
+/underlay {    % - -> -
+  gsave
+    0 d_page_h translate
+    d_page_h neg d_page_w atan rotate
+
+    ul_gray setgray
+    ul_font setfont
+    /dw d_page_h dup mul d_page_w dup mul add sqrt def
+    ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
+    draw_underlay
+  grestore
+} def
+
+/user_underlay {       % - -> -
+  gsave
+    ul_x ul_y translate
+    ul_angle rotate
+    ul_gray setgray
+    ul_font setfont
+    0 0 ul_h_ptsize 2 div sub moveto
+    draw_underlay
+  grestore
+} def
+
+% Page prefeed
+/page_prefeed {                % bool -> -
+  statusdict /prefeed known {
+    statusdict exch /prefeed exch put
+  } {
+    pop
+  } ifelse
+} def
+
+% Wrapped line markers
+/wrapped_line_mark {   % x y charwith charheight type -> -
+  /type exch def
+  /h exch def
+  /w exch def
+  /y exch def
+  /x exch def
+
+  type 2 eq {
+    % Black boxes (like TeX does)
+    gsave
+      0 setlinewidth
+      x w 4 div add y M
+      0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
+      closepath fill
+    grestore
+  } {
+    type 3 eq {
+      % Small arrows
+      gsave
+        .2 setlinewidth
+        x w 2 div add y h 2 div add M
+        w 4 div 0 rlineto
+        x w 4 div add y lineto stroke
+
+        x w 4 div add w 8 div add y h 4 div add M
+        x w 4 div add y lineto
+       w 4 div h 8 div rlineto stroke
+      grestore
+    } {
+      % do nothing
+    } ifelse
+  } ifelse
+} def
+
+% EPSF import.
+
+/BeginEPSF {
+  /b4_Inc_state save def               % Save state for cleanup
+  /dict_count countdictstack def       % Count objects on dict stack
+  /op_count count 1 sub def            % Count objects on operand stack
+  userdict begin
+  /showpage { } def
+  0 setgray 0 setlinecap
+  1 setlinewidth 0 setlinejoin
+  10 setmiterlimit [ ] 0 setdash newpath
+  /languagelevel where {
+    pop languagelevel
+    1 ne {
+      false setstrokeadjust false setoverprint
+    } if
+  } if
+} bind def
+
+/EndEPSF {
+  count op_count sub { pos } repeat    % Clean up stacks
+  countdictstack dict_count sub { end } repeat
+  b4_Inc_state restore
+} bind def
+
+% Check PostScript language level.
+/languagelevel where {
+  pop /gs_languagelevel languagelevel def
+} {
+  /gs_languagelevel 1 def
+} ifelse
+%%EndResource
+%%BeginResource: procset Enscript-Encoding-88591 1.6 4
+/encoding_vector [
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/space         /exclam         /quotedbl       /numbersign     
+/dollar        /percent        /ampersand      /quoteright     
+/parenleft     /parenright     /asterisk       /plus           
+/comma         /hyphen         /period         /slash          
+/zero          /one            /two            /three          
+/four          /five           /six            /seven          
+/eight         /nine           /colon          /semicolon      
+/less          /equal          /greater        /question       
+/at            /A              /B              /C              
+/D             /E              /F              /G              
+/H             /I              /J              /K              
+/L             /M              /N              /O              
+/P             /Q              /R              /S              
+/T             /U              /V              /W              
+/X             /Y              /Z              /bracketleft    
+/backslash     /bracketright   /asciicircum    /underscore     
+/quoteleft     /a              /b              /c              
+/d             /e              /f              /g              
+/h             /i              /j              /k              
+/l             /m              /n              /o              
+/p             /q              /r              /s              
+/t             /u              /v              /w              
+/x             /y              /z              /braceleft      
+/bar           /braceright     /tilde          /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/.notdef       /.notdef        /.notdef        /.notdef        
+/space         /exclamdown     /cent           /sterling       
+/currency      /yen            /brokenbar      /section        
+/dieresis      /copyright      /ordfeminine    /guillemotleft  
+/logicalnot    /hyphen         /registered     /macron         
+/degree        /plusminus      /twosuperior    /threesuperior  
+/acute         /mu             /paragraph      /bullet         
+/cedilla       /onesuperior    /ordmasculine   /guillemotright 
+/onequarter    /onehalf        /threequarters  /questiondown   
+/Agrave        /Aacute         /Acircumflex    /Atilde         
+/Adieresis     /Aring          /AE             /Ccedilla       
+/Egrave        /Eacute         /Ecircumflex    /Edieresis      
+/Igrave        /Iacute         /Icircumflex    /Idieresis      
+/Eth           /Ntilde         /Ograve         /Oacute         
+/Ocircumflex   /Otilde         /Odieresis      /multiply       
+/Oslash        /Ugrave         /Uacute         /Ucircumflex    
+/Udieresis     /Yacute         /Thorn          /germandbls     
+/agrave        /aacute         /acircumflex    /atilde         
+/adieresis     /aring          /ae             /ccedilla       
+/egrave        /eacute         /ecircumflex    /edieresis      
+/igrave        /iacute         /icircumflex    /idieresis      
+/eth           /ntilde         /ograve         /oacute         
+/ocircumflex   /otilde         /odieresis      /divide         
+/oslash        /ugrave         /uacute         /ucircumflex    
+/udieresis     /yacute         /thorn          /ydieresis      
+] def
+%%EndResource
+%%EndProlog
+%%BeginSetup
+%%IncludeResource: font Courier-Bold
+%%IncludeResource: font Courier
+/HFpt_w 10 def
+/HFpt_h 10 def
+/Courier-Bold /HF-gs-font MF
+/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
+/Courier /F-gs-font MF
+/F-gs-font 10 10 SF
+/#copies 1 def
+% Pagedevice definitions:
+gs_languagelevel 1 gt {
+  <<
+    /PageSize [595 842] 
+  >> setpagedevice
+} if
+%%BeginResource: procset Enscript-Header-simple 1.6 4
+
+/do_header {   % print default simple header
+  gsave
+    d_header_x d_header_y HFpt_h 3 div add translate
+
+    HF setfont
+    user_header_p {
+      5 0 moveto user_header_left_str show
+
+      d_header_w user_header_center_str stringwidth pop sub 2 div
+      0 moveto user_header_center_str show
+
+      d_header_w user_header_right_str stringwidth pop sub 5 sub
+      0 moveto user_header_right_str show
+    } {
+      5 0 moveto fname show
+      45 0 rmoveto fmodstr show
+      45 0 rmoveto pagenumstr show
+    } ifelse
+
+  grestore
+} def
+%%EndResource
+/d_page_w 547 def
+/d_page_h 794 def
+/d_header_x 0 def
+/d_header_y 779 def
+/d_header_w 547 def
+/d_header_h 15 def
+/d_footer_x 0 def
+/d_footer_y 0 def
+/d_footer_w 547 def
+/d_footer_h 0 def
+/d_output_w 547 def
+/d_output_h 779 def
+/cols 1 def
+%%EndSetup
+%%Page: (1) 1
+%%BeginPageSetup
+_S
+24 24 translate
+/pagenum 1 def
+/fname (shabal_shorttest.log) def
+/fdir () def
+/ftail (shabal_shorttest.log) def
+% User defined strings:
+/fmodstr (Mon Apr 27 00:58:21 2009) def
+/pagenumstr (1) def
+/user_header_p false def
+/user_footer_p false def
+%%EndPageSetup
+do_header
+5 766 M
+(test) s
+5 744 M
+(Test vectors for Shabal \(192 bits\):) s
+5 733 M
+(message:) s
+5 722 M
+(    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 711 M
+(    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 700 M
+(    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 689 M
+(    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 678 M
+(hash:) s
+5 667 M
+(    0F 70 6E CB 97 CF 4D CE 00 BF BB D2 FB 64 53 0C ) s
+5 656 M
+(    32 87 0C B4 48 39 73 0D ) s
+5 634 M
+(Test vectors for Shabal \(192 bits\):) s
+5 623 M
+(message:) s
+5 612 M
+(    61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 ) s
+5 601 M
+(    71 72 73 74 75 76 77 78 79 7A 2D 30 31 32 33 34 ) s
+5 590 M
+(    35 36 37 38 39 2D 41 42 43 44 45 46 47 48 49 4A ) s
+5 579 M
+(    4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A ) s
+5 568 M
+(    2D 30 31 32 33 34 35 36 37 38 39 2D 61 62 63 64 ) s
+5 557 M
+(    65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 ) s
+5 546 M
+(    75 76 77 78 79 7A ) s
+5 535 M
+(hash:) s
+5 524 M
+(    69 0F AE 79 22 6D 95 76 0A E8 FD B4 F5 8C 05 37 ) s
+5 513 M
+(    11 17 56 55 7D 30 7B 15 ) s
+5 491 M
+(Test vectors for Shabal \(224 bits\):) s
+5 480 M
+(message:) s
+5 469 M
+(    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 458 M
+(    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 447 M
+(    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 436 M
+(    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 425 M
+(hash:) s
+5 414 M
+(    99 DD A6 14 F9 07 D2 E8 81 76 18 F7 30 69 6F 32 ) s
+5 403 M
+(    00 AE CA 8B 5F 85 F4 25 43 BA 20 31 ) s
+5 381 M
+(Test vectors for Shabal \(224 bits\):) s
+5 370 M
+(message:) s
+5 359 M
+(    61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 ) s
+5 348 M
+(    71 72 73 74 75 76 77 78 79 7A 2D 30 31 32 33 34 ) s
+5 337 M
+(    35 36 37 38 39 2D 41 42 43 44 45 46 47 48 49 4A ) s
+5 326 M
+(    4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A ) s
+5 315 M
+(    2D 30 31 32 33 34 35 36 37 38 39 2D 61 62 63 64 ) s
+5 304 M
+(    65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 ) s
+5 293 M
+(    75 76 77 78 79 7A ) s
+5 282 M
+(hash:) s
+5 271 M
+(    C7 D6 2D 8D 2A 34 74 B4 F4 A9 D1 1A 52 DB 3D 43 ) s
+5 260 M
+(    5B F1 58 CF 45 4C 5D 56 1D 71 25 F5 ) s
+5 238 M
+(Test vectors for Shabal \(256 bits\):) s
+5 227 M
+(message:) s
+5 216 M
+(    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 205 M
+(    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 194 M
+(    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 183 M
+(    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 172 M
+(hash:) s
+5 161 M
+(    DA 8F 08 C0 2A 67 BA 9A 56 BD D0 79 8E 48 AE 07 ) s
+5 150 M
+(    14 21 5E 09 3B 5B 85 06 49 A3 77 18 99 3F 54 A2 ) s
+5 128 M
+(Test vectors for Shabal \(256 bits\):) s
+5 117 M
+(message:) s
+5 106 M
+(    61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 ) s
+5 95 M
+(    71 72 73 74 75 76 77 78 79 7A 2D 30 31 32 33 34 ) s
+5 84 M
+(    35 36 37 38 39 2D 41 42 43 44 45 46 47 48 49 4A ) s
+5 73 M
+(    4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A ) s
+5 62 M
+(    2D 30 31 32 33 34 35 36 37 38 39 2D 61 62 63 64 ) s
+5 51 M
+(    65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 ) s
+5 40 M
+(    75 76 77 78 79 7A ) s
+5 29 M
+(hash:) s
+5 18 M
+(    B4 9F 34 BF 51 86 4C 30 53 3C C4 6C C2 54 2B DE ) s
+5 7 M
+(    C2 F9 6F D0 6F 5C 53 9A FF 6E AD 58 83 F7 32 7A ) s
+_R
+S
+%%Page: (2) 2
+%%BeginPageSetup
+_S
+24 24 translate
+/pagenum 2 def
+/fname (shabal_shorttest.log) def
+/fdir () def
+/ftail (shabal_shorttest.log) def
+% User defined strings:
+/fmodstr (Mon Apr 27 00:58:21 2009) def
+/pagenumstr (2) def
+/user_header_p false def
+/user_footer_p false def
+%%EndPageSetup
+do_header
+5 755 M
+(Test vectors for Shabal \(384 bits\):) s
+5 744 M
+(message:) s
+5 733 M
+(    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 722 M
+(    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 711 M
+(    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 700 M
+(    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 689 M
+(hash:) s
+5 678 M
+(    9D DE 12 33 91 0D 85 DA 3A 5C 78 03 12 B1 11 C6 ) s
+5 667 M
+(    FC CA 1B 5D D2 55 37 03 5E E0 8E 3B 4E 1E 25 15 ) s
+5 656 M
+(    4F 72 6A 63 84 E5 A8 F0 AF EA AB 4A C4 C0 2F 12 ) s
+5 634 M
+(Test vectors for Shabal \(384 bits\):) s
+5 623 M
+(message:) s
+5 612 M
+(    61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 ) s
+5 601 M
+(    71 72 73 74 75 76 77 78 79 7A 2D 30 31 32 33 34 ) s
+5 590 M
+(    35 36 37 38 39 2D 41 42 43 44 45 46 47 48 49 4A ) s
+5 579 M
+(    4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A ) s
+5 568 M
+(    2D 30 31 32 33 34 35 36 37 38 39 2D 61 62 63 64 ) s
+5 557 M
+(    65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 ) s
+5 546 M
+(    75 76 77 78 79 7A ) s
+5 535 M
+(hash:) s
+5 524 M
+(    30 01 2C 0E 3E DC 46 0B D7 86 27 C2 C3 09 44 D2 ) s
+5 513 M
+(    A1 89 66 9A FA 2D 7A 97 13 EF 2F 77 4C 44 74 A4 ) s
+5 502 M
+(    3A F1 CB CE C5 FA B4 24 8C 08 73 F0 38 FB EB A0 ) s
+5 480 M
+(Test vectors for Shabal \(512 bits\):) s
+5 469 M
+(message:) s
+5 458 M
+(    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 447 M
+(    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 436 M
+(    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 425 M
+(    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 414 M
+(hash:) s
+5 403 M
+(    15 80 16 C6 C8 1F 3F 0A 52 D9 8D 68 ED 2F 9E 8E ) s
+5 392 M
+(    78 95 EF 23 CB A7 E2 BC 61 09 D8 A5 32 E6 C9 E6 ) s
+5 381 M
+(    A6 A5 01 97 9F B8 37 F0 4E C4 C6 20 E7 31 79 DC ) s
+5 370 M
+(    82 AB B5 2B 32 CD AD B3 56 50 E2 9C 98 5E 30 22 ) s
+5 348 M
+(Test vectors for Shabal \(512 bits\):) s
+5 337 M
+(message:) s
+5 326 M
+(    61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 ) s
+5 315 M
+(    71 72 73 74 75 76 77 78 79 7A 2D 30 31 32 33 34 ) s
+5 304 M
+(    35 36 37 38 39 2D 41 42 43 44 45 46 47 48 49 4A ) s
+5 293 M
+(    4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A ) s
+5 282 M
+(    2D 30 31 32 33 34 35 36 37 38 39 2D 61 62 63 64 ) s
+5 271 M
+(    65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 ) s
+5 260 M
+(    75 76 77 78 79 7A ) s
+5 249 M
+(hash:) s
+5 238 M
+(    67 7E 6F 7F 12 D7 0A F0 B3 35 66 2F 59 B5 68 51 ) s
+5 227 M
+(    F3 65 3E 66 64 7D 33 86 DF DA 01 43 25 4C C8 A5 ) s
+5 216 M
+(    DB 3E 21 94 06 8C 6F 71 59 7D 7B 60 98 4D 22 B4 ) s
+5 205 M
+(    7A 1F 60 D9 1C A8 DF CB 17 5D 65 B9 73 59 CE CF ) s
+5 194 M
+(>) s
+_R
+S
+%%Trailer
+%%Pages: 2
+%%DocumentNeededResources: font Courier-Bold Courier 
+%%EOF
diff --git a/skein/memxor.c b/skein/memxor.c
new file mode 100644 (file)
index 0000000..7485b3e
--- /dev/null
@@ -0,0 +1,12 @@
+#include <stdint.h>
+
+#include "memxor.h"
+
+void memxor(void* dest, const void* src, uint16_t n){
+  while(n--){
+    *((uint8_t*)dest) ^= *((uint8_t*)src);
+    dest = (uint8_t*)dest +1;
+    src  = (uint8_t*)src  +1;
+  }
+}
+
diff --git a/skein/memxor.h b/skein/memxor.h
new file mode 100644 (file)
index 0000000..a62a616
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef MEMXOR_H_
+#define MEMXOR_H_
+#include <stdint.h>
+
+void memxor(void* dest, const void* src, uint16_t n);
+
+#endif
diff --git a/skein/skein.h b/skein/skein.h
new file mode 100644 (file)
index 0000000..0fd5b51
--- /dev/null
@@ -0,0 +1,76 @@
+/* skein.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    skein.c
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-03-12
+ * \license GPLv3 or later
+ * 
+ */
+
+#ifndef SKEIN_H_
+#define SKEIN_H_
+
+#include <stdint.h>
+#include "ubi.h"
+
+#define SKEIN256_BLOCKSIZE    UBI256_BLOCKSIZE
+#define SKEIN256_BLOCKSIZE_B  UBI256_BLOCKSIZE_B
+
+#define SKEIN512_BLOCKSIZE    UBI512_BLOCKSIZE
+#define SKEIN512_BLOCKSIZE_B  UBI512_BLOCKSIZE_B
+
+#define SKEIN1024_BLOCKSIZE   UBI1024_BLOCKSIZE
+#define SKEIN1024_BLOCKSIZE_B UBI1024_BLOCKSIZE_B
+
+typedef struct{
+        uint16_t outsize_b;
+        ubi256_ctx_t ubictx;
+}skein256_ctx_t;
+
+void skein256_init(skein256_ctx_t* ctx, uint16_t outsize_b);
+void skein256_nextBlock(skein256_ctx_t* ctx, const void* block);
+void skein256_lastBlock(skein256_ctx_t* ctx, const void* block, uint16_t length_b);
+void skein256_ctx2hash(void* dest, skein256_ctx_t* ctx);
+void skein256(void* dest, uint16_t outlength_b, const void* msg, uint32_t length_b);
+
+typedef struct{
+        uint16_t outsize_b;
+        ubi512_ctx_t ubictx;
+}skein512_ctx_t;
+
+void skein512_init(skein512_ctx_t* ctx, uint16_t outsize_b);
+void skein512_nextBlock(skein512_ctx_t* ctx, const void* block);
+void skein512_lastBlock(skein512_ctx_t* ctx, const void* block, uint16_t length_b);
+void skein512_ctx2hash(void* dest, skein512_ctx_t* ctx);
+void skein512(void* dest, uint16_t outlength_b, const void* msg, uint32_t length_b);
+
+typedef struct{
+        uint16_t outsize_b;
+        ubi1024_ctx_t ubictx;
+}skein1024_ctx_t;
+
+void skein1024_init(skein1024_ctx_t* ctx, uint16_t outsize_b);
+void skein1024_nextBlock(skein1024_ctx_t* ctx, const void* block);
+void skein1024_lastBlock(skein1024_ctx_t* ctx, const void* block, uint16_t length_b);
+void skein1024_ctx2hash(void* dest, skein1024_ctx_t* ctx);
+void skein1024(void* dest, uint16_t outlength_b, const void* msg, uint32_t length_b);
+
+#endif /* SKEIN_H_ */
diff --git a/skein/skein1024.c b/skein/skein1024.c
new file mode 100644 (file)
index 0000000..34fc22d
--- /dev/null
@@ -0,0 +1,93 @@
+/* skein1024.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-03-12
+ * \license GPLv3 or later
+ * 
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "ubi.h"
+#include "skein.h"
+
+
+void skein1024_init(skein1024_ctx_t* ctx, uint16_t outsize_b){
+       skein_config_t conf;
+       uint8_t null[UBI1024_BLOCKSIZE_B];
+       memset(null, 0, UBI1024_BLOCKSIZE_B);
+       memset(&conf, 0, sizeof(skein_config_t));
+       conf.schema[0] = 'S';
+       conf.schema[1] = 'H';
+       conf.schema[2] = 'A';
+       conf.schema[3] = '3';
+       conf.version = 1;
+       conf.out_length = outsize_b;
+       ctx->outsize_b = outsize_b;
+       ubi1024_init(&(ctx->ubictx), null, UBI_TYPE_CFG);
+       ubi1024_lastBlock(&(ctx->ubictx), &conf, 256);
+       ubi1024_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_MSG);
+}
+
+void skein1024_nextBlock(skein1024_ctx_t* ctx, const void* block){
+       ubi1024_nextBlock(&(ctx->ubictx), block);
+}
+
+void skein1024_lastBlock(skein1024_ctx_t* ctx, const void* block, uint16_t length_b){
+       ubi1024_lastBlock(&(ctx->ubictx), block, length_b);
+}
+
+void skein1024_ctx2hash(void* dest, skein1024_ctx_t* ctx){
+       ubi1024_ctx_t uctx;
+       uint16_t outsize_b;
+       
+       uint64_t counter=0;
+       uint8_t outbuffer[UBI1024_BLOCKSIZE_B];
+       ubi1024_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_OUT);
+       
+       outsize_b = ctx->outsize_b;
+       while(1){
+               memcpy(&uctx, &(ctx->ubictx), sizeof(ubi1024_ctx_t));
+               ubi1024_lastBlock(&uctx, &counter, 64);
+               ubi1024_ctx2hash(outbuffer, &uctx);
+               if(outsize_b<=UBI1024_BLOCKSIZE){
+                       memcpy(dest, outbuffer, (ctx->outsize_b+7)/8);
+                       break;
+               }else{
+                       memcpy(dest, outbuffer, UBI1024_BLOCKSIZE_B);
+                       dest = (uint8_t*)dest + UBI1024_BLOCKSIZE_B;
+                       outsize_b -= UBI1024_BLOCKSIZE;
+                       counter++;
+               }
+       }
+}
+
+void skein1024(void* dest, uint16_t outlength_b, const void* msg, uint32_t length_b){
+       skein1024_ctx_t ctx;
+       skein1024_init(&ctx, outlength_b);
+       while(length_b>SKEIN1024_BLOCKSIZE){
+               skein1024_nextBlock(&ctx, msg);
+               msg = (uint8_t*)msg + SKEIN1024_BLOCKSIZE_B;
+               length_b -= SKEIN1024_BLOCKSIZE;
+       }
+       skein1024_lastBlock(&ctx, msg, length_b);
+       skein1024_ctx2hash(dest, &ctx);
+}
diff --git a/skein/skein256.c b/skein/skein256.c
new file mode 100644 (file)
index 0000000..91c0eff
--- /dev/null
@@ -0,0 +1,94 @@
+/* skein256.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-03-12
+ * \license GPLv3 or later
+ * 
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "ubi.h"
+#include "skein.h"
+
+#include "cli.h"
+
+void skein256_init(skein256_ctx_t* ctx, uint16_t outsize_b){
+       skein_config_t conf;
+       uint8_t null[UBI256_BLOCKSIZE_B];
+       memset(null, 0, UBI256_BLOCKSIZE_B);
+       memset(&conf, 0, sizeof(skein_config_t));
+       conf.schema[0] = 'S';
+       conf.schema[1] = 'H';
+       conf.schema[2] = 'A';
+       conf.schema[3] = '3';
+       conf.version = 1;
+       conf.out_length = outsize_b;
+       ctx->outsize_b = outsize_b;
+       ubi256_init(&(ctx->ubictx), null, UBI_TYPE_CFG);
+       ubi256_lastBlock(&(ctx->ubictx), &conf, 256);
+       ubi256_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_MSG);
+}
+
+void skein256_nextBlock(skein256_ctx_t* ctx, const void* block){
+       ubi256_nextBlock(&(ctx->ubictx), block);
+}
+
+void skein256_lastBlock(skein256_ctx_t* ctx, const void* block, uint16_t length_b){
+       ubi256_lastBlock(&(ctx->ubictx), block, length_b);
+}
+
+void skein256_ctx2hash(void* dest, skein256_ctx_t* ctx){
+       ubi256_ctx_t uctx;
+       uint16_t outsize_b;
+       
+       uint64_t counter=0;
+       uint8_t outbuffer[UBI256_BLOCKSIZE_B];
+       ubi256_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_OUT);
+       
+       outsize_b = ctx->outsize_b;
+       while(1){
+               memcpy(&uctx, &(ctx->ubictx), sizeof(ubi256_ctx_t));
+               ubi256_lastBlock(&uctx, &counter, 64);
+               ubi256_ctx2hash(outbuffer, &uctx);
+               if(outsize_b<=UBI256_BLOCKSIZE){
+                       memcpy(dest, outbuffer, (outsize_b+7)/8);
+                       break;
+               }else{
+                       memcpy(dest, outbuffer, UBI256_BLOCKSIZE_B);
+                       dest = (uint8_t*)dest + UBI256_BLOCKSIZE_B;
+                       outsize_b -= UBI256_BLOCKSIZE;
+                       counter++;
+               }
+       }
+}
+
+void skein256(void* dest, uint16_t outlength_b,const void* msg, uint32_t length_b){
+       skein256_ctx_t ctx;
+       skein256_init(&ctx, outlength_b);
+       while(length_b>SKEIN256_BLOCKSIZE){
+               skein256_nextBlock(&ctx, msg);
+               msg = (uint8_t*)msg + SKEIN256_BLOCKSIZE_B;
+               length_b -= SKEIN256_BLOCKSIZE;
+       }
+       skein256_lastBlock(&ctx, msg, length_b);
+       skein256_ctx2hash(dest, &ctx);
+}
diff --git a/skein/skein512.c b/skein/skein512.c
new file mode 100644 (file)
index 0000000..5948acf
--- /dev/null
@@ -0,0 +1,94 @@
+/* skein512.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-03-12
+ * \license GPLv3 or later
+ * 
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "ubi.h"
+#include "skein.h"
+
+
+void skein512_init(skein512_ctx_t* ctx, uint16_t outsize_b){
+       skein_config_t conf;
+       uint8_t null[UBI512_BLOCKSIZE_B];
+       memset(null, 0, UBI512_BLOCKSIZE_B);
+       memset(&conf, 0, sizeof(skein_config_t));
+       conf.schema[0] = 'S';
+       conf.schema[1] = 'H';
+       conf.schema[2] = 'A';
+       conf.schema[3] = '3';
+       conf.version = 1;
+       conf.out_length = outsize_b;
+       ctx->outsize_b = outsize_b;
+       ubi512_init(&(ctx->ubictx), null, UBI_TYPE_CFG);
+       ubi512_lastBlock(&(ctx->ubictx), &conf, 256);
+       ubi512_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_MSG);
+}
+
+void skein512_nextBlock(skein512_ctx_t* ctx, const void* block){
+       ubi512_nextBlock(&(ctx->ubictx), block);
+}
+
+void skein512_lastBlock(skein512_ctx_t* ctx, const void* block, uint16_t length_b){
+       ubi512_lastBlock(&(ctx->ubictx), block, length_b);
+}
+
+void skein512_ctx2hash(void* dest, skein512_ctx_t* ctx){
+       ubi512_ctx_t uctx;
+       uint16_t outsize_b;
+       
+       uint64_t counter=0;
+       uint8_t outbuffer[UBI512_BLOCKSIZE_B];
+       ubi512_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_OUT);
+       
+       outsize_b = ctx->outsize_b;
+       while(1){
+               memcpy(&uctx, &(ctx->ubictx), sizeof(ubi512_ctx_t));
+               ubi512_lastBlock(&uctx, &counter, 64);
+               ubi512_ctx2hash(outbuffer, &uctx);
+               if(outsize_b<=UBI512_BLOCKSIZE){
+                       memcpy(dest, outbuffer, (ctx->outsize_b+7)/8);
+                       break;
+               }else{
+                       memcpy(dest, outbuffer, UBI512_BLOCKSIZE_B);
+                       dest = (uint8_t*)dest + UBI512_BLOCKSIZE_B;
+                       outsize_b -= UBI512_BLOCKSIZE;
+                       counter++;
+               }
+       }
+}
+
+void skein512(void* dest, uint16_t outlength_b,const void* msg, uint32_t length_b){
+       skein512_ctx_t ctx;
+       skein512_init(&ctx, outlength_b);
+       while(length_b>SKEIN512_BLOCKSIZE){
+               skein512_nextBlock(&ctx, msg);
+               msg = (uint8_t*)msg + SKEIN512_BLOCKSIZE_B;
+               length_b -= SKEIN512_BLOCKSIZE;
+       }
+       skein512_lastBlock(&ctx, msg, length_b);
+       skein512_ctx2hash(dest, &ctx);
+}
+
diff --git a/skein/skein_algo_list.txt b/skein/skein_algo_list.txt
new file mode 100644 (file)
index 0000000..5b25e73
--- /dev/null
@@ -0,0 +1,20 @@
+         a:     Skein-256-128
+         b:     Skein-256-160
+         c:     Skein-256-224
+        *d:     Skein-256-256
+         e:     Skein-256-384
+         f:     Skein-256-512
+         g:     Skein-512-128
+         h:     Skein-512-160
+         i:     Skein-512-224
+         j:     Skein-512-256
+         k:     Skein-512-384
+         l:     Skein-512-512
+         m:     Skein-512-1024
+         n:     Skein-1024-128
+         o:     Skein-1024-160
+         p:     Skein-1024-224
+         q:     Skein-1024-256
+         r:     Skein-1024-384
+         s:     Skein-1024-512
+         t:     Skein-1024-1024
diff --git a/skein/threefish.h b/skein/threefish.h
new file mode 100644 (file)
index 0000000..3b4cc99
--- /dev/null
@@ -0,0 +1,90 @@
+/* threefish.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \file    threefish.h
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-03-12
+ * \license GPLv3 or later
+ * \brief   Implementation of the Threefish block cipher
+ * \ingroup Threefish
+ */
+
+#ifndef THREEFISH_H_
+#define THREEFISH_H_
+
+#include <stdint.h>
+
+#define THREEFISH256_BLOCKSIZE 256
+#define THREEFISH256_BLOCKSIZE_B ((THREEFISH256_BLOCKSIZE+7)/8)
+#define THREEFISH512_BLOCKSIZE 512
+#define THREEFISH512_BLOCKSIZE_B ((THREEFISH512_BLOCKSIZE+7)/8)
+#define THREEFISH1024_BLOCKSIZE 1024
+#define THREEFISH1024_BLOCKSIZE_B ((THREEFISH1024_BLOCKSIZE+7)/8)
+
+/** \typedef threefish256_ctx_t
+ * \brief holds key data for Threefish-256
+ *  
+ * A variable of this type may hold the key data for Threefish-256 encryption
+ * or decryption..
+ */
+typedef struct{
+       uint64_t k[5];
+       uint64_t t[3];
+} threefish256_ctx_t;
+
+/** \typedef threefish512_ctx_t
+ * \brief holds key data for Threefish-512
+ *  
+ * A variable of this type may hold the key data for Threefish-512 encryption
+ * or decryption..
+ */
+typedef struct{
+       uint64_t k[9];
+       uint64_t t[3];
+} threefish512_ctx_t;
+
+/** \typedef threefish1024_ctx_t
+ * \brief holds key data for Threefish-1024
+ *  
+ * A variable of this type may hold the key data for Threefish-1024 encryption
+ * or decryption..
+ */
+typedef struct{
+       uint64_t k[17];
+       uint64_t t[3];
+} threefish1024_ctx_t;
+
+
+void threefish_mix(void* data, uint8_t rot);
+void threefish_invmix(void* data, uint8_t rot);
+
+void threefish256_init(const void* key, const void* tweak, threefish256_ctx_t* ctx);
+void threefish512_init(const void* key, const void* tweak, threefish512_ctx_t* ctx);
+void threefish1024_init(const void* key, const void* tweak, threefish1024_ctx_t* ctx);
+
+void threefish256_enc(void* data, const threefish256_ctx_t* ctx);
+void threefish512_enc(void* data, const threefish512_ctx_t* ctx);
+void threefish1024_enc(void* data, const threefish1024_ctx_t* ctx);
+
+void threefish256_dec(void* data, const threefish256_ctx_t* ctx);
+void threefish512_dec(void* data, const threefish512_ctx_t* ctx);
+void threefish1024_dec(void* data, const threefish1024_ctx_t* ctx);
+
+#endif /* THREEFISH_H_ */
diff --git a/skein/threefish1024_dec.c b/skein/threefish1024_dec.c
new file mode 100644 (file)
index 0000000..816efcb
--- /dev/null
@@ -0,0 +1,106 @@
+/* threefish1024_enc.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-03-12
+ * \license GPLv3 or later
+ *
+ *
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+
+#define X(a) (((uint64_t*)data)[(a)])
+
+static
+void permute_inv16(void* data){
+       uint64_t t;
+       t = X(15);
+       X(15) = X(7);
+       X(7) = X(9);
+       X(9) = X(1);
+       X(1) = t;
+       t = X(11);
+       X(11) = X(5);
+       X(5) = X(13);
+       X(13) = X(3);
+       X(3) = t;
+       t = X(4);
+       X(4) = X(6);
+       X(6) = t;
+       t = X(14);
+       X(14) = X(12);
+       X(12) = X(10);
+       X(10) = X(8);
+       X(8) = t;
+}
+
+static
+void add_key_16(void* data, const threefish1024_ctx_t* ctx, uint8_t s){
+       uint8_t i;
+       for(i=0; i<13; ++i){
+               X(i) -= ctx->k[(s+i)%17];
+       }
+       X(13) -= ctx->k[(s+13)%17] + ctx->t[s%3];
+       X(14) -= ctx->k[(s+14)%17] + ctx->t[(s+1)%3];
+       X(15) -= ctx->k[(s+15)%17] + s;
+}
+
+void threefish1024_dec(void* data, const threefish1024_ctx_t* ctx){
+       uint8_t i=0,s=20;
+       /* old round constants
+       uint8_t r0[8] = {47, 58, 17, 28, 34, 33, 25, 55};
+       uint8_t r1[8] = {49,  7,  6,  7, 43,  8, 25, 43};
+       uint8_t r2[8] = {27, 32, 18, 47, 25, 18, 46, 37};
+       uint8_t r3[8] = {58, 45, 25, 48, 60, 57, 13, 40};
+       uint8_t r4[8] = {37, 19, 43, 51, 44, 21, 14, 16};
+       uint8_t r5[8] = {48, 18, 42,  9,  9, 12, 13, 22};
+       uint8_t r6[8] = {53,  2, 40, 35, 59, 32, 52, 38};
+       uint8_t r7[8] = {56, 56, 15, 41, 34, 54, 57, 12};
+       */
+       uint8_t r0[8] = {  9, 31, 16, 41,  5, 33, 38, 24};
+       uint8_t r1[8] = { 48, 44, 34,  9, 20,  4, 19, 13};
+       uint8_t r2[8] = { 35, 47, 56, 37, 48, 51, 10,  8};
+       uint8_t r3[8] = { 52, 46, 51, 31, 41, 13, 55, 47};
+       uint8_t r4[8] = { 23, 19,  4, 12, 47, 34, 49,  8};
+       uint8_t r5[8] = { 31, 42, 53, 47, 28, 41, 18, 17};
+       uint8_t r6[8] = { 37, 44, 42, 44, 16, 59, 23, 22};
+       uint8_t r7[8] = { 20, 25, 41, 30, 25, 17, 52, 37};
+       do{
+               if(i%4==0){
+                       add_key_16(data, ctx, s);
+                       --s;
+               }
+               permute_inv16(data);
+               threefish_invmix((uint8_t*)data +  0, r0[i%8]);
+               threefish_invmix((uint8_t*)data + 16, r1[i%8]);
+               threefish_invmix((uint8_t*)data + 32, r2[i%8]);
+               threefish_invmix((uint8_t*)data + 48, r3[i%8]);
+               threefish_invmix((uint8_t*)data + 64, r4[i%8]);
+               threefish_invmix((uint8_t*)data + 80, r5[i%8]);
+               threefish_invmix((uint8_t*)data + 96, r6[i%8]);
+               threefish_invmix((uint8_t*)data +112, r7[i%8]);
+               ++i;
+       }while(i!=80);
+       add_key_16(data, ctx, s);
+}
diff --git a/skein/threefish1024_enc.c b/skein/threefish1024_enc.c
new file mode 100644 (file)
index 0000000..b873be1
--- /dev/null
@@ -0,0 +1,126 @@
+/* threefish1024_enc.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-03-12
+ * \license GPLv3 or later
+ *
+ *
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+
+#define X(a) (((uint64_t*)data)[(a)])
+
+static
+void permute_16(void* data){
+       uint64_t t;
+       t = X(1);
+       X(1) = X(9);
+       X(9) = X(7);
+       X(7) = X(15);
+       X(15) = t;
+       t = X(3);
+       X(3) = X(13);
+       X(13) = X(5);
+       X(5) = X(11);
+       X(11) = t;
+       t = X(4);
+       X(4) = X(6);
+       X(6) = t;
+       t = X(8);
+       X(8) = X(10);
+       X(10) = X(12);
+       X(12) = X(14);
+       X(14) = t;
+}
+
+#define THREEFISH_KEY_CONST 0x5555555555555555LL /* 2**64/3 */
+
+#define K(s) (((uint64_t*)key)[(s)])
+#define T(s) (((uint64_t*)tweak)[(s)])
+
+void threefish1024_init(const void* key, const void* tweak, threefish1024_ctx_t* ctx){
+       memcpy(ctx->k, key, 16*8);
+       if(tweak){
+               memcpy(ctx->t, tweak, 2*8);
+               ctx->t[2] = T(0) ^ T(1);
+       }else{
+               memset(ctx, 0, 3*8);
+       }
+       uint8_t i;
+       ctx->k[16] = THREEFISH_KEY_CONST;
+       for(i=0; i<16; ++i){
+               ctx->k[16] ^= K(i);
+       }
+}
+
+static
+void add_key_16(void* data, const threefish1024_ctx_t* ctx, uint8_t s){
+       uint8_t i;
+       for(i=0; i<13; ++i){
+               X(i) += ctx->k[(s+i)%17];
+       }
+       X(13) += ctx->k[(s+13)%17] + ctx->t[s%3];
+       X(14) += ctx->k[(s+14)%17] + ctx->t[(s+1)%3];
+       X(15) += ctx->k[(s+15)%17] + s;
+}
+
+void threefish1024_enc(void* data, const threefish1024_ctx_t* ctx){
+       uint8_t i=0,s=0;
+       /* old constans, changed at round 2 of the SHA-3 contest
+       uint8_t r0[8] = {55, 25, 33, 34, 28, 17, 58, 47};
+       uint8_t r1[8] = {43, 25,  8, 43,  7,  6,  7, 49};
+       uint8_t r2[8] = {37, 46, 18, 25, 47, 18, 32, 27};
+       uint8_t r3[8] = {40, 13, 57, 60, 48, 25, 45, 58};
+       uint8_t r4[8] = {16, 14, 21, 44, 51, 43, 19, 37};
+       uint8_t r5[8] = {22, 13, 12,  9,  9, 42, 18, 48};
+       uint8_t r6[8] = {38, 52, 32, 59, 35, 40,  2, 53};
+       uint8_t r7[8] = {12, 57, 54, 34, 41, 15, 56, 56};
+       */
+       uint8_t r0[8] = {24, 38, 33,  5, 41, 16, 31,  9};
+       uint8_t r1[8] = {13, 19,  4, 20,  9, 34, 44, 48};
+       uint8_t r2[8] = { 8, 10, 51, 48, 37, 56, 47, 35};
+       uint8_t r3[8] = {47, 55, 13, 41, 31, 51, 46, 52};
+       uint8_t r4[8] = { 8, 49, 34, 47, 12,  4, 19, 23};
+       uint8_t r5[8] = {17, 18, 41, 28, 47, 53, 42, 31};
+       uint8_t r6[8] = {22, 23, 59, 16, 44, 42, 44, 37};
+       uint8_t r7[8] = {37, 52, 17, 25, 30, 41, 25, 20};
+       do{
+               if(i%4==0){
+                       add_key_16(data, ctx, s);
+                       ++s;
+               }
+               threefish_mix((uint8_t*)data +  0, r0[i%8]);
+               threefish_mix((uint8_t*)data + 16, r1[i%8]);
+               threefish_mix((uint8_t*)data + 32, r2[i%8]);
+               threefish_mix((uint8_t*)data + 48, r3[i%8]);
+               threefish_mix((uint8_t*)data + 64, r4[i%8]);
+               threefish_mix((uint8_t*)data + 80, r5[i%8]);
+               threefish_mix((uint8_t*)data + 96, r6[i%8]);
+               threefish_mix((uint8_t*)data +112, r7[i%8]);
+               permute_16(data);
+               ++i;
+       }while(i!=80);
+       add_key_16(data, ctx, s);
+}
diff --git a/skein/threefish256_dec.c b/skein/threefish256_dec.c
new file mode 100644 (file)
index 0000000..a8e7eab
--- /dev/null
@@ -0,0 +1,74 @@
+/* threefish256_enc.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-03-12
+ * \license GPLv3 or later
+ *
+ *
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+
+#define X(a) (((uint64_t*)data)[(a)])
+static
+void permute_4(void* data){
+       uint64_t t;
+       t = X(1);
+       X(1) = X(3);
+       X(3) = t;
+}
+
+#define K(s) (((uint64_t*)key)[(s)])
+#define T(s) (((uint64_t*)tweak)[(s)])
+
+static
+void add_key_4(void* data, const threefish256_ctx_t* ctx, uint8_t s){
+       X(0) -= ctx->k[(s+0)%5];
+       X(1) -= ctx->k[(s+1)%5] + ctx->t[s%3];
+       X(2) -= ctx->k[(s+2)%5] + ctx->t[(s+1)%3];
+       X(3) -= ctx->k[(s+3)%5] + s;
+}
+
+void threefish256_dec(void* data, const threefish256_ctx_t* ctx){
+       uint8_t i=0,s=18;
+/* old constans, changed at round 2 of the SHA-3 contest
+       uint8_t r0[8] = {59, 11, 53, 26, 58, 13, 36,  5};
+       uint8_t r1[8] = {50, 42, 35, 20, 44, 46, 28, 56};
+*/
+       uint8_t r0[8] = { 32, 58, 46, 25,  5, 23, 52, 14};
+       uint8_t r1[8] = { 32, 22, 12, 33, 37, 40, 57, 16};
+
+       do{
+               if(i%4==0){
+                       add_key_4(data, ctx, s);
+                       --s;
+               }
+               permute_4(data);
+               threefish_invmix(data, r0[i%8]);
+               threefish_invmix((uint8_t*)data + 16, r1[i%8]);
+               ++i;
+       }while(i!=72);
+       add_key_4(data, ctx, s);
+}
+
diff --git a/skein/threefish256_enc.c b/skein/threefish256_enc.c
new file mode 100644 (file)
index 0000000..7530f4f
--- /dev/null
@@ -0,0 +1,90 @@
+/* threefish256_enc.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-03-12
+ * \license GPLv3 or later
+ *
+ *
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+
+#define X(a) (((uint64_t*)data)[(a)])
+static
+void permute_4(void* data){
+       uint64_t t;
+       t = X(1);
+       X(1) = X(3);
+       X(3) = t;
+}
+
+#define THREEFISH_KEY_CONST 0x5555555555555555LL /* 2**64/3 */
+
+#define K(s) (((uint64_t*)key)[(s)])
+#define T(s) (((uint64_t*)tweak)[(s)])
+
+void threefish256_init(const void* key, const void* tweak, threefish256_ctx_t* ctx){
+       memcpy(ctx->k, key, 4*8);
+       if(tweak){
+               memcpy(ctx->t, tweak, 2*8);
+               ctx->t[2] = T(0) ^ T(1);
+       }else{
+               memset(ctx->t, 0, 3*8);
+       }
+       uint8_t i;
+       ctx->k[4] = THREEFISH_KEY_CONST;
+       for(i=0; i<4; ++i){
+               ctx->k[4] ^= K(i);
+       }
+}
+
+static
+void add_key_4(void* data, const threefish256_ctx_t* ctx, uint8_t s){
+       X(0) += ctx->k[(s+0)%5];
+       X(1) += ctx->k[(s+1)%5] + ctx->t[s%3];
+       X(2) += ctx->k[(s+2)%5] + ctx->t[(s+1)%3];
+       X(3) += ctx->k[(s+3)%5] + s;
+}
+
+void threefish256_enc(void* data, const threefish256_ctx_t* ctx){
+       uint8_t i=0,s=0;
+/* old constans, changed at round 2 of the SHA-3 contest
+       uint8_t r0[8] = { 5, 36, 13, 58, 26, 53, 11, 59};
+       uint8_t r1[8] = {56, 28, 46, 44, 20, 35, 42, 50};
+*/
+       uint8_t r0[8] = {14, 52, 23,  5, 25, 46, 58, 32};
+       uint8_t r1[8] = {16, 57, 40, 37, 33, 12, 22, 32};
+       do{
+               if(i%4==0){
+                       add_key_4(data, ctx, s);
+                       ++s;
+               }
+               threefish_mix(data, r0[i%8]);
+               threefish_mix((uint8_t*)data + 16, r1[i%8]);
+               permute_4(data);
+               ++i;
+       }while(i!=72);
+       add_key_4(data, ctx, s);
+}
+
diff --git a/skein/threefish512_dec.c b/skein/threefish512_dec.c
new file mode 100644 (file)
index 0000000..de63d4f
--- /dev/null
@@ -0,0 +1,88 @@
+/* threefish512_dec.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-03-22
+ * \license GPLv3 or later
+ *
+ *
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+
+
+#define X(a) (((uint64_t*)data)[(a)])
+
+
+static
+void permute_inv8(void* data){
+       uint64_t t;
+       t = X(6);
+       X(6) = X(4);
+       X(4) = X(2);
+       X(2) = X(0);
+       X(0) = t;
+       t = X(7);
+       X(7) = X(3);
+       X(3) = t;
+}
+
+static
+void add_key_8(void* data, const threefish512_ctx_t* ctx, uint8_t s){
+       uint8_t i;
+       for(i=0; i<5; ++i){
+               X(i) -= ctx->k[(s+i)%9];
+       }
+       X(5) -= ctx->k[(s+5)%9] + ctx->t[s%3];
+       X(6) -= ctx->k[(s+6)%9] + ctx->t[(s+1)%3];
+       X(7) -= ctx->k[(s+7)%9] + s;
+}
+
+void threefish512_dec(void* data, const threefish512_ctx_t* ctx){
+       uint8_t i=0,s=18;
+       /* old round constants
+       uint8_t r0[8] = {33, 29, 39, 33, 26, 34, 48, 38};
+       uint8_t r1[8] = {51, 26, 27, 49, 12, 14, 20, 30};
+       uint8_t r2[8] = {39, 11, 41,  8, 58, 15, 43, 50};
+       uint8_t r3[8] = {35,  9, 14, 42,  7, 27, 31, 53};
+       */
+       uint8_t r0[8] = {  8, 25, 13, 39, 44, 17, 33, 46};
+       uint8_t r1[8] = { 35, 29, 50, 30,  9, 49, 27, 36};
+       uint8_t r2[8] = { 56, 39, 10, 34, 54, 36, 14, 19};
+       uint8_t r3[8] = { 22, 43, 17, 24, 56, 39, 42, 37};
+
+       do{
+               if(i%4==0){
+                       add_key_8(data, ctx, s);
+                       --s;
+               }
+               permute_inv8(data);
+               threefish_invmix((uint8_t*)data +  0, r0[i%8]);
+               threefish_invmix((uint8_t*)data + 16, r1[i%8]);
+               threefish_invmix((uint8_t*)data + 32, r2[i%8]);
+               threefish_invmix((uint8_t*)data + 48, r3[i%8]);
+               ++i;
+       }while(i!=72);
+       add_key_8(data, ctx, s);
+}
+
diff --git a/skein/threefish512_enc.c b/skein/threefish512_enc.c
new file mode 100644 (file)
index 0000000..20cbdc1
--- /dev/null
@@ -0,0 +1,121 @@
+/* threefish512_enc.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-03-12
+ * \license GPLv3 or later
+ *
+ *
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+
+
+#define X(a) (((uint64_t*)data)[(a)])
+
+
+static
+void permute_8(void* data){
+       uint64_t t;
+       t = X(0);
+       X(0) = X(2);
+       X(2) = X(4);
+       X(4) = X(6);
+       X(6) = t;
+       t = X(3);
+       X(3) = X(7);
+       X(7) = t;
+}
+/*
+static
+void permute_inv8(void* data){
+       uint64_t t;
+       t = X(6);
+       X(6) = X(4);
+       X(4) = X(2);
+       X(2) = X(0);
+       X(0) = t;
+       t = X(7);
+       X(7) = X(3);
+       X(3) = t;
+}
+*/
+
+#define THREEFISH_KEY_CONST 0x5555555555555555LL /* 2**64/3 */
+
+#define K(s) (((uint64_t*)key)[(s)])
+#define T(s) (((uint64_t*)tweak)[(s)])
+
+void threefish512_init(const void* key, const void* tweak, threefish512_ctx_t* ctx){
+       memcpy(ctx->k, key, 8*8);
+       if(tweak){
+               memcpy(ctx->t, tweak, 2*8);
+               ctx->t[2] = T(0) ^ T(1);
+       }else{
+               memset(ctx->t, 0, 3*8);
+       }
+       uint8_t i;
+       ctx->k[8] = THREEFISH_KEY_CONST;
+       for(i=0; i<8; ++i){
+               ctx->k[8] ^= K(i);
+       }
+}
+
+static
+void add_key_8(void* data, const threefish512_ctx_t* ctx, uint8_t s){
+       uint8_t i;
+       for(i=0; i<5; ++i){
+               X(i) += ctx->k[(s+i)%9];
+       }
+       X(5) += ctx->k[(s+5)%9] + ctx->t[s%3];
+       X(6) += ctx->k[(s+6)%9] + ctx->t[(s+1)%3];
+       X(7) += ctx->k[(s+7)%9] + s;
+}
+
+void threefish512_enc(void* data, const threefish512_ctx_t* ctx){
+       uint8_t i=0,s=0;
+       /* old constans, changed at round 2 of the SHA-3 contest
+       uint8_t r0[8] = {38, 48, 34, 26, 33, 39, 29, 33};
+       uint8_t r1[8] = {30, 20, 14, 12, 49, 27, 26, 51};
+       uint8_t r2[8] = {50, 43, 15, 58,  8, 41, 11, 39};
+       uint8_t r3[8] = {53, 31, 27,  7, 42, 14,  9, 35};
+       */
+       uint8_t r0[8] = {46, 33, 17, 44, 39, 13, 25,  8};
+       uint8_t r1[8] = {36, 27, 49,  9, 30, 50, 29, 35};
+       uint8_t r2[8] = {19, 14, 36, 54, 34, 10, 39, 56};
+       uint8_t r3[8] = {37, 42, 39, 56, 24, 17, 43, 22};
+       do{
+               if(i%4==0){
+                       add_key_8(data, ctx, s);
+                       ++s;
+               }
+               threefish_mix((uint8_t*)data +  0, r0[i%8]);
+               threefish_mix((uint8_t*)data + 16, r1[i%8]);
+               threefish_mix((uint8_t*)data + 32, r2[i%8]);
+               threefish_mix((uint8_t*)data + 48, r3[i%8]);
+               permute_8(data);
+               ++i;
+       }while(i!=72);
+       add_key_8(data, ctx, s);
+}
+
diff --git a/skein/threefish_invmix_c.c b/skein/threefish_invmix_c.c
new file mode 100644 (file)
index 0000000..e0d9e5c
--- /dev/null
@@ -0,0 +1,39 @@
+/* threefish_invmix_c.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-03-21
+ * \license GPLv3 or later
+ * 
+ * 
+ * 
+ */
+
+#include <stdint.h>
+
+#define X0 (((uint64_t*)data)[0])
+#define X1 (((uint64_t*)data)[1])
+void threefish_invmix(void* data, uint8_t rot){
+       uint64_t x;
+       x = X1;
+       x ^= X0;
+       X1 = ((x>>rot)|(x<<(64-rot)));
+       X0 -= X1;
+}
diff --git a/skein/threefish_mix_c.c b/skein/threefish_mix_c.c
new file mode 100644 (file)
index 0000000..0a1e706
--- /dev/null
@@ -0,0 +1,38 @@
+/* threefish_mix_c.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-03-16
+ * \license GPLv3 or later
+ * 
+ * 
+ * 
+ */
+
+#include <stdint.h>
+
+#define X0 (((uint64_t*)data)[0])
+#define X1 (((uint64_t*)data)[1])
+void threefish_mix(void* data, uint8_t rot){
+       uint64_t x;
+       x = X1;
+       X0 += x;
+       X1 = ((x<<rot)|(x>>(64-rot))) ^ X0;
+}
diff --git a/skein/ubi.h b/skein/ubi.h
new file mode 100644 (file)
index 0000000..1471881
--- /dev/null
@@ -0,0 +1,93 @@
+/* ubi.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-03-12
+ * \license GPLv3 or later
+ * 
+ */
+
+#ifndef UBI_H_
+#define UBI_H_
+
+#include <stdint.h>
+
+#define UBI_TYPE_KEY  0
+#define UBI_TYPE_CFG  4
+#define UBI_TYPE_PRS  8
+#define UBI_TYPE_PK  12
+#define UBI_TYPE_KDF 16
+#define UBI_TYPE_NON 20
+#define UBI_TYPE_MSG 48
+#define UBI_TYPE_OUT 63
+
+#define UBI256_BLOCKSIZE 256
+#define UBI256_BLOCKSIZE_B ((UBI256_BLOCKSIZE+7)/8)
+
+#define UBI512_BLOCKSIZE 512
+#define UBI512_BLOCKSIZE_B ((UBI512_BLOCKSIZE+7)/8)
+
+#define UBI1024_BLOCKSIZE 1024
+#define UBI1024_BLOCKSIZE_B ((UBI1024_BLOCKSIZE+7)/8)
+
+
+typedef struct{
+       uint8_t tweak[16];
+       uint8_t g[32];
+}ubi256_ctx_t;
+
+typedef struct{
+       uint8_t tweak[16];
+       uint8_t g[64];
+}ubi512_ctx_t;
+
+typedef struct{
+       uint8_t tweak[16];
+       uint8_t g[128];
+}ubi1024_ctx_t;
+
+void ubi256_init(ubi256_ctx_t* ctx, const void* g, uint8_t type);
+void ubi256_nextBlock(ubi256_ctx_t* ctx, const void* block);
+void ubi256_lastBlock(ubi256_ctx_t* ctx, const void* block, uint16_t length_b);
+void ubi256_ctx2hash(void* dest, const ubi256_ctx_t* ctx);
+
+void ubi512_init(ubi512_ctx_t* ctx, const void* g, uint8_t type);
+void ubi512_nextBlock(ubi512_ctx_t* ctx, const void* block);
+void ubi512_lastBlock(ubi512_ctx_t* ctx, const void* block, uint16_t length_b);
+void ubi512_ctx2hash(void* dest, const ubi512_ctx_t* ctx);
+
+void ubi1024_init(ubi1024_ctx_t* ctx, const void* g, uint8_t type);
+void ubi1024_nextBlock(ubi1024_ctx_t* ctx, const void* block);
+void ubi1024_lastBlock(ubi1024_ctx_t* ctx, const void* block, uint16_t length_b);
+void ubi1024_ctx2hash(void* dest, const ubi1024_ctx_t* ctx);
+
+typedef struct{
+       char     schema[4];
+       uint16_t version;
+       uint16_t reserved1;
+       uint64_t out_length;
+       uint8_t  tree_leaf_size;
+       uint8_t  tree_fan_out;
+       uint8_t  tree_max_height;
+       uint8_t  reserved2[13];
+}skein_config_t;
+
+
+#endif /* UBI_H_ */
diff --git a/skein/ubi1024.c b/skein/ubi1024.c
new file mode 100644 (file)
index 0000000..a7d5326
--- /dev/null
@@ -0,0 +1,76 @@
+/* ubi1024.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-03-12
+ * \license GPLv3 or later
+ * 
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+#include "memxor.h"
+#include "ubi.h"
+
+void ubi1024_init(ubi1024_ctx_t* ctx, const void* g, uint8_t type){
+       memset(ctx->tweak, 0, 15);
+       ctx->tweak[15] = 0x40+type;
+       memcpy(ctx->g, g, UBI1024_BLOCKSIZE_B);
+}
+
+void ubi1024_nextBlock(ubi1024_ctx_t* ctx, const void* block){
+       threefish1024_ctx_t tfctx;
+       ((uint64_t*)(ctx->tweak))[0] += UBI1024_BLOCKSIZE_B;
+       threefish1024_init(ctx->g, ctx->tweak, &tfctx);
+       memcpy(ctx->g, block, UBI1024_BLOCKSIZE_B);
+       threefish1024_enc(ctx->g, &tfctx);
+       memxor(ctx->g, block, UBI1024_BLOCKSIZE_B);
+       ctx->tweak[15] &= (uint8_t)~0x40;
+} 
+
+
+void ubi1024_lastBlock(ubi1024_ctx_t* ctx, const void* block, uint16_t length_b){
+       threefish1024_ctx_t tfctx;
+       while(length_b>UBI1024_BLOCKSIZE){
+               ubi1024_nextBlock(ctx, block);
+               block = (uint8_t*)block + UBI1024_BLOCKSIZE_B;
+               length_b -= UBI1024_BLOCKSIZE;
+       }
+       ctx->tweak[15] |= 0x80;
+       ((uint64_t*)(ctx->tweak))[0] += (length_b+7)/8;
+       if(length_b & 0x07)
+               ctx->tweak[14] |= 0x80;
+       threefish1024_init(ctx->g, ctx->tweak, &tfctx);
+       memset(ctx->g, 0, UBI1024_BLOCKSIZE_B);
+       memcpy(ctx->g, block, (length_b+7)/8);
+       if(length_b & 0x07)
+               ctx->g[(length_b+7)/8-1] |= 0x80>>(length_b&7);
+       threefish1024_enc(ctx->g, &tfctx);
+       memxor(ctx->g, block, (length_b+7)/8);
+       if(length_b & 0x07){
+               ctx->g[((length_b+7)/8)-1] ^= 0x80>>(length_b&7);
+       }
+} 
+
+void ubi1024_ctx2hash(void* dest, const ubi1024_ctx_t* ctx){
+       memcpy(dest, ctx->g, UBI1024_BLOCKSIZE_B);
+}
+
diff --git a/skein/ubi256.c b/skein/ubi256.c
new file mode 100644 (file)
index 0000000..5b0fc57
--- /dev/null
@@ -0,0 +1,80 @@
+/* ubi256.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-03-12
+ * \license GPLv3 or later
+ * 
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+#include "memxor.h"
+#include "ubi.h"
+
+void ubi256_init(ubi256_ctx_t* ctx, const void* g, uint8_t type){
+       memset(ctx->tweak, 0, 15);
+       ctx->tweak[15] = 0x40+type;
+       memcpy(ctx->g, g, 32);
+}
+
+void ubi256_nextBlock(ubi256_ctx_t* ctx, const void* block){
+       threefish256_ctx_t tfctx;
+       ((uint64_t*)(ctx->tweak))[0] += UBI256_BLOCKSIZE_B;
+       threefish256_init(ctx->g, ctx->tweak, &tfctx);
+       memcpy(ctx->g, block, UBI256_BLOCKSIZE_B);
+       threefish256_enc(ctx->g, &tfctx);
+       memxor(ctx->g, block, UBI256_BLOCKSIZE_B);
+       ctx->tweak[15] &= (uint8_t)~0x40;
+} 
+
+
+void ubi256_lastBlock(ubi256_ctx_t* ctx, const void* block, uint16_t length_b){
+       threefish256_ctx_t tfctx;
+       while(length_b>UBI256_BLOCKSIZE){
+               ubi256_nextBlock(ctx, block);
+               block = (uint8_t*)block + UBI256_BLOCKSIZE_B;
+               length_b -= UBI256_BLOCKSIZE;
+       }
+       ctx->tweak[15] |= 0x80;
+       ((uint64_t*)(ctx->tweak))[0] += (length_b+7)/8;
+       if(length_b & 0x07){
+               ctx->tweak[14] |= 0x80;
+       }
+       threefish256_init(ctx->g, ctx->tweak, &tfctx);
+       memset(ctx->g, 0, UBI256_BLOCKSIZE_B);
+       memcpy(ctx->g, block, (length_b+7)/8);
+       if(length_b & 0x07){
+               ctx->g[((length_b+7)/8)-1] |= 0x80>>(length_b&7);
+               ctx->g[((length_b+7)/8)-1] &= ~((0x80>>(length_b&7))-1);
+       }
+       threefish256_enc(ctx->g, &tfctx);
+       memxor(ctx->g, block, (length_b+7)/8);
+       if(length_b & 0x07){
+               ctx->g[((length_b+7)/8)-1] ^= 0x80>>(length_b&7);
+       }
+
+} 
+
+void ubi256_ctx2hash(void* dest, const ubi256_ctx_t* ctx){
+       memcpy(dest, ctx->g, UBI256_BLOCKSIZE_B);
+}
+
diff --git a/skein/ubi512.c b/skein/ubi512.c
new file mode 100644 (file)
index 0000000..e0e6dc0
--- /dev/null
@@ -0,0 +1,76 @@
+/* ubi512.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-03-12
+ * \license GPLv3 or later
+ * 
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+#include "memxor.h"
+#include "ubi.h"
+
+void ubi512_init(ubi512_ctx_t* ctx, const void* g, uint8_t type){
+       memset(ctx->tweak, 0, 15);
+       ctx->tweak[15] = 0x40+type;
+       memcpy(ctx->g, g, UBI512_BLOCKSIZE_B);
+}
+
+void ubi512_nextBlock(ubi512_ctx_t* ctx, const void* block){
+       threefish512_ctx_t tfctx;
+       ((uint64_t*)(ctx->tweak))[0] += UBI512_BLOCKSIZE_B;
+       threefish512_init(ctx->g, ctx->tweak, &tfctx);
+       memcpy(ctx->g, block, UBI512_BLOCKSIZE_B);
+       threefish512_enc(ctx->g, &tfctx);
+       memxor(ctx->g, block, UBI512_BLOCKSIZE_B);
+       ctx->tweak[15] &= (uint8_t)~0x40;
+} 
+
+
+void ubi512_lastBlock(ubi512_ctx_t* ctx, const void* block, uint16_t length_b){
+       threefish512_ctx_t tfctx;
+       while(length_b>UBI512_BLOCKSIZE){
+               ubi512_nextBlock(ctx, block);
+               block = (uint8_t*)block + UBI512_BLOCKSIZE_B;
+               length_b -= UBI512_BLOCKSIZE;
+       }
+       ctx->tweak[15] |= 0x80;
+       ((uint64_t*)(ctx->tweak))[0] += (length_b+7)/8;
+       if(length_b & 0x07)
+               ctx->tweak[14] |= 0x80;
+       threefish512_init(ctx->g, ctx->tweak, &tfctx);
+       memset(ctx->g, 0, UBI512_BLOCKSIZE_B);
+       memcpy(ctx->g, block, (length_b+7)/8);
+       if(length_b & 0x07)
+               ctx->g[(length_b+7)/8-1] |= 0x80>>(length_b&7);
+       threefish512_enc(ctx->g, &tfctx);
+       memxor(ctx->g, block, (length_b+7)/8);
+       if(length_b & 0x07){
+               ctx->g[((length_b+7)/8)-1] ^= 0x80>>(length_b&7);
+       }
+} 
+
+void ubi512_ctx2hash(void* dest, const ubi512_ctx_t* ctx){
+       memcpy(dest, ctx->g, UBI512_BLOCKSIZE_B);
+}
+
diff --git a/test_src/circularbytebuffer.c b/test_src/circularbytebuffer.c
new file mode 100644 (file)
index 0000000..720da14
--- /dev/null
@@ -0,0 +1,123 @@
+/* circularbytebuffer.c */
+/*
+    This file is part of the AVR-circularbuffer.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     circularbytebuffer.c
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-07-24
+ * \license  GPLv3 or later
+ * \ingroup  circularbytebuffer
+ * \brief    implementation for circular byte buffer
+ */
+ #include <stdint.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include "circularbytebuffer.h"
+
+#ifndef CIRCULARBYTEBUFFER_NO_MALLOC
+#  define CIRCULARBYTEBUFFER_NO_MALLOC 0
+#endif
+
+#ifndef CIRCULARBYTEBUFFER_NO_INIT2
+#  define CIRCULARBYTEBUFFER_NO_INIT2 0
+#endif
+
+#if CIRCULARBYTEBUFFER_NO_MALLOC==0
+uint8_t circularbytebuffer_init(uint32_t buffersize, circularbytebuffer_t* cb){
+       cb->buffer_size = buffersize;
+       cb->buffer = malloc(buffersize);
+       cb->head = cb->tail = cb->buffer;
+       cb->top = cb->buffer + cb->buffer_size;
+       cb->fillcount = 0;
+       if(cb->buffer)
+               return 1; /* success */
+       return 0; /* malloc failed */   
+}
+#endif
+
+#if CIRCULARBYTEBUFFER_NO_INIT2==0
+void circularbytebuffer_init2(uint32_t buffersize, circularbytebuffer_t* cb, void* buffer){
+       cb->buffer_size = buffersize;
+       cb->buffer = buffer;
+       cb->head = cb->tail = cb->buffer;
+       cb->top = cb->buffer + cb->buffer_size;
+       cb->fillcount = 0;
+}
+#endif
+
+uint16_t circularbytebuffer_get_lifo(circularbytebuffer_t* cb){
+       uint8_t ret;
+       if(cb->fillcount==0)
+               return 0xffff;
+       --cb->fillcount;
+       ret=*(cb->tail);
+       cb->tail = (uint8_t*)(cb->tail) + 1;
+       if(cb->tail>=cb->top)   
+               cb->tail = (uint8_t*)(cb->tail) - cb->buffer_size;
+       return ret;     
+}
+
+uint16_t circularbytebuffer_get_fifo(circularbytebuffer_t* cb){
+       uint8_t ret;
+       if(cb->fillcount==0)
+               return 0xffff;
+       --cb->fillcount;
+       ret=*(cb->head);
+       cb->head = (uint8_t*)(cb->head) - 1;
+       if(cb->head<cb->buffer) 
+               cb->head = (uint8_t*)(cb->head) + cb->buffer_size;
+       return ret;
+}
+
+uint8_t circularbytebuffer_append(uint8_t elem, circularbytebuffer_t* cb){
+       if(cb->fillcount==cb->buffer_size)
+               return 1;
+       cb->fillcount++;        
+       cb->tail = cb->tail - 1;
+       if(cb->tail<cb->buffer) 
+               cb->tail = (uint8_t*)(cb->tail) + cb->buffer_size;
+       if(cb->fillcount==1)
+               cb->head = cb->tail;
+       *(cb->tail) = elem;
+       return 0;
+}
+
+uint8_t circularbytebuffer_push(uint8_t elem, circularbytebuffer_t* cb){
+       if(cb->fillcount==cb->buffer_size)
+               return 1;
+       cb->fillcount++;        
+       cb->head = cb->head + 1;
+       if(cb->head>=cb->top)   
+               cb->head = (uint8_t*)(cb->head) - cb->buffer_size;
+       if(cb->fillcount==1)
+               cb->tail = cb->head;
+       *(cb->head) = elem;
+       return 0;
+}
+
+uint32_t circularbytebuffer_cnt(circularbytebuffer_t* cb){
+       return (cb->fillcount);
+}
+
+#if CIRCULARBYTEBUFFER_NO_MALLOC==0
+void circularbytebuffer_free(circularbytebuffer_t* cb){
+       free(cb->buffer);
+}
+#endif
diff --git a/test_src/circularbytebuffer.h b/test_src/circularbytebuffer.h
new file mode 100644 (file)
index 0000000..6d6864c
--- /dev/null
@@ -0,0 +1,58 @@
+/* circularbytebuffer.h */
+/*
+    This file is part of the AVR-circularbytebuffer.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     circularbytebuffer.h
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-07-24
+ * \license  GPLv3 or later
+ * \ingroup  circularbytebuffer
+ * \brief    declaration for circular byte buffer
+ */
+#ifndef CIRCULARBYTEBUFFER_H_
+#define CIRCULARBYTEBUFFER_H_
+
+#include <stdint.h>
+#include <stdlib.h>
+ typedef struct {
+        uint32_t buffer_size;
+        uint32_t fillcount;
+        uint8_t* buffer;
+        uint8_t* head;
+        uint8_t* tail;
+        uint8_t* top;
+} circularbytebuffer_t;
+
+
+#if CIRCULARBYTEBUFFER_NO_MALLOC==0
+uint8_t circularbytebuffer_init(uint32_t buffersize, circularbytebuffer_t* cb);
+#endif
+#if CIRCULARBYTEBUFFER_NO_INIT2==0
+void    circularbytebuffer_init2(uint32_t buffersize, circularbytebuffer_t* cb, void* buffer);
+#endif
+uint16_t circularbytebuffer_get_lifo(circularbytebuffer_t* cb);
+uint16_t circularbytebuffer_get_fifo(circularbytebuffer_t* cb);
+uint8_t  circularbytebuffer_append(uint8_t, circularbytebuffer_t* cb);
+uint8_t  circularbytebuffer_push(uint8_t, circularbytebuffer_t* cb);
+uint32_t circularbytebuffer_cnt(circularbytebuffer_t* cb);
+void circularbytebuffer_free(circularbytebuffer_t* cb);
+
+#endif /* CIRCULARBYTEBUFFER_H_ */
diff --git a/test_src/cli-basics.o b/test_src/cli-basics.o
new file mode 100644 (file)
index 0000000..1c194cf
Binary files /dev/null and b/test_src/cli-basics.o differ
diff --git a/test_src/cli-core.o b/test_src/cli-core.o
new file mode 100644 (file)
index 0000000..dbedf89
Binary files /dev/null and b/test_src/cli-core.o differ
diff --git a/test_src/cli-hexdump.o b/test_src/cli-hexdump.o
new file mode 100644 (file)
index 0000000..745817c
Binary files /dev/null and b/test_src/cli-hexdump.o differ
diff --git a/test_src/cli.c b/test_src/cli.c
new file mode 100644 (file)
index 0000000..3ecdf6c
--- /dev/null
@@ -0,0 +1,421 @@
+/* cli.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * 
+ * author: Daniel Otte
+ * email:  daniel.otte@rub.de
+ * license: GPLv3 or later
+ * 
+ * components to help implementing simple command based interaction
+ * 
+ **/
+#include <stdlib.h> 
+#include <stdint.h>
+#include <ctype.h>
+#include <string.h>
+#include "string-extras.h"
+#include "cli.h"
+#include "hexdigit_tab.h"
+
+#ifndef MAX
+#define MAX(a,b) ((a>b)?(a):(b))
+#endif
+
+
+cli_rx_fpt cli_rx = NULL;
+cli_tx_fpt cli_tx = NULL;
+uint8_t cli_echo=1;
+
+/**
+ * \brief output a character to the console
+ * 
+ */
+
+void cli_putc(char c){
+       if(cli_tx)
+               cli_tx(c);
+}
+
+/**
+ * \brief get a character from the console
+ * Gets a character from the console input and blocks
+ * until a character is recieved
+ */
+uint16_t cli_getc(void){
+       if(cli_rx)
+               return cli_rx();
+       return ((uint16_t)-1);
+}
+
+/**
+ * \brief get a character from the console
+ * Gets a char from the console input (like cli_getc())
+ * and echos it back to the console if echo is enabled.
+ */
+uint16_t cli_getc_cecho(void){
+       char c;
+       if(cli_rx){
+               c = cli_rx();
+               if(cli_tx && cli_echo)
+                       cli_tx(c);
+               return c;
+       }
+       return ((uint16_t)-1);
+}
+
+/**
+ * \brief outputs a zero-terminated string from ram to the console
+ */
+void cli_putstr(const char* s){
+       if(!cli_tx)
+               return;
+       while(*s)
+               cli_tx(*s++);
+}
+
+
+/**
+ * \brief reads a line or max n characters from the console
+ * Writes characters from the console into the supplied buffer until a '\r'
+ * character is received or until n character a read (whatever happens first).
+ * The string will always be terminated by a '\0' character, so the buffer
+ * should have at least a size of n+1. 
+ */
+uint8_t cli_getsn(char* s, uint32_t n){
+       char c;
+       if(n==0)
+               return 2;
+       while((c=cli_getc_cecho())!='\0' && c!='\r' && n--){
+               *s++=c;
+       }
+       *s='\0';
+       return (c=='\r')?0:1;
+}
+
+void cli_hexdump_byte(uint8_t byte){
+       cli_tx(hexdigit_tab[byte>>4]);
+       cli_tx(hexdigit_tab[byte & 0xf]);
+}
+
+/**
+ * \brief dumps the contents of a buffer to the console
+ * Dumps length bytes from data to the console output. The dump
+ * will have 2*n continuous hexadecimal characters.
+ */
+void cli_hexdump(const void* data, uint32_t length){
+       if(!cli_tx)
+               return;
+       while(length--){
+               cli_hexdump_byte(*((uint8_t*)data));
+               data = (uint8_t*)data +1;
+       }
+}
+
+/**
+ * \brief dumps the contents of a buffer to the console
+ * This function behaves like cli_hexdump except that the
+ * bytes are dumped in reverse order. This is useful to dump
+ * integers which are in little endian order.
+ */
+void cli_hexdump_rev(const void* data, uint32_t length){
+       if(!cli_tx)
+               return;
+       data = (uint8_t*)data + length -1;
+       while(length--){
+               cli_hexdump_byte(*((uint8_t*)data));
+               data = (uint8_t*)data -1;
+       }
+}
+
+/**
+ * \brief dumps the contents of a buffer to the console
+ * Like cli_hexdump but bytes are seperated with a single space
+ * on the console output.
+ */
+void cli_hexdump2(const void* data, uint32_t length){
+       if(!cli_tx)
+               return;
+       while(length--){
+               cli_hexdump_byte(*((uint8_t*)data));
+               cli_tx(' ');
+               data = (uint8_t*)data +1;
+       }
+}
+
+/**
+ * \brief dumps the contents of a buffer to the console
+ * Like cli_hexdump but bytes are separated with a single space
+ * on the console output.
+ */
+void cli_hexdump_block(const void* data, uint32_t length, uint8_t indent, uint8_t width){
+       uint16_t i;
+       uint8_t  j;
+       if(!cli_tx)
+               return;
+       for(i=0; i<length; ++i){
+               if(i%width==0){
+                       cli_putstr("\r\n");
+                       for(j=0; j<indent; ++j){
+                               cli_tx(' ');
+                       }
+               }
+               cli_hexdump_byte(*((uint8_t*)data));
+               cli_tx(' ');
+               data = (uint8_t*)data +1;
+       }
+}
+
+static
+void cli_auto_help(uint32_t maxcmdlength, const cmdlist_entry_t* cmdlist){
+       cmdlist_entry_t item;
+       uint16_t i;
+       if(!cli_tx)
+               return;
+       
+       cli_putstr("\r\n[auto help] available commands:\r\n"
+                         " <command> - <params> - <address>\r\n");
+       for(;;){
+               memcpy(&item, cmdlist, sizeof(cmdlist_entry_t));
+               cmdlist += 1;
+               if(item.cmd_name==NULL){
+                       return;
+               }
+               cli_tx(' ');
+               cli_putstr(item.cmd_name);
+               i=MAX(maxcmdlength, strlen("<command>"))-strlen(item.cmd_name);
+               while(i--)
+                       cli_tx(' ');
+               cli_putstr(" - ");
+               if(item.cmd_param_str==NULL){
+                       cli_putstr("none \t- 0x");
+               } else {
+                       if(item.cmd_param_str==(void*)1){
+                               cli_putstr("yes  \t- 0x");
+                       } else {
+                               cli_putstr(item.cmd_param_str);
+                               cli_putstr(" \t- 0x");
+                       }
+               }
+               cli_hexdump_rev(&item.cmd_function, sizeof(void*));
+               cli_putstr("\r\n");
+       }
+}
+
+void echo_ctrl(char* s){
+       s = strstrip(s);
+       if(s==NULL || *s=='\0'){
+               cli_putstr("\r\necho is ");
+               cli_putstr(cli_echo?"on":"off");
+               cli_putstr("\r\n");
+       }
+       strlwr(s);
+       if(!strcmp(s, "true") || !strcmp(s, "on") || *s=='1'){
+               cli_echo=1;
+       }
+       if(!strcmp(s, "false") || !strcmp(s, "off") || *s=='0'){
+               cli_echo=0;
+       }
+}
+
+
+typedef void(*str_fpt)(char*);
+#define CLI_ENTER     13
+#define CLI_BACKSPACE  8
+#define CLI_TABULATOR  9
+
+static
+int8_t search_and_call(char* cmd, uint32_t maxcmdlength, const cmdlist_entry_t* cmdlist){
+       const cmdlist_entry_t* cmdlist_orig = cmdlist;
+       if(*cmd=='\0' || *cmd=='#')
+               return 1;
+       if(!strcmp(cmd, "exit"))
+               return 0;
+       if((!strcmp(cmd, "help")) || (!strcmp(cmd, "?"))){
+               cli_auto_help(maxcmdlength, cmdlist);
+               return 1;
+       }
+       uint16_t fwlength=firstword_length(cmd);
+       char fw[fwlength+1];
+       memcpy(fw, cmd, fwlength);
+       fw[fwlength] = '\0';
+       cmdlist_entry_t item;
+       do{
+               memcpy(&item, cmdlist, sizeof(cmdlist_entry_t));
+               cmdlist += 1;
+       }while(item.cmd_name!=NULL && strcmp(fw, item.cmd_name));
+       if(item.cmd_name==NULL){
+               cli_auto_help(maxcmdlength, cmdlist_orig);
+       } else {
+               if(item.cmd_function==NULL)
+                       return 2;
+               switch((uint32_t)item.cmd_param_str){
+                       case 0:
+                               item.cmd_function();
+                               break;
+                       case 1:
+                               if(cmd[fwlength]=='\0'){
+                                       ((str_fpt)item.cmd_function)(cmd+fwlength);
+                               } else {
+                                       ((str_fpt)item.cmd_function)(cmd+fwlength+1);
+                               }
+                               break;
+                       default:
+                               cli_putstr("\r\nparam parsing currently not implemented!\r\n");
+                               break;
+               }       
+               
+       }       
+       return 1;        
+}
+
+static const
+uint16_t max_cmd_length(const cmdlist_entry_t* cmdlist){
+       uint16_t t,ret=0;
+       const char* str;
+       for(;;){
+               str = cmdlist->cmd_name;
+               cmdlist += 1;
+               if(str==NULL){
+                       return ret;
+               }
+               t = strlen(str);
+               if(t>ret){
+                       ret=t;
+               }
+       }
+}
+
+uint8_t cli_completion(char* buffer, uint16_t maxcmdlength, const cmdlist_entry_t* cmdlist){
+       uint8_t i=0;
+       char ref[maxcmdlength+1];
+       const char* itemstr;
+       ref[0]='\0';
+       /* check if we are behind the first word */
+       while(buffer[i]){
+               if(!isgraph(buffer[i++]))
+                       return 0;
+       }
+       for(;;){
+               itemstr = cmdlist->cmd_name;
+               if(itemstr==NULL)
+                       break;
+               cmdlist += 1;
+               if(!strncmp(buffer, itemstr, i)){
+                       if(!ref[0]){
+                               strcpy(ref, itemstr);
+                       }else{
+                               ref[stridentcnt(ref, itemstr)]='\0';
+                       }
+               }
+       }
+       i = strcmp(buffer, ref);
+       if(i)
+               strcpy(buffer, ref);
+       return ~i;
+}
+
+void cli_option_listing(char* buffer, const cmdlist_entry_t* cmdlist){
+       const char* itemstr;
+       uint16_t len=strlen(buffer);
+       for(;;){
+               itemstr = cmdlist->cmd_name;
+               if(itemstr==NULL){
+                       cli_putstr("\r\n>");
+                       cli_putstr(buffer);
+                       return;
+               }
+               cmdlist += 1;
+               if(!strncmp(buffer, itemstr, len)){
+                       cli_putstr("\r\n    ");
+                       cli_putstr(itemstr);
+               }
+       }
+}
+
+int8_t cmd_interface(const cmdlist_entry_t* cmd_desc){
+       uint16_t cli_buffer_size;
+       uint16_t cli_buffer_index;
+       int8_t exit_code;
+       uint8_t completion_failed=0;
+       char* cli_buffer;
+       char c;
+       uint16_t maxcmdlength = max_cmd_length(cmd_desc);
+       cli_buffer = calloc(1,cli_buffer_size=maxcmdlength+2);
+       cli_buffer_index=0;
+       if(!cli_rx)
+               return -1;
+       if(cli_tx)
+               cli_tx('>');
+       for(;;){
+               c = cli_rx();
+               switch (c){
+               case CLI_ENTER:
+                       if((exit_code=search_and_call(cli_buffer, maxcmdlength, cmd_desc))<=0){
+                               free(cli_buffer);
+                               return exit_code;
+                       }
+                       memset(cli_buffer, 0, cli_buffer_size);
+                       cli_buffer_index=0;
+                       cli_putstr("\r\n>");
+                       completion_failed=0;
+                       break;
+               case CLI_BACKSPACE:
+                       completion_failed=0;
+                       if(cli_buffer_index==0)
+                               break;
+                       cli_buffer_index--;
+                       cli_buffer[cli_buffer_index] = '\0';
+                       if(cli_echo && cli_tx){
+                               cli_tx(c);
+                       }
+                       break;
+               case CLI_TABULATOR:
+                       if(completion_failed || cli_buffer_index==0){
+                               if(cli_tx)
+                                       cli_option_listing(cli_buffer, cmd_desc);
+                       } else {
+                               uint16_t old_idx = cli_buffer_index;
+                               completion_failed = 
+                                       ~cli_completion(cli_buffer, maxcmdlength, cmd_desc);
+                               cli_buffer_index = strlen(cli_buffer);
+                               if(cli_echo && cli_tx){
+                                       while(old_idx<cli_buffer_index){
+                                               cli_tx(cli_buffer[old_idx++]);
+                                       }
+                               }
+                       }
+                       break;
+               default:
+                       completion_failed=0;
+                       if(cli_echo && cli_tx){
+                               cli_tx(c);
+                       }
+                       if(cli_buffer_index+1==cli_buffer_size){
+                               cli_buffer = realloc(cli_buffer, cli_buffer_size+=CLI_BUFFER_BS);
+                               if(!cli_buffer){
+                                       return -2;
+                               }
+                               memset(cli_buffer+cli_buffer_index+1, 0, CLI_BUFFER_BS);
+                       }
+                       cli_buffer[cli_buffer_index++] = c;
+               }
+       }
+}
+
diff --git a/test_src/cli.h b/test_src/cli.h
new file mode 100644 (file)
index 0000000..5ab9799
--- /dev/null
@@ -0,0 +1,70 @@
+/* cli.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+
+#ifndef CLI_H_
+#define CLI_H_
+
+#include <stdint.h>
+#include "string-extras.h"
+
+#ifndef VOID_FPT
+#define VOID_FPT
+typedef void(*void_fpt)(void);
+#endif
+typedef char (*cli_rx_fpt)(void);
+typedef void (*cli_tx_fpt)(char);
+
+#define CLI_BUFFER_BS 20
+#define CMDLIST_ENTRY_SIZE 16
+
+typedef struct {
+       uint16_t   option_flags;
+       void      *options[];
+} cmdoption_t;
+
+#define CLI_OPTION_DESC 0x01
+#define CLI_OPTION_MANP 0x02
+
+typedef struct {
+       const char*  cmd_name;      /* string containing the function name */
+       const char*  cmd_param_str; /* param descriptor string */
+       void_fpt     cmd_function;  /* function pointer */
+       cmdoption_t* options;
+} cmdlist_entry_t;
+
+extern cli_rx_fpt cli_rx;
+extern cli_tx_fpt cli_tx;
+extern uint8_t cli_echo;
+
+
+void cli_putc(char c);
+uint16_t cli_getc(void);
+uint16_t cli_getc_cecho(void);
+uint8_t cli_getsn(char* s, uint32_t n);
+void cli_putstr(const char* s);
+void cli_hexdump(const void* data, uint32_t length);
+void cli_hexdump_rev(const void* data, uint32_t length);
+void cli_hexdump2(const void* data, uint32_t length);
+void cli_hexdump_block(const void* data, uint32_t length, uint8_t indent, uint8_t width);
+
+void echo_ctrl(char* s);
+int8_t cmd_interface(const cmdlist_entry_t* cmd_desc);
+
+
+#endif /*CLI_H_*/
diff --git a/test_src/config.h b/test_src/config.h
new file mode 100644 (file)
index 0000000..853f359
--- /dev/null
@@ -0,0 +1,44 @@
+/* config.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+// #define F_CPU 20000000
+// #define F_CPU 16000000         /* oscillator-frequency in Hz */
+// #define F_CPU 14745600
+#define F_CPU 20000000 /* this is out of spec but lets try it */
+
+#define DEBUG_METHOD uart
+
+#include "uart_defines.h"
+
+#define UART0_I 1
+#define UART0_BAUD_RATE  115200
+#define UART0_PARATY     UART_PARATY_NONE
+#define UART0_STOPBITS   UART_STOPBITS_ONE
+#define UART0_DATABITS   UART_DATABITS_8
+#define UART0_RXBUFFER_SIZE 120
+#define UART0_TXBUFFER_SIZE 120
+#define UART0_SWFLOWCTRL     1
+#define UART0_THRESH_LOW     0
+#define UART0_THRESH_HIGH   32
+
+#define CLI_AUTO_HELP
+
+#endif
+
diff --git a/test_src/dbz_strings.c b/test_src/dbz_strings.c
new file mode 100644 (file)
index 0000000..2004544
--- /dev/null
@@ -0,0 +1,64 @@
+/* dbz_strings.c */
+/*
+ *   This file is part of AnonAccess, an access system which can be used
+ *    to open door or doing other things with an anonymity featured
+ *    account managment.
+ *   Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+ *
+ *   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/>.
+ */
+
+
+/*
+ * author: Daniel Otte
+ * email:  daniel.otte@rub.de
+ * license: GPLv3
+ * 
+ * */
+
+#include <stdint.h>
+#include <string.h>
+/******************************************************************************/
+
+uint8_t dbz_strcount(const char* str){
+       uint8_t ret=1;
+       if(*str=='\0' && *(str+1)=='\0')
+                       return 0;
+       for(;;){
+               while(*str++)
+                       ;
+               if(*str=='\0')
+                       return ret;
+               ++ret;
+       }       
+}
+
+/******************************************************************************/
+
+void dbz_splitup(char* dbzstr, char** strings){
+       if(*dbzstr=='\0' && *(dbzstr+1)=='\0')
+               return;
+       *strings++ = dbzstr;
+       for(;;){        
+               while(*dbzstr++)
+                       ;
+               if(*dbzstr=='\0')
+                       return;
+               *strings++ = dbzstr;
+       }
+}
+
+/******************************************************************************/
+
diff --git a/test_src/dbz_strings.h b/test_src/dbz_strings.h
new file mode 100644 (file)
index 0000000..a6f73ed
--- /dev/null
@@ -0,0 +1,55 @@
+/* dbz_strings.h */
+/*
+ *   This file is part of AnonAccess, an access system which can be used
+ *    to open door or doing other things with an anonymity featured
+ *    account managment.
+ *   Copyright (C) 2006, 2007, 2008, 2009  Daniel Otte (daniel.otte@rub.de)
+ *
+ *   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/>.
+ */
+
+
+#ifndef DBZ_STRINGS_H_
+#define DBZ_STRINGS_H_
+
+/** \file dbz_strings.h
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \license GPLv3 or later
+ * \brief functions for handling of double-zero-terminated strings
+ * 
+ */
+
+#include <stdint.h>
+
+/** \fn uint8_t dbz_strcount(const char* str)
+ * \brief count stings in dbz-terminated string
+ * 
+ * Count the single zero terminated strings in a 
+ * double terminated string
+ * \param str pointer to the double-zero-terminated string
+ */
+uint8_t dbz_strcount(const char* str);
+
+/** \fn void dbz_splitup(char* dbzstr, char** strings)
+ * \brief split up a dbz-terminated string
+ * 
+ * Fills an array with pointers to the single terminated string
+ * in a double-zero-terminated string
+ * \param dbzstr pointer to the double-zero-terminated string
+ * \param strings pointer to the array of strings (char pointers)
+ */
+void dbz_splitup(char* dbzstr, char** strings);
+
+#endif /*DBZ_STRINGS_H_*/
diff --git a/test_src/dump-decl.c b/test_src/dump-decl.c
new file mode 100644 (file)
index 0000000..d7e7d3e
--- /dev/null
@@ -0,0 +1,64 @@
+/* dump.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     dump.c
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-02-04
+ * \license  GPLv3 or later
+ * 
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>                                    
+#include <ctype.h>
+#include <avr/pgmspace.h>
+#include <avr/eeprom.h>
+#include "cli.h" 
+#include "string-extras.h" 
+#define DUMP_WIDTH 16
+
+void pgm_read_block(void* buffer, uint32_t addr, uint8_t length);
+void ee_read_block(void* buffer, uint32_t addr, uint8_t length);
+void ram_read_block(void* buffer, uint32_t addr, uint8_t length);
+
+const char flash_trigger[]  PROGMEM = "fF";
+const char ram_trigger[]    PROGMEM = "sSrRmM";
+const char eeprom_trigger[] PROGMEM = "eE";
+
+const char flash_desc[]  PROGMEM = "flash";
+const char ram_desc[]    PROGMEM = "ram";
+const char eeprom_desc[] PROGMEM = "eeprom";
+
+typedef struct {
+       PGM_P trigger;
+       PGM_P desc;
+       void (*fpt)(void*, uint32_t, uint8_t);
+} memtype_desc_t;
+
+memtype_desc_t memtype_desc[] PROGMEM = {
+       { flash_trigger,   flash_desc,      pgm_read_block },
+       { eeprom_trigger,  eeprom_desc,     ee_read_block  },
+       { ram_trigger,     ram_desc   ,     ram_read_block },
+       { NULL,            NULL,            NULL        }
+};
+
+void dump(char* s);
diff --git a/test_src/dump.c b/test_src/dump.c
new file mode 100644 (file)
index 0000000..988bc87
--- /dev/null
@@ -0,0 +1,110 @@
+/* dump.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     dump.c
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-02-04
+ * \license  GPLv3 or later
+ * 
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>                                    
+#include <ctype.h>
+#include "cli.h" 
+#include "string-extras.h" 
+#define DUMP_WIDTH 16
+
+static
+void dump_chars(uint8_t* buffer, uint8_t len){
+       uint8_t i;
+       cli_putc('|');
+       for(i=0; i<len; ++i){
+               if(isprint(buffer[i])){
+                       cli_putc(buffer[i]);
+               }else{
+                       cli_putc('.');
+               }
+       }
+       for(;len<DUMP_WIDTH; ++len){
+               cli_putc(' ');
+       }
+       cli_putc('|');
+}
+
+static 
+void print_aligned(unsigned long value, uint8_t align){
+       char str[10];
+       uint8_t i;
+       ultoa(value, str, 16);
+       for(i=strlen(str);i<align;++i)
+               cli_putc(' ');
+       cli_putstr(str);
+}
+
+
+void dump(char* s){
+       uint8_t readlen;
+       uint32_t addr=0;
+       uint32_t size=32;
+       uint8_t buffer[DUMP_WIDTH];
+       char tstr[9];
+       if(s){
+               s=strstrip(s);
+               if(isalpha(*s)){
+                       while(isalpha(*s))
+                               ++s;
+               }
+               char* eptr;
+               if(*s)
+                       addr = strtoul(s, &eptr, 0);
+               if(eptr)
+                       size = strtoul(eptr, NULL, 0);
+               if(!size)
+                       size = 32;
+       }
+       cli_putstr("\r\ndumping ");
+       ultoa(size, tstr, 10);
+       cli_putstr(tstr);
+       cli_putstr(" bytes, beginning at 0x");
+       ultoa(addr, tstr, 16);
+       cli_putstr(tstr);
+       cli_putstr(":\r\n");
+       uint8_t t;
+       while(size){
+               readlen = (size>DUMP_WIDTH)?DUMP_WIDTH:size;
+               memcpy(buffer, (void*)addr, readlen);
+               print_aligned(addr, 6);
+               cli_putstr(": ");
+               cli_hexdump2(buffer, readlen);
+               t=(DUMP_WIDTH-readlen)*3;
+               while(t--){
+                       cli_putc(' ');
+               }
+               cli_putc('\t');
+               dump_chars(buffer,readlen);
+               addr+=readlen;
+               size-=readlen;
+               cli_putstr("\r\n");
+       }
+}
+
diff --git a/test_src/dump.h b/test_src/dump.h
new file mode 100644 (file)
index 0000000..ceee1fa
--- /dev/null
@@ -0,0 +1,35 @@
+/* dump.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     dump.h
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-02-04
+ * \license  GPLv3 or later
+ * 
+ */
+
+#ifndef DUMP_H_
+#define DUMP_H_
+
+#define DUMP_WIDTH 16
+
+void dump(char* s);
+
+#endif /* DUMP_H_ */
diff --git a/test_src/hexdigit_tab.S b/test_src/hexdigit_tab.S
new file mode 100644 (file)
index 0000000..ca54b4f
--- /dev/null
@@ -0,0 +1,42 @@
+/* hexdigit_tab.S */
+/*
+ *   This file is part of AnonAccess, an access system which can be used
+ *    to open door or doing other things with an anonymity featured
+ *    account managment.
+ *   Copyright (C) 2006, 2007, 2008  Daniel Otte (daniel.otte@rub.de)
+ *
+ *   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/>.
+ */
+.global hexdigit_tab
+hexdigit_tab:
+.global hexdigit_tab_uc
+hexdigit_tab_uc:
+.byte '0','1','2','3'
+.byte '4','5','6','7'
+.byte '8','9','A','B'
+.byte 'C','D','E','F'
+
+.global hexdigit_tab_lc
+hexdigit_tab_lc:
+.byte '0','1','2','3'
+.byte '4','5','6','7'
+.byte '8','9','a','b'
+.byte 'c','d','e','f'
+
+
+
+
+
+
diff --git a/test_src/hexdigit_tab.h b/test_src/hexdigit_tab.h
new file mode 100644 (file)
index 0000000..265ea6d
--- /dev/null
@@ -0,0 +1,29 @@
+/* hexdigit_tab.h */
+/*
+ *   This file is part of AnonAccess, an access system which can be used
+ *    to open door or doing other things with an anonymity featured
+ *    account managment.
+ *   Copyright (C) 2006, 2007, 2008  Daniel Otte (daniel.otte@rub.de)
+ *
+ *   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/>.
+ */
+
+
+#ifndef HEXDIGIT_TAB_H_
+#define HEXDIGIT_TAB_H_
+
+extern char hexdigit_tab[];
+extern char hexdigit_tab_uc[]; 
+extern char hexdigit_tab_lc[];
+#endif /*HEXDIGIT_TAB_H_*/
diff --git a/test_src/hexdigit_tab_c.c b/test_src/hexdigit_tab_c.c
new file mode 100644 (file)
index 0000000..6b6e4a6
--- /dev/null
@@ -0,0 +1,49 @@
+/* hexdigit_tab.c */
+/*
+ *   This file is part of AnonAccess, an access system which can be used
+ *    to open door or doing other things with an anonymity featured
+ *    account managment.
+ *   Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+ *
+ *   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 <avr/pgmspace.h>
+#include "hexdigit_tab.h"
+
+char hexdigit_tab_P[] PROGMEM = 
+                              {'0','1','2','3',
+                               '4','5','6','7',
+                               '8','9','A','B',
+                               'C','D','E','F'};
+
+char hexdigit_tab_uc_P[] PROGMEM = 
+                              {'0','1','2','3',
+                               '4','5','6','7',
+                               '8','9','A','B',
+                               'C','D','E','F'};
+
+
+char hexdigit_tab_lc_P[] PROGMEM = 
+                              {'0','1','2','3',
+                               '4','5','6','7',
+                               '8','9','a','b',
+                               'c','d','e','f'};
+
+
+
+
+
diff --git a/test_src/hw_gptm.c b/test_src/hw_gptm.c
new file mode 100644 (file)
index 0000000..d163613
--- /dev/null
@@ -0,0 +1,105 @@
+/* hw_gptm.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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 <stdint.h>
+#include "hw_regs.h"
+#include "hw_gptm.h"
+
+static const
+uint32_t timer_base[] = { TIMER0_BASE, TIMER1_BASE, TIMER2_BASE, TIMER3_BASE };
+
+uint32_t gptm_read_timer(uint8_t timerno, uint8_t b){
+       if(timerno>3){
+               return 0;
+       }
+       return HW_REG(timer_base[timerno]+(b?GPTM_TBV_OFFSET:GPTM_TAV_OFFSET));
+}
+
+void gptm_write_timer(uint8_t timerno, uint8_t b, uint32_t value){
+       if(timerno>3){
+               return;
+       }
+       HW_REG(timer_base[timerno]+(b?GPTM_TBV_OFFSET:GPTM_TAV_OFFSET)) = value;
+}
+
+void gptm_start_timer(uint8_t timerno, uint8_t b){
+       if(timerno>3){
+               return;
+       }
+       HW_REG(timer_base[timerno]+GPTM_CTL_OFFSET) |= _BV(b?GPTM_TBEN:GPTM_TAEN);
+}
+
+void gptm_stop_timer(uint8_t timerno, uint8_t b){
+       if(timerno>3){
+               return;
+       }
+       HW_REG(timer_base[timerno]+GPTM_CTL_OFFSET) &= ~_BV(b?GPTM_TBEN:GPTM_TAEN);
+}
+
+void gptm_set_timer_prescaler(uint8_t timerno, uint8_t b, uint8_t prescaler){
+       if(timerno>3){
+               return;
+       }
+       HW_REG(timer_base[timerno]+(b?GPTM_TBPR_OFFSET:GPTM_TAPR_OFFSET)) =
+                       prescaler;
+}
+
+void gptm_set_timer_loadvalue(uint8_t timerno, uint8_t b, uint32_t value){
+       if(timerno>3){
+               return;
+       }
+       HW_REG(timer_base[timerno]+(b?GPTM_TBILR_OFFSET:GPTM_TAILR_OFFSET)) =
+                       value;
+}
+
+void gptm_set_timer_mode(uint8_t timerno, uint8_t b, uint8_t mode){
+       if(timerno>3){
+               return;
+       }
+       uint32_t tmp;
+       tmp = HW_REG(timer_base[timerno]+(b?GPTM_TBMR_OFFSET:GPTM_TAMR_OFFSET));
+       tmp &= ~3;
+       tmp |= mode;
+       HW_REG(timer_base[timerno]+(b?GPTM_TBMR_OFFSET:GPTM_TAMR_OFFSET)) = tmp;
+}
+
+uint8_t gptm_get_timer_running(uint8_t timerno, uint8_t b){
+       if(timerno>3){
+               return 0;
+       }
+       return (HW_REG(timer_base[timerno]+GPTM_CTL_OFFSET)>>(b?GPTM_TBEN:GPTM_TAEN))&1;
+}
+
+
+void gptm_set_timer_32periodic(uint8_t timerno){
+       if(timerno>3){
+               return;
+       }
+       volatile uint8_t i;
+       HW_REG(SYSCTL_BASE+RCGC1_OFFSET) |= _BV(16+timerno);
+       for(i=8; i>0; --i)
+               ;
+       gptm_stop_timer(timerno, 0);
+       HW_REG(timer_base[timerno]+GPTM_CTL_OFFSET) = 0;
+       gptm_set_timer_mode(timerno, 0, GPTM_MODE_PERIODIC);
+       HW_REG(timer_base[timerno]+GPTM_TAMR_OFFSET) |= _BV(4);
+       gptm_set_timer_loadvalue(timerno, 0, 0xffffffff);
+}
+
+
diff --git a/test_src/hw_gptm.h b/test_src/hw_gptm.h
new file mode 100644 (file)
index 0000000..115d887
--- /dev/null
@@ -0,0 +1,83 @@
+/* hw_gpt.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+
+#ifndef HW_GPT_H_
+#define HW_GPT_H_
+
+#define TIMER0 0
+#define TIMER1 1
+#define TIMER2 2
+#define TIMER3 3
+
+
+#define TIMER0_BASE 0x40030000
+#define TIMER1_BASE 0x40031000
+#define TIMER2_BASE 0x40032000
+#define TIMER3_BASE 0x40033000
+
+#define GPTM_CFG_OFFSET            0x000
+#define GPTM_TAMR_OFFSET           0x004
+#define GPTM_TBMR_OFFSET           0x008
+#define GPTM_CTL_OFFSET            0x00C
+#define GPTM_IMR_OFFSET            0x018
+#define GPTM_RIS_OFFSET            0x01C
+#define GPTM_MIS_OFFSET            0x020
+#define GPTM_ICR_OFFSET            0x024
+#define GPTM_TAILR_OFFSET          0x028
+#define GPTM_TBILR_OFFSET          0x02C
+#define GPTM_TAMATCHR_OFFSET       0x030
+#define GPTM_TBMATCHR_OFFSET       0x034
+#define GPTM_TAPR_OFFSET           0x038
+#define GPTM_TBPR_OFFSET           0x03C
+#define GPTM_TAR_OFFSET            0x048
+#define GPTM_TBR_OFFSET            0x04C
+#define GPTM_TAV_OFFSET            0x050
+#define GPTM_TBV_OFFSET            0x054
+
+#define GPTM_TAEN       0
+#define GPTM_TASTALL    1
+#define GPTM_TAEVENT    2
+#define GPTM_RTCEN      4
+#define GPTM_TAOTE      5
+#define GPTM_TAPWML     6
+#define GPTM_TBEN       8
+#define GPTM_TBSTALL    9
+#define GPTM_TBEVENT   10
+#define GPTM_TBOTE     13
+#define GPTM_TBPWML    14
+
+#define GPTM_MODE_ONESHOT  1
+#define GPTM_MODE_PERIODIC 2
+#define GPTM_MODE_CAPTURE  3
+
+
+
+uint32_t gptm_read_timer(uint8_t timerno, uint8_t b);
+void gptm_write_timer(uint8_t timerno, uint8_t b, uint32_t value);
+void gptm_start_timer(uint8_t timerno, uint8_t b);
+void gptm_stop_timer(uint8_t timerno, uint8_t b);
+void gptm_set_timer_prescaler(uint8_t timerno, uint8_t b, uint8_t prescaler);
+void gptm_set_timer_loadvalue(uint8_t timerno, uint8_t b, uint32_t value);
+void gptm_set_timer_mode(uint8_t timerno, uint8_t b, uint8_t mode);
+uint8_t gptm_get_timer_running(uint8_t timerno, uint8_t b);
+void gptm_set_timer_32periodic(uint8_t timerno);
+
+
+
+#endif /* HW_GPT_H_ */
diff --git a/test_src/hw_regs.h b/test_src/hw_regs.h
new file mode 100644 (file)
index 0000000..bcf9100
--- /dev/null
@@ -0,0 +1,153 @@
+/* hw_regs.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+
+#ifndef HW_REGS_H_
+#define HW_REGS_H_
+
+#include <stdint.h>
+
+#define SET_REG(r,v) (*((volatile uint32_t*)(r))) = (v)
+#define GET_REG(r)   (*((volatile uint32_t*)(r)))
+#define HW_REG(r)    (*((volatile uint32_t*)(r)))
+#define _BV(x)       (1<<(x))
+
+#define SYSCTL_BASE 0x400FE000
+#define DID0_OFFSET           0x000
+#define DID1_OFFSET           0x004
+#define DC0_OFFSET            0x008
+#define DC1_OFFSET            0x010
+#define DC2_OFFSET            0x014
+#define DC3_OFFSET            0x018
+#define DC4_OFFSET            0x01C
+#define DC5_OFFSET            0x020
+#define DC6_OFFSET            0x024
+#define DC7_OFFSET            0x028
+#define DC8_OFFSET            0x02C
+#define PBORCTL_OFFSET        0x030
+#define SRCR0_OFFSET          0x040
+#define SRCR1_OFFSET          0x044
+#define SRCR2_OFFSET          0x048
+#define RIS_OFFSET            0x050
+#define IMC_OFFSET            0x054
+#define MISC_OFFSET           0x058
+#define RESC_OFFSET           0x05C
+#define RCC_OFFSET            0x060
+#define PLLCFG_OFFSET         0x064
+#define GPIOHBCTL_OFFSET      0x06C
+#define RCC2_OFFSET           0x070
+#define MOSCCTL_OFFSET        0x07C
+#define RCGC0_OFFSET          0x100
+#define RCGC1_OFFSET          0x104
+#define RCGC2_OFFSET          0x108
+#define SCGC0_OFFSET          0x110
+#define SCGC1_OFFSET          0x114
+#define SCGC2_OFFSET          0x118
+#define DCGC0_OFFSET          0x120
+#define DCGC1_OFFSET          0x124
+#define DCGC2_OFFSET          0x128
+#define DSLPCLKCFG_OFFSET     0x144
+#define PIOSCCAL_OFFSET       0x150
+#define PIOSCSTAT_OFFSET      0x154
+#define I2SMCLKCFG_OFFSET     0x170
+#define DC9_OFFSET            0x190
+#define NVMSTAT_OFFSET        0x1A0
+
+#define RCC_ACG       27
+#define RCC_SYSDIV    23
+#define RCC_USESYSDIV 22
+#define RCC_PWRDN     13
+#define RCC_BYPASS    11
+#define RCC_XTAL       6
+#define RCC_OSCSRC     4
+#define RCC_IOSCDIS    1
+#define RCC_MOSCDIS    0
+
+#define RCC2_USERCC2     31
+#define RCC2_DIV400      30
+#define RCC2_SYSDIV2     23
+#define RCC2_SYSDIV2LSB  22
+#define RCC2_USBPWRDN    14
+#define RCC2_PWRDN2      13
+#define RCC2_BYPASS2     11
+#define RCC2_OSCSR2       4
+
+#define RIS_MOSCPUPRIS   8
+#define RIS_USBPLLLRIS   7
+#define RIS_PLLLRIS      6
+#define RIS BORRIS       1
+
+#define GPIOA  0
+#define GPIOB  1
+#define GPIOC  2
+#define GPIOD  3
+#define GPIOE  4
+#define GPIOF  5
+#define GPIOG  6
+#define GPIOH  7
+#define GPIOJ  8
+
+#define GPIOA_BASE  0x40004000
+#define GPIOB_BASE  0x40005000
+#define GPIOC_BASE  0x40006000
+#define GPIOD_BASE  0x40007000
+#define GPIOE_BASE  0x40024000
+#define GPIOF_BASE  0x40025000
+#define GPIOG_BASE  0x40026000
+#define GPIOH_BASE  0x40027000
+#define GPIOJ_BASE  0x4003D000
+
+#define GPIO_DATA_OFFSET         0x000
+#define GPIO_DIR_OFFSET          0x400
+#define GPIO_IS_OFFSET           0x404
+#define GPIO_IBE_OFFSET          0x408
+#define GPIO_IEV_OFFSET          0x40C
+#define GPIO_IM_OFFSET           0x410
+#define GPIO_RIS_OFFSET          0x414
+#define GPIO_MIS_OFFSET          0x418
+#define GPIO_ICR_OFFSET          0x41C
+#define GPIO_AFSEL_OFFSET        0x420
+#define GPIO_DR2R_OFFSET         0x500
+#define GPIO_DR4R_OFFSET         0x504
+#define GPIO_DR8R_OFFSET         0x508
+#define GPIO_ODR_OFFSET          0x50C
+#define GPIO_PUR_OFFSET          0x510
+#define GPIO_PDR_OFFSET          0x514
+#define GPIO_SLR_OFFSET          0x518
+#define GPIO_DEN_OFFSET          0x51C
+#define GPIO_LOCK_OFFSET         0x520
+#define GPIO_CR_OFFSET           0x524
+#define GPIO_AMSEL_OFFSET        0x528
+#define GPIO_PCTL_OFFSET         0x52C
+#define GPIO_PeriphID4_OFFSET    0xFD0
+#define GPIO_PeriphID5_OFFSET    0xFD4
+#define GPIO_PeriphID6_OFFSET    0xFD8
+#define GPIO_PeriphID7_OFFSET    0xFDC
+#define GPIO_PeriphID0_OFFSET    0xFE0
+#define GPIO_PeriphID1_OFFSET    0xFE4
+#define GPIO_PeriphID2_OFFSET    0xFE8
+#define GPIO_PeriphID3_OFFSET    0xFEC
+#define GPIO_PCellID0_OFFSET     0xFF0
+#define GPIO_PCellID1_OFFSET     0xFF4
+#define GPIO_PCellID2_OFFSET     0xFF8
+#define GPIO_PCellID3_OFFSET     0xFFC
+
+
+#define ISR_ENABLE_VECTOR    0xE000E100
+
+#endif /* HW_REGS_H_ */
diff --git a/test_src/hw_uart.h b/test_src/hw_uart.h
new file mode 100644 (file)
index 0000000..43cfe59
--- /dev/null
@@ -0,0 +1,458 @@
+//*****************************************************************************\r
+//\r
+// hw_uart.h - Macros and defines used when accessing the UART hardware.\r
+//\r
+// Copyright (c) 2005-2010 Texas Instruments Incorporated.  All rights reserved.\r
+// Software License Agreement\r
+// \r
+// Texas Instruments (TI) is supplying this software for use solely and\r
+// exclusively on TI's microcontroller products. The software is owned by\r
+// TI and/or its suppliers, and is protected under applicable copyright\r
+// laws. You may not combine this software with "viral" open-source\r
+// software in order to form a larger program.\r
+// \r
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.\r
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT\r
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY\r
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL\r
+// DAMAGES, FOR ANY REASON WHATSOEVER.\r
+// \r
+// This is part of revision 5821 of the Stellaris Firmware Development Package.\r
+//\r
+//*****************************************************************************\r
+\r
+#ifndef __HW_UART_H__\r
+#define __HW_UART_H__\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are defines for the UART register offsets.\r
+//\r
+//*****************************************************************************\r
+#define UART_O_DR               0x00000000  // UART Data\r
+#define UART_O_RSR              0x00000004  // UART Receive Status/Error Clear\r
+#define UART_O_ECR              0x00000004  // UART Receive Status/Error Clear\r
+#define UART_O_FR               0x00000018  // UART Flag\r
+#define UART_O_ILPR             0x00000020  // UART IrDA Low-Power Register\r
+#define UART_O_IBRD             0x00000024  // UART Integer Baud-Rate Divisor\r
+#define UART_O_FBRD             0x00000028  // UART Fractional Baud-Rate\r
+                                            // Divisor\r
+#define UART_O_LCRH             0x0000002C  // UART Line Control\r
+#define UART_O_CTL              0x00000030  // UART Control\r
+#define UART_O_IFLS             0x00000034  // UART Interrupt FIFO Level Select\r
+#define UART_O_IM               0x00000038  // UART Interrupt Mask\r
+#define UART_O_RIS              0x0000003C  // UART Raw Interrupt Status\r
+#define UART_O_MIS              0x00000040  // UART Masked Interrupt Status\r
+#define UART_O_ICR              0x00000044  // UART Interrupt Clear\r
+#define UART_O_DMACTL           0x00000048  // UART DMA Control\r
+#define UART_O_LCTL             0x00000090  // UART LIN Control\r
+#define UART_O_LSS              0x00000094  // UART LIN Snap Shot\r
+#define UART_O_LTIM             0x00000098  // UART LIN Timer\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are defines for the bit fields in the UART_O_DR register.\r
+//\r
+//*****************************************************************************\r
+#define UART_DR_OE              0x00000800  // UART Overrun Error\r
+#define UART_DR_BE              0x00000400  // UART Break Error\r
+#define UART_DR_PE              0x00000200  // UART Parity Error\r
+#define UART_DR_FE              0x00000100  // UART Framing Error\r
+#define UART_DR_DATA_M          0x000000FF  // Data Transmitted or Received\r
+#define UART_DR_DATA_S          0\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are defines for the bit fields in the UART_O_RSR register.\r
+//\r
+//*****************************************************************************\r
+#define UART_RSR_OE             0x00000008  // UART Overrun Error\r
+#define UART_RSR_BE             0x00000004  // UART Break Error\r
+#define UART_RSR_PE             0x00000002  // UART Parity Error\r
+#define UART_RSR_FE             0x00000001  // UART Framing Error\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are defines for the bit fields in the UART_O_ECR register.\r
+//\r
+//*****************************************************************************\r
+#define UART_ECR_DATA_M         0x000000FF  // Error Clear\r
+#define UART_ECR_DATA_S         0\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are defines for the bit fields in the UART_O_FR register.\r
+//\r
+//*****************************************************************************\r
+#define UART_FR_RI              0x00000100  // Ring Indicator\r
+#define UART_FR_TXFE            0x00000080  // UART Transmit FIFO Empty\r
+#define UART_FR_RXFF            0x00000040  // UART Receive FIFO Full\r
+#define UART_FR_TXFF            0x00000020  // UART Transmit FIFO Full\r
+#define UART_FR_RXFE            0x00000010  // UART Receive FIFO Empty\r
+#define UART_FR_BUSY            0x00000008  // UART Busy\r
+#define UART_FR_DCD             0x00000004  // Data Carrier Detect\r
+#define UART_FR_DSR             0x00000002  // Data Set Ready\r
+#define UART_FR_CTS             0x00000001  // Clear To Send\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are defines for the bit fields in the UART_O_ILPR register.\r
+//\r
+//*****************************************************************************\r
+#define UART_ILPR_ILPDVSR_M     0x000000FF  // IrDA Low-Power Divisor\r
+#define UART_ILPR_ILPDVSR_S     0\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are defines for the bit fields in the UART_O_IBRD register.\r
+//\r
+//*****************************************************************************\r
+#define UART_IBRD_DIVINT_M      0x0000FFFF  // Integer Baud-Rate Divisor\r
+#define UART_IBRD_DIVINT_S      0\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are defines for the bit fields in the UART_O_FBRD register.\r
+//\r
+//*****************************************************************************\r
+#define UART_FBRD_DIVFRAC_M     0x0000003F  // Fractional Baud-Rate Divisor\r
+#define UART_FBRD_DIVFRAC_S     0\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are defines for the bit fields in the UART_O_LCRH register.\r
+//\r
+//*****************************************************************************\r
+#define UART_LCRH_SPS           0x00000080  // UART Stick Parity Select\r
+#define UART_LCRH_WLEN_M        0x00000060  // UART Word Length\r
+#define UART_LCRH_WLEN_5        0x00000000  // 5 bits (default)\r
+#define UART_LCRH_WLEN_6        0x00000020  // 6 bits\r
+#define UART_LCRH_WLEN_7        0x00000040  // 7 bits\r
+#define UART_LCRH_WLEN_8        0x00000060  // 8 bits\r
+#define UART_LCRH_FEN           0x00000010  // UART Enable FIFOs\r
+#define UART_LCRH_STP2          0x00000008  // UART Two Stop Bits Select\r
+#define UART_LCRH_EPS           0x00000004  // UART Even Parity Select\r
+#define UART_LCRH_PEN           0x00000002  // UART Parity Enable\r
+#define UART_LCRH_BRK           0x00000001  // UART Send Break\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are defines for the bit fields in the UART_O_CTL register.\r
+//\r
+//*****************************************************************************\r
+#define UART_CTL_CTSEN          0x00008000  // Enable Clear To Send\r
+#define UART_CTL_RTSEN          0x00004000  // Enable Request to Send\r
+#define UART_CTL_RTS            0x00000800  // Request to Send\r
+#define UART_CTL_DTR            0x00000400  // Data Terminal Ready\r
+#define UART_CTL_RXE            0x00000200  // UART Receive Enable\r
+#define UART_CTL_TXE            0x00000100  // UART Transmit Enable\r
+#define UART_CTL_LBE            0x00000080  // UART Loop Back Enable\r
+#define UART_CTL_LIN            0x00000040  // LIN Mode Enable\r
+#define UART_CTL_HSE            0x00000020  // High-Speed Enable\r
+#define UART_CTL_EOT            0x00000010  // End of Transmission\r
+#define UART_CTL_SMART          0x00000008  // ISO 7816 Smart Card Support\r
+#define UART_CTL_SIRLP          0x00000004  // UART SIR Low-Power Mode\r
+#define UART_CTL_SIREN          0x00000002  // UART SIR Enable\r
+#define UART_CTL_UARTEN         0x00000001  // UART Enable\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are defines for the bit fields in the UART_O_IFLS register.\r
+//\r
+//*****************************************************************************\r
+#define UART_IFLS_RX_M          0x00000038  // UART Receive Interrupt FIFO\r
+                                            // Level Select\r
+#define UART_IFLS_RX1_8         0x00000000  // RX FIFO >= 1/8 full\r
+#define UART_IFLS_RX2_8         0x00000008  // RX FIFO >= 1/4 full\r
+#define UART_IFLS_RX4_8         0x00000010  // RX FIFO >= 1/2 full (default)\r
+#define UART_IFLS_RX6_8         0x00000018  // RX FIFO >= 3/4 full\r
+#define UART_IFLS_RX7_8         0x00000020  // RX FIFO >= 7/8 full\r
+#define UART_IFLS_TX_M          0x00000007  // UART Transmit Interrupt FIFO\r
+                                            // Level Select\r
+#define UART_IFLS_TX1_8         0x00000000  // TX FIFO <= 1/8 full\r
+#define UART_IFLS_TX2_8         0x00000001  // TX FIFO <= 1/4 full\r
+#define UART_IFLS_TX4_8         0x00000002  // TX FIFO <= 1/2 full (default)\r
+#define UART_IFLS_TX6_8         0x00000003  // TX FIFO <= 3/4 full\r
+#define UART_IFLS_TX7_8         0x00000004  // TX FIFO <= 7/8 full\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are defines for the bit fields in the UART_O_IM register.\r
+//\r
+//*****************************************************************************\r
+#define UART_IM_LME5IM          0x00008000  // LIN Mode Edge 5 Interrupt Mask\r
+#define UART_IM_LME1IM          0x00004000  // LIN Mode Edge 1 Interrupt Mask\r
+#define UART_IM_LMSBIM          0x00002000  // LIN Mode Sync Break Interrupt\r
+                                            // Mask\r
+#define UART_IM_OEIM            0x00000400  // UART Overrun Error Interrupt\r
+                                            // Mask\r
+#define UART_IM_BEIM            0x00000200  // UART Break Error Interrupt Mask\r
+#define UART_IM_PEIM            0x00000100  // UART Parity Error Interrupt Mask\r
+#define UART_IM_FEIM            0x00000080  // UART Framing Error Interrupt\r
+                                            // Mask\r
+#define UART_IM_RTIM            0x00000040  // UART Receive Time-Out Interrupt\r
+                                            // Mask\r
+#define UART_IM_TXIM            0x00000020  // UART Transmit Interrupt Mask\r
+#define UART_IM_RXIM            0x00000010  // UART Receive Interrupt Mask\r
+#define UART_IM_DSRMIM          0x00000008  // UART Data Set Ready Modem\r
+                                            // Interrupt Mask\r
+#define UART_IM_DCDMIM          0x00000004  // UART Data Carrier Detect Modem\r
+                                            // Interrupt Mask\r
+#define UART_IM_CTSMIM          0x00000002  // UART Clear to Send Modem\r
+                                            // Interrupt Mask\r
+#define UART_IM_RIMIM           0x00000001  // UART Ring Indicator Modem\r
+                                            // Interrupt Mask\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are defines for the bit fields in the UART_O_RIS register.\r
+//\r
+//*****************************************************************************\r
+#define UART_RIS_LME5RIS        0x00008000  // LIN Mode Edge 5 Raw Interrupt\r
+                                            // Status\r
+#define UART_RIS_LME1RIS        0x00004000  // LIN Mode Edge 1 Raw Interrupt\r
+                                            // Status\r
+#define UART_RIS_LMSBRIS        0x00002000  // LIN Mode Sync Break Raw\r
+                                            // Interrupt Status\r
+#define UART_RIS_OERIS          0x00000400  // UART Overrun Error Raw Interrupt\r
+                                            // Status\r
+#define UART_RIS_BERIS          0x00000200  // UART Break Error Raw Interrupt\r
+                                            // Status\r
+#define UART_RIS_PERIS          0x00000100  // UART Parity Error Raw Interrupt\r
+                                            // Status\r
+#define UART_RIS_FERIS          0x00000080  // UART Framing Error Raw Interrupt\r
+                                            // Status\r
+#define UART_RIS_RTRIS          0x00000040  // UART Receive Time-Out Raw\r
+                                            // Interrupt Status\r
+#define UART_RIS_TXRIS          0x00000020  // UART Transmit Raw Interrupt\r
+                                            // Status\r
+#define UART_RIS_RXRIS          0x00000010  // UART Receive Raw Interrupt\r
+                                            // Status\r
+#define UART_RIS_DSRRIS         0x00000008  // UART Data Set Ready Modem Raw\r
+                                            // Interrupt Status\r
+#define UART_RIS_DCDRIS         0x00000004  // UART Data Carrier Detect Modem\r
+                                            // Raw Interrupt Status\r
+#define UART_RIS_CTSRIS         0x00000002  // UART Clear to Send Modem Raw\r
+                                            // Interrupt Status\r
+#define UART_RIS_RIRIS          0x00000001  // UART Ring Indicator Modem Raw\r
+                                            // Interrupt Status\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are defines for the bit fields in the UART_O_MIS register.\r
+//\r
+//*****************************************************************************\r
+#define UART_MIS_LME5MIS        0x00008000  // LIN Mode Edge 5 Masked Interrupt\r
+                                            // Status\r
+#define UART_MIS_LME1MIS        0x00004000  // LIN Mode Edge 1 Masked Interrupt\r
+                                            // Status\r
+#define UART_MIS_LMSBMIS        0x00002000  // LIN Mode Sync Break Masked\r
+                                            // Interrupt Status\r
+#define UART_MIS_OEMIS          0x00000400  // UART Overrun Error Masked\r
+                                            // Interrupt Status\r
+#define UART_MIS_BEMIS          0x00000200  // UART Break Error Masked\r
+                                            // Interrupt Status\r
+#define UART_MIS_PEMIS          0x00000100  // UART Parity Error Masked\r
+                                            // Interrupt Status\r
+#define UART_MIS_FEMIS          0x00000080  // UART Framing Error Masked\r
+                                            // Interrupt Status\r
+#define UART_MIS_RTMIS          0x00000040  // UART Receive Time-Out Masked\r
+                                            // Interrupt Status\r
+#define UART_MIS_TXMIS          0x00000020  // UART Transmit Masked Interrupt\r
+                                            // Status\r
+#define UART_MIS_RXMIS          0x00000010  // UART Receive Masked Interrupt\r
+                                            // Status\r
+#define UART_MIS_DSRMIS         0x00000008  // UART Data Set Ready Modem Masked\r
+                                            // Interrupt Status\r
+#define UART_MIS_DCDMIS         0x00000004  // UART Data Carrier Detect Modem\r
+                                            // Masked Interrupt Status\r
+#define UART_MIS_CTSMIS         0x00000002  // UART Clear to Send Modem Masked\r
+                                            // Interrupt Status\r
+#define UART_MIS_RIMIS          0x00000001  // UART Ring Indicator Modem Masked\r
+                                            // Interrupt Status\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are defines for the bit fields in the UART_O_ICR register.\r
+//\r
+//*****************************************************************************\r
+#define UART_ICR_LME5MIC        0x00008000  // LIN Mode Edge 5 Interrupt Clear\r
+#define UART_ICR_LME1MIC        0x00004000  // LIN Mode Edge 1 Interrupt Clear\r
+#define UART_ICR_LMSBMIC        0x00002000  // LIN Mode Sync Break Interrupt\r
+                                            // Clear\r
+#define UART_ICR_OEIC           0x00000400  // Overrun Error Interrupt Clear\r
+#define UART_ICR_BEIC           0x00000200  // Break Error Interrupt Clear\r
+#define UART_ICR_PEIC           0x00000100  // Parity Error Interrupt Clear\r
+#define UART_ICR_FEIC           0x00000080  // Framing Error Interrupt Clear\r
+#define UART_ICR_RTIC           0x00000040  // Receive Time-Out Interrupt Clear\r
+#define UART_ICR_TXIC           0x00000020  // Transmit Interrupt Clear\r
+#define UART_ICR_RXIC           0x00000010  // Receive Interrupt Clear\r
+#define UART_ICR_DSRMIC         0x00000008  // UART Data Set Ready Modem\r
+                                            // Interrupt Clear\r
+#define UART_ICR_DCDMIC         0x00000004  // UART Data Carrier Detect Modem\r
+                                            // Interrupt Clear\r
+#define UART_ICR_CTSMIC         0x00000002  // UART Clear to Send Modem\r
+                                            // Interrupt Clear\r
+#define UART_ICR_RIMIC          0x00000001  // UART Ring Indicator Modem\r
+                                            // Interrupt Clear\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are defines for the bit fields in the UART_O_DMACTL register.\r
+//\r
+//*****************************************************************************\r
+#define UART_DMACTL_DMAERR      0x00000004  // DMA on Error\r
+#define UART_DMACTL_TXDMAE      0x00000002  // Transmit DMA Enable\r
+#define UART_DMACTL_RXDMAE      0x00000001  // Receive DMA Enable\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are defines for the bit fields in the UART_O_LCTL register.\r
+//\r
+//*****************************************************************************\r
+#define UART_LCTL_BLEN_M        0x00000030  // Sync Break Length\r
+#define UART_LCTL_BLEN_13T      0x00000000  // Sync break length is 13T bits\r
+                                            // (default)\r
+#define UART_LCTL_BLEN_14T      0x00000010  // Sync break length is 14T bits\r
+#define UART_LCTL_BLEN_15T      0x00000020  // Sync break length is 15T bits\r
+#define UART_LCTL_BLEN_16T      0x00000030  // Sync break length is 16T bits\r
+#define UART_LCTL_MASTER        0x00000001  // LIN Master Enable\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are defines for the bit fields in the UART_O_LSS register.\r
+//\r
+//*****************************************************************************\r
+#define UART_LSS_TSS_M          0x0000FFFF  // Timer Snap Shot\r
+#define UART_LSS_TSS_S          0\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are defines for the bit fields in the UART_O_LTIM register.\r
+//\r
+//*****************************************************************************\r
+#define UART_LTIM_TIMER_M       0x0000FFFF  // Timer Value\r
+#define UART_LTIM_TIMER_S       0\r
+\r
+//*****************************************************************************\r
+//\r
+// The following definitions are deprecated.\r
+//\r
+//*****************************************************************************\r
+#ifndef DEPRECATED\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are deprecated defines for the UART register offsets.\r
+//\r
+//*****************************************************************************\r
+#define UART_O_LCR_H            0x0000002C  // Line Control Register, HIGH byte\r
+#define UART_O_PeriphID4        0x00000FD0\r
+#define UART_O_PeriphID5        0x00000FD4\r
+#define UART_O_PeriphID6        0x00000FD8\r
+#define UART_O_PeriphID7        0x00000FDC\r
+#define UART_O_PeriphID0        0x00000FE0\r
+#define UART_O_PeriphID1        0x00000FE4\r
+#define UART_O_PeriphID2        0x00000FE8\r
+#define UART_O_PeriphID3        0x00000FEC\r
+#define UART_O_PCellID0         0x00000FF0\r
+#define UART_O_PCellID1         0x00000FF4\r
+#define UART_O_PCellID2         0x00000FF8\r
+#define UART_O_PCellID3         0x00000FFC\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are deprecated defines for the bit fields in the UART_O_DR\r
+// register.\r
+//\r
+//*****************************************************************************\r
+#define UART_DR_DATA_MASK       0x000000FF  // UART data\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are deprecated defines for the bit fields in the UART_O_IBRD\r
+// register.\r
+//\r
+//*****************************************************************************\r
+#define UART_IBRD_DIVINT_MASK   0x0000FFFF  // Integer baud-rate divisor\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are deprecated defines for the bit fields in the UART_O_FBRD\r
+// register.\r
+//\r
+//*****************************************************************************\r
+#define UART_FBRD_DIVFRAC_MASK  0x0000003F  // Fractional baud-rate divisor\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are deprecated defines for the bit fields in the UART_O_LCR_H\r
+// register.\r
+//\r
+//*****************************************************************************\r
+#define UART_LCR_H_SPS          0x00000080  // Stick Parity Select\r
+#define UART_LCR_H_WLEN         0x00000060  // Word length\r
+#define UART_LCR_H_WLEN_5       0x00000000  // 5 bit data\r
+#define UART_LCR_H_WLEN_6       0x00000020  // 6 bit data\r
+#define UART_LCR_H_WLEN_7       0x00000040  // 7 bit data\r
+#define UART_LCR_H_WLEN_8       0x00000060  // 8 bit data\r
+#define UART_LCR_H_FEN          0x00000010  // Enable FIFO\r
+#define UART_LCR_H_STP2         0x00000008  // Two Stop Bits Select\r
+#define UART_LCR_H_EPS          0x00000004  // Even Parity Select\r
+#define UART_LCR_H_PEN          0x00000002  // Parity Enable\r
+#define UART_LCR_H_BRK          0x00000001  // Send Break\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are deprecated defines for the bit fields in the UART_O_IFLS\r
+// register.\r
+//\r
+//*****************************************************************************\r
+#define UART_IFLS_RX_MASK       0x00000038  // RX FIFO level mask\r
+#define UART_IFLS_TX_MASK       0x00000007  // TX FIFO level mask\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are deprecated defines for the bit fields in the UART_O_ICR\r
+// register.\r
+//\r
+//*****************************************************************************\r
+#define UART_RSR_ANY            (UART_RSR_OE | UART_RSR_BE | UART_RSR_PE | \\r
+                                 UART_RSR_FE)\r
+\r
+//*****************************************************************************\r
+//\r
+// The following are deprecated defines for the Reset Values for UART\r
+// Registers.\r
+//\r
+//*****************************************************************************\r
+#define UART_RV_CTL             0x00000300\r
+#define UART_RV_PCellID1        0x000000F0\r
+#define UART_RV_PCellID3        0x000000B1\r
+#define UART_RV_FR              0x00000090\r
+#define UART_RV_PeriphID2       0x00000018\r
+#define UART_RV_IFLS            0x00000012\r
+#define UART_RV_PeriphID0       0x00000011\r
+#define UART_RV_PCellID0        0x0000000D\r
+#define UART_RV_PCellID2        0x00000005\r
+#define UART_RV_PeriphID3       0x00000001\r
+#define UART_RV_PeriphID4       0x00000000\r
+#define UART_RV_LCR_H           0x00000000\r
+#define UART_RV_PeriphID6       0x00000000\r
+#define UART_RV_DR              0x00000000\r
+#define UART_RV_RSR             0x00000000\r
+#define UART_RV_ECR             0x00000000\r
+#define UART_RV_PeriphID5       0x00000000\r
+#define UART_RV_RIS             0x00000000\r
+#define UART_RV_FBRD            0x00000000\r
+#define UART_RV_IM              0x00000000\r
+#define UART_RV_MIS             0x00000000\r
+#define UART_RV_ICR             0x00000000\r
+#define UART_RV_PeriphID1       0x00000000\r
+#define UART_RV_PeriphID7       0x00000000\r
+#define UART_RV_IBRD            0x00000000\r
+\r
+#endif\r
+\r
+#endif // __HW_UART_H__\r
diff --git a/test_src/hw_uart_regs.h b/test_src/hw_uart_regs.h
new file mode 100644 (file)
index 0000000..6798cb7
--- /dev/null
@@ -0,0 +1,154 @@
+/* hw_uart_regs.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+
+#ifndef HW_UART_REGS_H_
+#define HW_UART_REGS_H_
+
+#define UART0_BASE 0x4000C000
+#define UART1_BASE 0x4000D000
+#define UART2_BASE 0x4000E000
+
+#define UARTDR_OFFSET        0x00
+#define UARTRSR_OFFSET       0x04
+#define UARTECR_OFFSET       0x04
+#define UARTFR_OFFSET        0x18
+#define UARTILPR_OFFSET      0x20
+#define UARTIBRD_OFFSET      0x24
+#define UARTFBRD_OFFSET      0x28
+#define UARTLCRH_OFFSET      0x2C
+#define UARTCTL_OFFSET       0x30
+#define UARTIFLS_OFFSET      0x34
+#define UARTIM_OFFSET        0x38
+#define UARTRIS_OFFSET       0x3C
+#define UARTMIS_OFFSET       0x40
+#define UARTICR_OFFSET       0x44
+#define UARTDMACTL_OFFSET    0x48
+#define UARTLCTL_OFFSET      0x90
+#define UARTLSS_OFFSET       0x94
+#define UARTLTIM_OFFSET      0x98
+
+#define UARTPeriphID4_OFFSET  0x0FD0
+#define UARTPeriphID5_OFFSET  0x0FD4
+#define UARTPeriphID6_OFFSET  0x0FD8
+#define UARTPeriphID7_OFFSET  0x0FDC
+#define UARTPeriphID0_OFFSET  0x0FE0
+#define UARTPeriphID1_OFFSET  0x0FE4
+#define UARTPeriphID2_OFFSET  0x0FE8
+#define UARTPeriphID3_OFFSET  0x0FEC
+
+#define UARTCellID0_OFFSET    0x0FF0
+#define UARTCellID1_OFFSET    0x0FF4
+#define UARTCellID2_OFFSET    0x0FF8
+#define UARTCellID3_OFFSET    0x0FFC
+
+/* bits in UARTFR */
+#define UART_RI   8
+#define UART_TXFE 7
+#define UART_RXFF 6
+#define UART_TXFF 5
+#define UART_RXFE 4
+#define UART_BUSY 3
+#define UART_DCD  2
+#define UART_DSR  1
+#define UART_CTS  0
+
+/* bits in UARTLCRH */
+#define UART_FEN 4
+
+/* bits in UARTMIS */
+#define UART_LME5MIS  15
+#define UART_LME1MIS  14
+#define UART_LMSBMIS  13
+#define UART_OEMIS    10
+#define UART_BEMIS     9
+#define UART_PEMIS     8
+#define UART_FEMIS     7
+#define UART_RTMIS     6
+#define UART_TXMIS     5
+#define UART_RXMIS     4
+#define UART_DSRMIS    3
+#define UART_DCDMIS    2
+#define UART_CTSMIS    1
+#define UART_RIMIS     0
+
+/* bits in UARTICR */
+#define UART_LME5MIC  15
+#define UART_LME1MIC  14
+#define UART_LMSBMIC  13
+#define UART_OEIC     10
+#define UART_BEIC      9
+#define UART_PEIC      8
+#define UART_FEIC      7
+#define UART_RTIC      6
+#define UART_TXIC      5
+#define UART_RXIC      4
+#define UART_DSRMIC    3
+#define UART_DCDMIC    2
+#define UART_CTSMIC    1
+#define UART_RIMIC     0
+
+/* bits in UARTIM */
+#define UART_LME5IM  15
+#define UART_LME1IM  14
+#define UART_LMSBIM  13
+#define UART_OEIM    10
+#define UART_BEIM     9
+#define UART_PEIM     8
+#define UART_FEIM     7
+#define UART_RTIM     6
+#define UART_TXIM     5
+#define UART_RXIM     4
+#define UART_DSRIM    3
+#define UART_DCDIM    2
+#define UART_CTSIM    1
+#define UART_RIIM     0
+
+/* bits in UARTRIS */
+#define UART_LME5RIS  15
+#define UART_LME1RIS  14
+#define UART_LMSBRIS  13
+#define UART_OERIS    10
+#define UART_BERIS     9
+#define UART_PERIS     8
+#define UART_FERIS     7
+#define UART_RTRIS     6
+#define UART_TXRIS     5
+#define UART_RXRIS     4
+#define UART_DSRRIS    3
+#define UART_DCDRIS    2
+#define UART_CTSRIS    1
+#define UART_RIRIS     0
+
+/* bits in UARTCTL */
+#define UART_CTSEN    15
+#define UART_RTSEN    14
+#define UART_RTS      11
+#define UART_DTR      10
+#define UART_RXE       9
+#define UART_TXE       8
+#define UART_LBE       7
+#define UART_LIN       6
+#define UART_HSE       5
+#define UART_EOT       4
+#define UART_SMART     3
+#define UART_SIRLP     2
+#define UART_SIREN     1
+#define UART_UARTEN    0
+
+#endif /* HW_UART_REGS_H_ */
diff --git a/test_src/nessie_common.c b/test_src/nessie_common.c
new file mode 100644 (file)
index 0000000..41381ed
--- /dev/null
@@ -0,0 +1,184 @@
+/* nessie_common.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * 
+ * author: Daniel Otte
+ * email:  daniel.otte@rub.de
+ * license: GPLv3
+ * 
+ * common function for nessie-tests
+ * 
+ * */
+
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h> /* utoa() */
+#include "nessie_common.h"
+#include "hexdigit_tab.h"
+#include "cli.h"
+#include "string-extras.h"
+
+#ifdef NESSIE_ALIVE
+void nessie_send_alive(void){
+       cli_putc(NESSIE_ALIVE_CHAR);
+}
+
+void nessie_send_alive_a(uint16_t i){
+       if((i&31)==0)
+               cli_putc(NESSIE_ALIVE_CHAR);
+}
+#endif
+
+void nessie_print_block(uint8_t* block, uint16_t blocksize_bit){
+       cli_hexdump(block, (blocksize_bit+7)/8);
+}
+
+#define SPACES 31
+#define BYTESPERLINE 16
+
+void nessie_print_item(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){
+               cli_putstr("\r\n!!! formatting error !!!\r\n");
+               return;
+       }
+       cli_putstr("\r\n");
+       for(i=0; i<SPACES-name_len-1; ++i){
+               cli_putc(' ');
+       }
+       cli_putstr(name);
+       cli_putc('=');
+       /* now the data printing begins */
+       if(size_B<=BYTESPERLINE){
+               /* one line seems sufficient */
+               nessie_print_block(buffer, size_B*8);
+       } else {
+               /* we need more lines */
+               nessie_print_block(buffer, BYTESPERLINE*8); /* first line */
+               int16_t toprint = size_B - BYTESPERLINE;
+               buffer += BYTESPERLINE;
+               while(toprint > 0){
+                       cli_putstr("\r\n");
+                       for(i=0; i<SPACES; ++i){
+                               cli_putc(' ');
+                       }
+                       nessie_print_block(buffer, ((toprint>BYTESPERLINE)?BYTESPERLINE:toprint)*8);
+                       buffer  += BYTESPERLINE;
+                       toprint -= BYTESPERLINE;
+               }
+       }
+} 
+
+
+void nessie_print_set_vector(uint8_t set, uint16_t vector){
+       cli_putstr("\r\n\r\nSet ");
+       cli_putc('0'+set%10);
+       cli_putstr(", vector#");
+       cli_putc((vector<1000)?' ':'0'+vector/1000);
+       cli_putc((vector<100)?' ':'0'+(vector/100)%10);
+       cli_putc((vector<10 )?' ':'0'+(vector/10)%10);
+       cli_putc('0'+vector%10);
+       cli_putc(':');
+}
+
+/* example:
+Test vectors -- set 3
+=====================
+ */ 
+void nessie_print_setheader(uint8_t set){
+       cli_putstr("\r\n\r\nTest vectors -- set ");
+       cli_putc('0'+set%10);
+       cli_putstr("\r\n=====================");
+}
+
+/* example:
+********************************************************************************
+*Project NESSIE - New European Schemes for Signature, Integrity, and Encryption*
+********************************************************************************
+
+Primitive Name: Serpent
+=======================
+Key size: 256 bits
+Block size: 128 bits
+*/
+
+void nessie_print_header(char* name,
+                         uint16_t keysize_b, 
+                         uint16_t blocksize_b,
+                         uint16_t hashsize_b, 
+                         uint16_t macsize_b,
+                         uint16_t ivsize_b ){
+       uint16_t i;
+       cli_putstr("\r\n\r\n"
+       "********************************************************************************\r\n"
+       "* ARM-Crypto-Lib - crypto primitives for ARM microcontrolles by Daniel Otte    *\r\n"
+       "********************************************************************************\r\n"
+       "\r\n");
+       cli_putstr("Primitive Name: ");
+       cli_putstr(name);
+       cli_putstr("\r\n");
+       /* underline */ 
+       for(i=0; i<16+strlen(name); ++i){
+               cli_putc('=');
+       }
+       char str[6]; /* must catch numbers up to 65535 + terminatin \0 */
+       if(keysize_b){
+               cli_putstr("\r\nKey size: ");
+               ustoa(keysize_b, str, 10);
+               cli_putstr(str);
+               cli_putstr(" bits");
+       }
+       if(blocksize_b){
+               cli_putstr("\r\nBlock size: ");
+               ustoa(blocksize_b, str, 10);
+               cli_putstr(str);
+               cli_putstr(" bits");
+       }
+       if(hashsize_b){
+               cli_putstr("\r\nHash size: ");
+               ustoa(hashsize_b, str, 10);
+               cli_putstr(str);
+               cli_putstr(" bits");
+       }
+       if(macsize_b){
+               cli_putstr("\r\nMac size: ");
+               ustoa(macsize_b, str, 10);
+               cli_putstr(str);
+               cli_putstr(" bits");
+       }
+       if(ivsize_b){
+               if(ivsize_b==(uint16_t)-1){
+                       cli_putstr("\r\nNo initial value (IV) mode");
+               }
+               {
+                       cli_putstr("\r\nIV size: ");
+                       ustoa(ivsize_b, str, 10);
+                       cli_putstr(str);
+                       cli_putstr(" bits");
+               }
+       }
+       cli_putstr("\r\n");
+}
+
+void nessie_print_footer(void){
+       cli_putstr("\r\n\r\n\r\n\r\nEnd of test vectors\r\n\r\n");
+}
+
diff --git a/test_src/nessie_common.h b/test_src/nessie_common.h
new file mode 100644 (file)
index 0000000..65b05b6
--- /dev/null
@@ -0,0 +1,70 @@
+/* nessie_common.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * 
+ * author: Daniel Otte
+ * email:  daniel.otte@rub.de
+ * license: GPLv3
+ * 
+ * common function for nessie-tests
+ * 
+ * */
+
+#ifndef NESSIE_COMMON_H_
+#define NESSIE_COMMON_H_
+
+#define NESSIE_ALIVE_CHAR 0x06
+#define NESSIE_ALIVE
+#define NESSIE_USE_CLI
+
+#include <stdint.h>
+
+#ifdef NESSIE_ALIVE
+#define NESSIE_SEND_ALIVE nessie_send_alive()
+void nessie_send_alive(void);
+#define NESSIE_SEND_ALIVE_A(i) nessie_send_alive_a(i)
+void nessie_send_alive_a(uint16_t i);
+#else
+#define NESSIE_SEND_ALIVE 
+#define NESSIE_SEND_ALIVE_A(i)  
+#endif
+
+
+#ifdef NESSIE_USE_CLI
+#include "cli.h"
+#define NESSIE_PUTC cli_putc
+#define NESSIE_PUTSTR cli_putstr
+#define NESSIE_PUTSTR_P cli_putstr_P
+#else
+# error "direct uart output removed for nessie"
+#endif
+
+void nessie_print_block(uint8_t* block, uint16_t blocksize_bit);
+void nessie_print_item(char* name, uint8_t* buffer, uint16_t size_B);
+void nessie_print_set_vector(uint8_t set, uint16_t vector);
+void nessie_print_setheader(uint8_t set);
+void nessie_print_header(char* name,
+                         uint16_t keysize_b, 
+                         uint16_t blocksize_b,
+                         uint16_t hashsize_b, 
+                         uint16_t macsize_b,
+                         uint16_t ivsize_b );
+void nessie_print_footer(void);
+
+#endif /*NESSIE_COMMON_H_*/
diff --git a/test_src/nessie_hash_test.c b/test_src/nessie_hash_test.c
new file mode 100644 (file)
index 0000000..4309fd4
--- /dev/null
@@ -0,0 +1,270 @@
+/* nessie_hash_test.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * 
+ * author: Daniel Otte
+ * email:  daniel.otte@rub.de
+ * license: GPLv3
+ * 
+ * a suit for running the nessie-tests for hashes
+ * 
+ * */
+#include <stdint.h>
+#include <string.h>
+#include "nessie_hash_test.h"
+#include "nessie_common.h"
+#include "dbz_strings.h"
+
+nessie_hash_ctx_t nessie_hash_ctx;
+uint8_t           nessie_hash_quick=0;
+
+#define HASHSIZE_B ((nessie_hash_ctx.hashsize_b+7)/8)
+#define BLOCKSIZE_B (nessie_hash_ctx.blocksize_B)
+
+static
+void ascii_hash(const char* data, const char* desc){
+       uint8_t ctx[nessie_hash_ctx.ctx_size_B];
+       uint8_t hash[HASHSIZE_B];
+       uint16_t sl;
+       uint8_t buffer[BLOCKSIZE_B];
+       
+       cli_putstr("\r\n                       message=");
+       cli_putstr(desc);
+       nessie_hash_ctx.hash_init(ctx);
+       sl = strlen(data);
+       while(sl>=BLOCKSIZE_B){
+               memcpy(buffer, data, BLOCKSIZE_B);
+               nessie_hash_ctx.hash_next(ctx, buffer);
+               data += BLOCKSIZE_B;
+               sl   -= BLOCKSIZE_B;
+       }
+       memcpy(buffer, data, sl);
+       nessie_hash_ctx.hash_last(ctx, buffer, sl*8);
+       nessie_hash_ctx.hash_conv(hash, ctx);
+       nessie_print_item("hash", hash, (nessie_hash_ctx.hashsize_b+7)/8);
+}
+
+// message=1 million times "a"
+
+static
+void amillion_hash(void){
+       uint8_t ctx[nessie_hash_ctx.ctx_size_B];
+       uint8_t hash[(nessie_hash_ctx.hashsize_b+7)/8];
+       uint8_t block[nessie_hash_ctx.blocksize_B];
+       uint32_t n=1000000LL;
+       uint16_t i=0;
+       
+       cli_putstr("\r\n                       message=");
+       cli_putstr("1 million times \"a\"");
+       memset(block, 'a', nessie_hash_ctx.blocksize_B);
+       nessie_hash_ctx.hash_init(ctx);
+       while(n>=nessie_hash_ctx.blocksize_B){
+               nessie_hash_ctx.hash_next(ctx, block);
+               n    -= nessie_hash_ctx.blocksize_B;
+               NESSIE_SEND_ALIVE_A(i++);
+       }
+       nessie_hash_ctx.hash_last(ctx, block, n*8);
+       nessie_hash_ctx.hash_conv(hash, ctx);
+       nessie_print_item("hash", hash, (nessie_hash_ctx.hashsize_b+7)/8);
+}
+
+
+static
+void zero_hash(uint16_t n){
+       uint8_t ctx[nessie_hash_ctx.ctx_size_B];
+       uint8_t hash[(nessie_hash_ctx.hashsize_b+7)/8];
+       uint8_t block[nessie_hash_ctx.blocksize_B];
+       
+       cli_putstr("\r\n                       message=");
+       if(n>=10000)
+               cli_putc('0'+n/10000);
+       if(n>=1000)
+               cli_putc('0'+(n/1000)%10);
+       if(n>=100)
+               cli_putc('0'+(n/100)%10);
+       if(n>=10)
+               cli_putc('0'+(n/10)%10);
+       cli_putc('0'+n%10);
+       cli_putstr(" zero bits");
+       
+       memset(block, 0, nessie_hash_ctx.blocksize_B); 
+       nessie_hash_ctx.hash_init(ctx);
+       while(n>=nessie_hash_ctx.blocksize_B*8){
+               nessie_hash_ctx.hash_next(ctx, block);
+               n   -= nessie_hash_ctx.blocksize_B*8;
+       }
+       nessie_hash_ctx.hash_last(ctx, block, n);
+       nessie_hash_ctx.hash_conv(hash, ctx);
+       nessie_print_item("hash", hash, (nessie_hash_ctx.hashsize_b+7)/8);
+}
+
+static
+void one_in512_hash(uint16_t pos){
+       uint8_t ctx[nessie_hash_ctx.ctx_size_B];
+       uint8_t hash[(nessie_hash_ctx.hashsize_b+7)/8];
+       uint8_t block[nessie_hash_ctx.blocksize_B];
+       uint16_t n=512;
+       char* tab[8]={"80", "40", "20", "10", 
+                     "08", "04", "02", "01" };
+
+       pos&=511;
+       cli_putstr("\r\n                       message=");
+       cli_putstr("512-bit string: ");
+       if((pos/8) >=10){
+               cli_putc('0'+(pos/8/10)%10);
+       } else {
+               cli_putc(' ');
+       }
+       cli_putc('0'+(pos/8)%10);
+       cli_putstr("*00,");
+       cli_putstr(tab[pos&7]);
+       cli_putc(',');
+       if(63-(pos/8) >=10){
+               cli_putc('0'+((63-pos/8)/10)%10);
+       } else {
+               cli_putc(' ');
+       }
+       cli_putc('0'+(63-pos/8)%10);
+       cli_putstr("*00");
+       
+       /* now the real stuff */
+       memset(block, 0, 512/8);
+       block[pos>>3] = 0x80>>(pos&0x7);
+       nessie_hash_ctx.hash_init(ctx);
+       while(n>=nessie_hash_ctx.blocksize_B*8){
+               nessie_hash_ctx.hash_next(ctx, block);
+               n   -= nessie_hash_ctx.blocksize_B*8;
+       }
+       nessie_hash_ctx.hash_last(ctx, block, n);
+       nessie_hash_ctx.hash_conv(hash, ctx);
+       nessie_print_item("hash", hash, (nessie_hash_ctx.hashsize_b+7)/8);
+}
+
+static
+void tv4_hash(void){
+       uint8_t ctx[nessie_hash_ctx.ctx_size_B];
+       uint8_t hash[(nessie_hash_ctx.hashsize_b+7)/8];
+       uint8_t block[nessie_hash_ctx.hashsize_b/8];
+       uint16_t n=nessie_hash_ctx.hashsize_b;
+       uint32_t i;
+       
+       cli_putstr("\r\n                       message=");
+       if(nessie_hash_ctx.hashsize_b>=10000)
+               cli_putc('0' + (nessie_hash_ctx.hashsize_b/10000)%10);
+       if(nessie_hash_ctx.hashsize_b>=1000)
+               cli_putc('0' + (nessie_hash_ctx.hashsize_b/1000)%10);
+       if(nessie_hash_ctx.hashsize_b>=100)
+               cli_putc('0' + (nessie_hash_ctx.hashsize_b/100)%10);
+       if(nessie_hash_ctx.hashsize_b>=10)
+               cli_putc('0' + (nessie_hash_ctx.hashsize_b/10)%10);
+       cli_putc('0' + nessie_hash_ctx.hashsize_b%10);
+
+       cli_putstr(" zero bits");
+       memset(block, 0, 256/8);
+       
+       nessie_hash_ctx.hash_init(ctx);
+       while(n>=nessie_hash_ctx.blocksize_B*8){
+               nessie_hash_ctx.hash_next(ctx, block);
+               n    -= nessie_hash_ctx.blocksize_B*8;
+       }
+       nessie_hash_ctx.hash_last(ctx, block, n);
+       nessie_hash_ctx.hash_conv(hash, ctx);
+       nessie_print_item("hash", hash, (nessie_hash_ctx.hashsize_b+7)/8);
+       if(nessie_hash_quick)
+               return;
+       for(i=1; i<100000L; ++i){ /* this assumes BLOCKSIZE >= HASHSIZE */
+               nessie_hash_ctx.hash_init(ctx);
+               nessie_hash_ctx.hash_last(ctx, hash, nessie_hash_ctx.hashsize_b);
+               nessie_hash_ctx.hash_conv(hash, ctx);
+               NESSIE_SEND_ALIVE_A(i);
+       }
+       nessie_print_item("iterated 100000 times", hash, (nessie_hash_ctx.hashsize_b+7)/8);
+}
+
+/*
+   "" (empty string)
+   message="a"
+   message="abc"
+   message="message digest"
+   message="abcdefghijklmnopqrstuvwxyz"
+   message="abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+   message="A...Za...z0...9"
+   message=8 times "1234567890"
+*/
+
+
+void nessie_hash_run(void){
+       uint16_t i;
+       uint8_t set;
+       
+       nessie_print_header(nessie_hash_ctx.name, 0, 0, nessie_hash_ctx.hashsize_b, 0, 0);
+       /* test set 1 */
+       char* challange_dbz=
+                 "\0"
+               "\"\" (empty string)\0"
+                 "a\0"
+               "\"a\"\0"
+                 "abc\0"
+               "\"abc\"\0"
+                 "message digest\0"
+               "\"message digest\"\0"
+                 "abcdefghijklmnopqrstuvwxyz\0"
+               "\"abcdefghijklmnopqrstuvwxyz\"\0"
+                 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\0"
+               "\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\"\0"
+                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                 "abcdefghijklmnopqrstuvwxyz"
+                 "0123456789\0"         
+                "\"A...Za...z0...9\"\0"
+                "1234567890123456789012345678901234567890" 
+                "1234567890123456789012345678901234567890\0"
+                "8 times \"1234567890\"\0" ;
+       char* challange[16];
+       set=1;
+       nessie_print_setheader(set);
+       dbz_splitup(challange_dbz, challange);
+       for(i=0; i<8; ++i){
+               nessie_print_set_vector(set, i);
+               ascii_hash(challange[2*i], challange[2*i+1]);
+       }
+       nessie_print_set_vector(set, i);
+       if(!nessie_hash_quick)
+               amillion_hash();
+       /* test set 2 */
+       set=2;
+       nessie_print_setheader(set);
+       for(i=0; i<1024; ++i){
+               nessie_print_set_vector(set, i);
+               zero_hash(i);
+       }
+       /* test set 3 */
+       set=3;
+       nessie_print_setheader(set);
+       for(i=0; i<512; ++i){
+               nessie_print_set_vector(set, i);
+               one_in512_hash(i);
+       }
+       /* test set 4 */
+       set=4;
+       nessie_print_setheader(set);
+       nessie_print_set_vector(set, 0);
+       tv4_hash();
+
+       nessie_print_footer();
+}
diff --git a/test_src/nessie_hash_test.h b/test_src/nessie_hash_test.h
new file mode 100644 (file)
index 0000000..c3bf131
--- /dev/null
@@ -0,0 +1,46 @@
+/* nessie_hash_test.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+#ifndef NESSIE_HASH_TEST_H_
+#define NESSIE_HASH_TEST_H_
+
+#include <stdint.h>
+
+typedef void (*nessie_hash_init_fpt)(void* ctx);
+typedef void (*nessie_hash_next_fpt)(void* ctx, const void* buffer);
+typedef void (*nessie_hash_last_fpt)(void* ctx, const void* buffer, uint16_t size_b);
+typedef void (*nessie_hash_conv_fpt)(void* buffer, void* ctx);
+
+
+typedef struct nessie_hash_ctx_st{
+       uint16_t hashsize_b;
+       uint16_t blocksize_B;
+       uint16_t ctx_size_B;
+       char* name; 
+       nessie_hash_init_fpt hash_init;
+       nessie_hash_next_fpt hash_next;
+       nessie_hash_last_fpt hash_last;
+       nessie_hash_conv_fpt hash_conv;
+} nessie_hash_ctx_t; 
+
+
+extern nessie_hash_ctx_t nessie_hash_ctx;
+extern uint8_t nessie_hash_quick;
+void nessie_hash_run(void);
+
+#endif /*NESSIE_HASH_TEST_H_*/
diff --git a/test_src/performance_test.c b/test_src/performance_test.c
new file mode 100644 (file)
index 0000000..bea24fc
--- /dev/null
@@ -0,0 +1,101 @@
+/* performance_test.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/*
+ * author: Daniel Otte
+ * email:  daniel.otte@rub.de
+ * license: GPLv3
+ *
+ *
+ **/
+
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include "hw_regs.h"
+#include "hw_gptm.h"
+#include "cli.h"
+#include "string-extras.h"
+#include "performance_test.h"
+
+
+static volatile uint32_t ovfcounter;
+
+static uint32_t const_overhead=0;
+static uint32_t int_overhead=0;
+
+void calibrateTimer(void){
+       uint64_t t;
+       startTimer(1);
+       t=stopTimer();
+       const_overhead = (uint32_t)t;
+}
+
+void initTimer(void){
+       gptm_set_timer_32periodic(PERF_TIMER);
+}
+
+void startTimer(uint8_t granularity){
+       gptm_stop_timer(PERF_TIMER, 0);
+       gptm_write_timer(PERF_TIMER, 0, 0);
+       if(granularity>0){
+               gptm_set_timer_prescaler(PERF_TIMER, 0, granularity-1);
+               gptm_start_timer(PERF_TIMER, 0);
+       }else{
+               gptm_set_timer_prescaler(PERF_TIMER, 0, 0);
+       }
+}
+
+uint64_t stopTimer(void){
+       gptm_stop_timer(PERF_TIMER, 0);
+       uint64_t ret;
+       ret = gptm_read_timer(PERF_TIMER, 0);
+       ret -= const_overhead;
+       ret -= ovfcounter * int_overhead;
+       return ret;
+}
+
+void getOverhead(uint32_t* constoh, uint32_t* intoh){
+       *constoh = const_overhead;
+       *intoh   = int_overhead;
+}
+
+void print_time(const char* s, uint64_t t){
+       char sv[22];
+       uint8_t c;
+       cli_putstr("\r\n");
+       cli_putstr(s);
+       ulltoa(t, sv, 10);
+       for(c=strlen(sv); c<11; ++c){
+               cli_putc(' ');
+       }
+       cli_putstr(sv);
+}
+
+void print_overhead(void){
+       char str[11];
+       cli_putstr("\r\n\r\n=== benchmark ===");
+       ultoa(const_overhead, str, 10);
+       cli_putstr("\r\n\tconst overhead:     ");
+       cli_putstr(str);
+       ultoa(int_overhead, str, 10);
+       cli_putstr("\r\n\tinterrupt overhead: ");
+       cli_putstr(str);
+}
+
+
diff --git a/test_src/performance_test.h b/test_src/performance_test.h
new file mode 100644 (file)
index 0000000..adb08ef
--- /dev/null
@@ -0,0 +1,39 @@
+/* performance_test.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+#ifndef PERFORMANCE_TEST_H_
+#define PERFORMANCE_TEST_H_
+
+#include <stdint.h>
+#include "hw_gptm.h"
+
+#define PERF_TIMER TIMER0
+#define PERF_TIMER_BASE TIMER0_BASE
+
+#define START_TIMER  gptm_start_timer(PERF_TIMER, 0) /* HW_REG(PERF_TIMER_BASE+GPTM_CTL_OFFSET) |= _BV(GPTM_TAEN) */
+#define STOP_TIMER   gptm_stop_timer(PERF_TIMER, 0) /* HW_REG(PERF_TIMER_BASE+GPTM_CTL_OFFSET) &= ~_BV(GPTM_TAEN) */
+
+void calibrateTimer(void);
+void startTimer(uint8_t granularity);
+uint64_t stopTimer(void);
+void getOverhead(uint32_t* constoh, uint32_t* intoh);
+
+void print_time_P(const char* s, uint64_t t);
+void print_overhead(void);
+
+#endif /*PERFORMANCE_TEST_H_*/
diff --git a/test_src/setbaud_asm.inc b/test_src/setbaud_asm.inc
new file mode 100644 (file)
index 0000000..b472a88
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+    This file is part of the AVR-uart_ni.
+    Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+    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 <util/setbaud.h> */
+/* we use a modifyed version of util/setbaud where the UL suffix is removed
+ * since the preprocessor can not handle that.
+ */
+
+#ifndef F_CPU
+#  error "uart_i requires F_CPU to be defined"
+#endif
+
+#ifndef BAUD
+#  error "uart_i requires UART0_BAUD_RATE to be defined"
+#endif
+
+#if !(F_CPU)
+#  error "F_CPU must be a constant value"
+#endif
+
+#if !(BAUD)
+#  error "UART0_BAUD_RATE must be a constant value"
+#endif
+
+#undef USE_2X
+
+/* Baud rate tolerance is 2 % unless previously defined */
+#ifndef BAUD_TOL
+#  define BAUD_TOL 2
+#endif
+
+#define UBRR_VALUE (((F_CPU) + 8 * (BAUD)) / (16 * (BAUD)) -1)
+
+#if 100 * (F_CPU) > \
+  (16 * ((UBRR_VALUE) + 1)) * (100 * (BAUD) + (BAUD) * (BAUD_TOL))
+#  define USE_2X 1
+#elif 100 * (F_CPU) < \
+  (16 * ((UBRR_VALUE) + 1)) * (100 * (BAUD) - (BAUD) * (BAUD_TOL))
+#  define USE_2X 1
+#else
+#  define USE_2X 0
+#endif
+
+#if USE_2X
+/* U2X required, recalculate */
+#undef UBRR_VALUE
+#define UBRR_VALUE (((F_CPU) + 4 * (BAUD)) / (8 * (BAUD)) -1)
+
+#if 100 * (F_CPU) > \
+  (8 * ((UBRR_VALUE) + 1)) * (100 * (BAUD) + (BAUD) * (BAUD_TOL))
+#  warning "Baud rate achieved is higher than allowed"
+#endif
+
+#if 100 * (F_CPU) < \
+  (8 * ((UBRR_VALUE) + 1)) * (100 * (BAUD) - (BAUD) * (BAUD_TOL))
+#  warning "Baud rate achieved is lower than allowed"
+#endif
+
+#endif /* USE_U2X */
+
+#ifdef UBRR_VALUE
+#  define UBRRL_VALUE ((UBRR_VALUE) & 0xff)
+#  define UBRRH_VALUE ((UBRR_VALUE) >> 8)
+#endif
+
diff --git a/test_src/shavs.c b/test_src/shavs.c
new file mode 100644 (file)
index 0000000..7ac8ec7
--- /dev/null
@@ -0,0 +1,492 @@
+/* shavs.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file       shavs.c
+ * \author  Daniel Otte
+ * \date    2006-05-16
+ * \license    GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "hashfunction_descriptor.h"
+#include "hfal-basic.h"
+#include "shavs.h"
+#include "string-extras.h"
+#include "cli.h"
+
+
+#ifdef DEBUG
+#  undef DEBUG
+#endif
+
+#define DEBUG 0
+
+#if DEBUG
+//#  include "config.h"
+//#  include <util/delay.h>
+#endif
+
+hfdesc_t*  shavs_algo=NULL;
+hfdesc_t** shavs_algolist=NULL;
+
+void shavs_listalgos(void){
+       char option = 'a';
+
+       hfdesc_t* t;
+       uint8_t i=0;
+       cli_putstr("\r\nthe following algorithms are available:\r\n");
+       while(option<='z' && (t=shavs_algolist[i])){
+               cli_putc('\t');
+               cli_putc((t==shavs_algo)?'*':' ');
+               cli_putc(option++);
+               cli_putstr(":\t");
+               cli_putstr(t->name);
+               cli_putstr("\r\n");
+               i++;
+       }
+}
+
+void shavs_setalgo(char* param){
+       param = strstrip(param);
+       if(param[1]=='\0'){ /* single letter specified */
+               uint8_t i,option = param[0]-'a';
+
+               if(!shavs_algolist){
+                       cli_putstr("\r\nERROR: shavs_algolist not set!");
+                       return;
+               }
+               for(i=0; i<=option; ++i){
+                       if((shavs_algolist[i])==NULL){
+                               cli_putstr("\r\nERROR: invalid selection!");
+                               return;
+                       }
+               }
+               shavs_algo=(hfdesc_t*)(shavs_algolist[option]);
+       } else { /* name specified */
+               hfdesc_t* t=NULL;
+               uint8_t i=0;
+               while((t=shavs_algolist[i]) && strcasecmp(param, t->name)){
+                       ++i;
+               }
+               if(t){
+                       shavs_algo=t;
+               }else{
+                       cli_putstr("\r\nERROR: could not find \"");
+                       cli_putstr(param);
+                       cli_putstr("\"!");
+               }
+       }
+}
+
+typedef struct {
+       uint16_t buffer_idx;
+       uint16_t buffersize_B;
+       uint32_t blocks;
+       hfgen_ctx_t ctx;
+       uint8_t* buffer;
+       uint8_t  in_byte;
+} shavs_ctx_t;
+
+static shavs_ctx_t shavs_ctx;
+
+uint8_t buffer_add(char c){
+       uint8_t v,t;
+       if(shavs_ctx.buffer_idx==shavs_ctx.buffersize_B){
+               hfal_hash_nextBlock(&(shavs_ctx.ctx), shavs_ctx.buffer);
+               ++shavs_ctx.blocks;
+               shavs_ctx.buffer_idx=0;
+               shavs_ctx.in_byte=0;
+               cli_putc('.');
+               memset(shavs_ctx.buffer, 0, shavs_ctx.buffersize_B);
+       }
+       if(c>='0' && c<='9'){
+               v=c-'0';
+       }else{
+               c &= (uint8_t)~('a' ^ 'A');
+               if(c>='A' && c<='F'){
+                       v=c-'A'+10;
+               }else{
+                       return 1;
+               }
+       }
+       t=shavs_ctx.buffer[shavs_ctx.buffer_idx];
+       if(shavs_ctx.in_byte){
+               t |= v;
+               shavs_ctx.buffer[shavs_ctx.buffer_idx]=t;
+               shavs_ctx.buffer_idx++;
+               shavs_ctx.in_byte = 0;
+       }else{
+               t |= v<<4;
+               shavs_ctx.buffer[shavs_ctx.buffer_idx]=t;
+               shavs_ctx.in_byte = 1;
+       }
+       return 0;
+}
+
+int32_t getLength(void){
+       uint32_t len=0;
+       char lenstr[21];
+       char* len2;
+       for(;;){
+               memset(lenstr, 0, 21);
+               cli_getsn(lenstr, 20);
+               len2 = strstrip(lenstr);
+               if(!strncasecmp(len2, "LEN", 3)){
+                       while(*len2 && *len2!='=')
+                               len2++;
+                       if(*len2=='='){
+                               do{
+                                       len2++;
+                               }while(*len2 && !isdigit(*len2));
+                               len=(uint32_t)strtoul(len2, NULL, 10);
+                               return len;
+                       }
+               } else {
+                       if(!strncasecmp(len2, "EXIT", 4)){
+                               return -1;
+                       }
+               }
+       }
+}
+
+void shavs_test1(void){ /* KAT tests */
+       uint32_t length=0;
+       int32_t expect_input=0;
+
+       if(!shavs_algo){
+                       cli_putstr("\r\nERROR: select algorithm first!");
+               return;
+       }
+       char c;
+       uint8_t diggest[shavs_algo->hashsize_b/8];
+       shavs_ctx.buffersize_B=shavs_algo->blocksize_b/8;
+       uint8_t buffer[shavs_ctx.buffersize_B+5];
+       shavs_ctx.buffer = buffer;
+       cli_putstr("\r\nbuffer_size = 0x");
+       cli_hexdump_rev(&(shavs_ctx.buffersize_B), 2);
+       cli_putstr(" bytes");
+       for(;;){
+               shavs_ctx.blocks = 0;
+               memset(buffer, 0, shavs_ctx.buffersize_B);
+               length = getLength();
+               if(length<0){
+                       return;
+               }
+
+#if DEBUG
+               cli_putstr("\r\nLen == ");
+               cli_hexdump_rev(&length, 4);
+#endif
+               if(length==0){
+                       expect_input=2;
+               }else{
+                       expect_input=((length+7)>>2)&(~1L);
+               }
+#if DEBUG
+               cli_putstr("\r\nexpected_input == ");
+               cli_hexdump_rev(&expect_input, 4);
+               if(expect_input==0)
+                       cli_putstr("\r\nexpected_input == 0 !!!");
+#endif
+               shavs_ctx.buffer_idx = 0;
+               shavs_ctx.in_byte    = 0;
+               shavs_ctx.blocks     = 0;
+               uint8_t ret;
+#if DEBUG
+               cli_putstr("\r\n HFAL init");
+               cli_putstr("\r\n (2) expected_input == ");
+               cli_hexdump_rev(&expect_input, 4);
+#endif
+               ret = hfal_hash_init(shavs_algo, &(shavs_ctx.ctx));
+               if(ret){
+                       cli_putstr("\r\n HFAL init returned with: ");
+                       cli_hexdump(&ret, 1);
+                       return;
+               }
+#if DEBUG
+               cli_putstr("\r\n (3) expected_input == ");
+               cli_hexdump_rev(&expect_input, 4);
+               cli_putstr("\r\n");
+#endif
+               while((c=cli_getc_cecho())!='M' && c!='m'){
+                       if(!isblank(c)){
+                               cli_putstr("\r\nERROR: wrong input (1) [0x");
+                               cli_hexdump(&c, 1);
+                               cli_putstr("]!\r\n");
+                               hfal_hash_free(&(shavs_ctx.ctx));
+                               return;
+                       }
+               }
+               if((c=cli_getc_cecho())!='s' && c!='S'){
+                               cli_putstr("\r\nERROR: wrong input (2)!\r\n");
+                               hfal_hash_free(&(shavs_ctx.ctx));
+                               return;
+               }
+               if((c=cli_getc_cecho())!='g' && c!='G'){
+                               cli_putstr("\r\nERROR: wrong input (3)!\r\n");
+                               hfal_hash_free(&(shavs_ctx.ctx));
+                               return;
+               }
+               while((c=cli_getc_cecho())!='='){
+                       if(!isblank(c)){
+                               cli_putstr("\r\nERROR: wrong input (4)!\r\n");
+                               hfal_hash_free(&(shavs_ctx.ctx));
+                               return;
+                       }
+               }
+#if DEBUG
+               cli_putstr("\r\nparsing started");
+#endif
+               shavs_ctx.buffer_idx = 0;
+               shavs_ctx.in_byte    = 0;
+               shavs_ctx.blocks     = 0;
+               while(expect_input>0){
+                       c=cli_getc_cecho();
+#if DEBUG
+                       cli_putstr("\r\n\t(");
+                       cli_hexdump_rev(&expect_input, 4);
+                       cli_putstr(") ");
+#endif
+                       if(buffer_add(c)==0){
+                               --expect_input;
+                       }else{
+                               if(!isblank((uint16_t)c)){
+                                       cli_putstr("\r\nERROR: wrong input (5) (");
+                                       cli_putc(c);
+                                       cli_putstr(")!\r\n");
+                                       hfal_hash_free(&(shavs_ctx.ctx));
+                                       return;
+                               }
+                       }
+               }
+#if DEBUG
+               cli_putstr("\r\nBuffer-A:");
+               cli_hexdump_block(buffer, shavs_ctx.buffersize_B, 5, 8);
+
+               cli_putstr("\r\n starting finalisation");
+               cli_putstr("\r\n\tblocks     == ");
+               cli_hexdump_rev(&(shavs_ctx.blocks),4);
+               cli_putstr("\r\n\tbuffer_idx == ");
+               cli_hexdump_rev(&(shavs_ctx.buffer_idx),2);
+               cli_putstr("\r\n\tin_byte    == ");
+               cli_hexdump_rev(&(shavs_ctx.in_byte),1);
+
+               cli_putstr("\r\n starting last block");
+               cli_putstr("\r\n\tlength       == ");
+               cli_hexdump_rev(&length,4);
+               cli_putstr("\r\n\tbuffersize_B == ");
+               cli_hexdump_rev(&(shavs_ctx.buffersize_B),2);
+               uint16_t temp=length-(shavs_ctx.blocks)*((shavs_ctx.buffersize_B)*8);
+               cli_putstr("\r\n\t (temp)      == ");
+               cli_hexdump_rev(&temp,2);
+               temp=length-(shavs_ctx.blocks)*((shavs_ctx.buffersize_B)*8);
+#else
+               uint16_t temp=length-(shavs_ctx.blocks)*((shavs_ctx.buffersize_B)*8);
+#endif
+               /*              cli_putstr("\r\n\t (temp)      == ");
+               cli_hexdump_rev(&temp,2); */
+               hfal_hash_lastBlock( &(shavs_ctx.ctx), buffer, /* be aware of freaking compilers!!! */
+//                                                     length-(shavs_ctx.blocks)*((shavs_ctx.buffersize_B)*8));
+                                   temp );
+#if DEBUG
+               cli_putstr("\r\n starting ctx2hash");
+#endif
+               hfal_hash_ctx2hash(diggest, &(shavs_ctx.ctx));
+#if DEBUG
+               cli_putstr("\r\n starting hash free");
+#endif
+               hfal_hash_free(&(shavs_ctx.ctx));
+               cli_putstr("\r\n MD = ");
+               cli_hexdump(diggest, shavs_algo->hashsize_b/8);
+
+       }
+}
+
+void shavs_test2(void){ /* Monte Carlo tests for SHA-1 & SHA-2 */
+       uint16_t expected_input;
+       uint16_t count;
+       uint8_t v;
+       uint8_t index=0;
+       char c;
+       if(!shavs_algo){
+                       cli_putstr("\r\nERROR: select algorithm first!");
+               return;
+       }
+       uint8_t ml=shavs_algo->hashsize_b/8;
+       uint8_t m[ml*4+8];
+       for(;;){
+               while((c=cli_getc_cecho())!='S' && c!='s'){
+                       if(!isblank(c)){
+                               cli_putstr("\r\nERROR: wrong input (1) [0x");
+                               cli_hexdump(&c, 1);
+                               cli_putstr("]!\r\n");
+                               return;
+                       }
+               }
+               if((c=cli_getc_cecho())!='e' && c!='e'){
+                               cli_putstr("\r\nERROR: wrong input (2)!\r\n");
+                               return;
+               }
+               if((c=cli_getc_cecho())!='e' && c!='e'){
+                               cli_putstr("\r\nERROR: wrong input (3)!\r\n");
+                               return;
+               }
+               if((c=cli_getc_cecho())!='d' && c!='D'){
+                               cli_putstr("\r\nERROR: wrong input (4)!\r\n");
+                               return;
+               }
+               while((c=cli_getc_cecho())!='='){
+                       if(!isblank(c)){
+                               cli_putstr("\r\nERROR: wrong input (5)!\r\n");
+                               return;
+                       }
+               }
+               expected_input = ml*2;
+               memset(m+2*ml, 0, ml);
+               do{
+                       v=0xff;
+                       c=cli_getc_cecho();
+                       if(c>='0' && c<='9'){
+                               v = c - '0';
+                       }else{
+                               c |= 'A'^'a';
+                               if(c>='a' && c<='f'){
+                                       v = c - 'a' +10;
+                               }
+                       }
+                       if(v<0x10){
+                               c=m[ml*2+index/2];
+                               if(index&1){
+                                       c |= v;
+                               }else{
+                                       c |=v<<4;
+                               }
+                               m[ml*2+index/2]=c;
+                               index++;
+                               expected_input--;
+                       }
+               }while(expected_input);
+               /* so we have the seed */
+               cli_putstr("\r\nstarting processing");
+               uint16_t j;
+               for(count=0; count<100; ++count){
+                       memcpy(m, m+ml*2, ml);
+                       memcpy(m+ml, m+ml*2, ml);
+                       for(j=0; j<1000; ++j){
+                               hfal_hash_mem(shavs_algo, m+ml*3, m, ml*3*8);
+                               memmove(m, m+ml, 3*ml);
+                       }
+                       cli_putstr("\r\n\r\nCOUNT = ");
+                       if(count>=10){
+                               cli_putc(count/10+'0');
+                       }
+                       cli_putc(count%10+'0');
+                       cli_putstr("\r\nMD = ");
+                       cli_hexdump(m+ml*2, ml);
+               }
+       }
+}
+
+void shavs_test3(void){ /* Monte Carlo tests for SHA-3 */
+       uint16_t expected_input;
+       uint16_t count;
+       uint8_t v;
+       uint8_t index=0;
+       char c;
+       if(!shavs_algo){
+                       cli_putstr("\r\nERROR: select algorithm first!");
+               return;
+       }
+       uint8_t ml=shavs_algo->hashsize_b/8;
+       uint8_t m[ml+128];
+       for(;;){
+               while((c=cli_getc_cecho())!='S' && c!='s'){
+                       if(!isblank(c)){
+                               cli_putstr("\r\nERROR: wrong input (1) [0x");
+                               cli_hexdump(&c, 1);
+                               cli_putstr("]!\r\n");
+                               return;
+                       }
+               }
+               if((c=cli_getc_cecho())!='e' && c!='e'){
+                               cli_putstr("\r\nERROR: wrong input (2)!\r\n");
+                               return;
+               }
+               if((c=cli_getc_cecho())!='e' && c!='e'){
+                               cli_putstr("\r\nERROR: wrong input (3)!\r\n");
+                               return;
+               }
+               if((c=cli_getc_cecho())!='d' && c!='D'){
+                               cli_putstr("\r\nERROR: wrong input (4)!\r\n");
+                               return;
+               }
+               while((c=cli_getc_cecho())!='='){
+                       if(!isblank(c)){
+                               cli_putstr("\r\nERROR: wrong input (5)!\r\n");
+                               return;
+                       }
+               }
+               expected_input = 1024/4;
+               memset(m+ml, 0, 1024/8);
+               do{
+                       v=0xff;
+                       c=cli_getc_cecho();
+                       if(c>='0' && c<='9'){
+                               v = c - '0';
+                       }else{
+                               c |= 'A'^'a';
+                               if(c>='a' && c<='f'){
+                                       v = c - 'a' +10;
+                               }
+                       }
+                       if(v<0x10){
+                               c=m[ml+index/2];
+                               if(index&1){
+                                       c |= v;
+                               }else{
+                                       c |=v<<4;
+                               }
+                               m[ml+index/2]=c;
+                               index++;
+                               expected_input--;
+                       }
+               }while(expected_input);
+               /* so we have the seed */
+               cli_putstr("\r\nstarting processing");
+               uint16_t j;
+               for(count=0; count<100; ++count){
+                       for(j=0; j<1000; ++j){
+                               hfal_hash_mem(shavs_algo, m, m+ml, 1024);
+                               memmove(m+ml, m, 1024/8);
+                       }
+                       cli_putstr("\r\n\r\nj = ");
+                       if(count>=10){
+                               cli_putc(count/10+'0');
+                       }
+                       cli_putc(count%10+'0');
+                       cli_putstr("\r\nMD = ");
+                       cli_hexdump(m+ml, ml);
+
+               }
+       }
+}
diff --git a/test_src/shavs.h b/test_src/shavs.h
new file mode 100644 (file)
index 0000000..2199351
--- /dev/null
@@ -0,0 +1,43 @@
+/* shavs.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file       shavs.h
+ * \author  Daniel Otte
+ * \date    2006-05-16
+ * \license    GPLv3 or later
+ *
+ */
+
+#ifndef SHAVS_H_
+#define SHAVS_H_
+
+#include <stdlib.h>
+#include "hashfunction_descriptor.h"
+
+extern hfdesc_t*  shavs_algo;
+extern hfdesc_t** shavs_algolist;
+
+void shavs_listalgos(void);
+void shavs_setalgo(char* param);
+void shavs_test1(void);
+void shavs_test2(void);
+void shavs_test3(void);
+
+
+#endif /* SHAVS */
diff --git a/test_src/startup.c b/test_src/startup.c
new file mode 100644 (file)
index 0000000..f1c3619
--- /dev/null
@@ -0,0 +1,138 @@
+/* startup.c */
+/*
+    This file is part of the OpenARMWare.
+    Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
+
+    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 <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define RAM_START 0x20000000
+#define RAM_SIZE (96*1024)
+
+int main(void);
+void uart0_isr(void);
+
+/* the following are defined by the linker */
+extern char _text;
+extern char _text_end;
+extern char _data;
+extern char _data_end;
+extern char _bss;
+extern char _bss_end;
+
+typedef void(*isr_fpt)(void);
+
+static void fault_isr(void){
+       for(;;){
+       }
+}
+
+static void default_isr(void){
+       for(;;){
+       }
+}
+
+
+static void nmi_isr(void){
+       for(;;){
+       }
+}
+
+void reset_isr(void){
+       memcpy(&_data, &_text_end, &_data_end - &_data);
+       memset(&_bss, 0, &_bss_end - &_bss);
+       main();
+}
+
+isr_fpt isr_vector[] __attribute__ ((section(".isr_vectors"))) = {
+               (isr_fpt)(RAM_START+RAM_SIZE-4),
+               reset_isr,   /* Reset */
+               nmi_isr,     /* Non-Maskable Interrupt (NMI) */
+               fault_isr,   /* Hard Fault */
+               default_isr, /* Memory Management */
+               fault_isr, /* Bus Fault */
+               fault_isr, /* Usage Fault */
+               NULL,         /* Reserved */
+               NULL,         /* Reserved */
+               NULL,         /* Reserved */
+               NULL,         /* Reserved */
+               default_isr, /* SVCall */
+               default_isr, /* Debug Monitor */
+               NULL,         /* Reserved */
+               default_isr, /* PendSV */
+               default_isr, /* SysTick */
+               default_isr, /* GPIO Port A */
+               default_isr, /* GPIO Port B */
+               default_isr, /* GPIO Port C */
+               default_isr, /* GPIO Port D */
+               default_isr, /* GPIO Port E */
+               uart0_isr, /* UART0 */
+               default_isr, /* UART1 */
+               default_isr, /* SSI0 */
+               default_isr, /* I2C0 */
+               NULL,         /* Reserved */
+               NULL,         /* Reserved */
+               NULL,         /* Reserved */
+               NULL,         /* Reserved */
+               NULL,         /* Reserved */
+               default_isr, /* ADC0 Sequence 0 */
+               default_isr, /* ADC0 Sequence 1 */
+               default_isr, /* ADC0 Sequence 2 */
+               default_isr, /* ADC0 Sequence 3 */
+               default_isr, /* Watchdog Timers 0 and 1 */
+               default_isr, /* Timer 0A */
+               default_isr, /* Timer 0B */
+               default_isr, /* Timer 1A */
+               default_isr, /* Timer 1B */
+               default_isr, /* Timer 2A */
+               default_isr, /* Timer 2B */
+               default_isr, /* Analog Comparator 0 */
+               default_isr, /* Analog Comparator 1 */
+               default_isr, /* Analog Comparator 2 */
+               default_isr, /* System Control */
+               default_isr, /* Flash Memory Control */
+               default_isr, /* GPIO Port F */
+               default_isr, /* GPIO Port G */
+               default_isr, /* GPIO Port H */
+               default_isr, /* UART2 */
+               default_isr, /* SSI1 */
+               default_isr, /* Timer 3A */
+               default_isr, /* Timer 3B */
+               default_isr, /* I2C1 */
+               NULL,         /* Reserved */
+               default_isr, /* CAN0 */
+               default_isr, /* CAN1 */
+               NULL,         /* Reserved */
+               default_isr, /* Ethernet Controller */
+               default_isr, /* Hibernation Module */
+               default_isr, /* USB */
+               NULL,         /* Reserved */
+               default_isr, /* ÂµDMA Software */
+               default_isr, /* ÂµDMA Error */
+               default_isr, /* ADC1 Sequence 0 */
+               default_isr, /* ADC1 Sequence 1 */
+               default_isr, /* ADC1 Sequence 2 */
+               default_isr, /* ADC1 Sequence 3 */
+               default_isr, /* I2S0 */
+               default_isr, /* EPI */
+               default_isr, /* GPIO Port J */
+               NULL,         /* Reserved */
+};
+
+
+
diff --git a/test_src/string-extras.c b/test_src/string-extras.c
new file mode 100644 (file)
index 0000000..f4c95a2
--- /dev/null
@@ -0,0 +1,144 @@
+/* string_extras.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file       string_extras.c
+ * \author  Daniel Otte 
+ * \date    2006-05-16
+ * \license    GPLv3 or later
+ * 
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+uint32_t stridentcnt(const char* a, const char* b){
+       uint16_t i=0;
+       for(;;){
+               if(*a != *b || *b=='\0')
+                       return i;
+               i++;
+               a++;
+               b++;
+       }
+}
+
+uint16_t firstword_length(const char* s){
+       uint16_t ret=0;
+       while(isgraph(*s++))
+               ret++;
+       return ret; 
+}
+
+char* strstrip(char* str){
+       if(!str)
+               return str;
+       char* endptr;
+       while(*str && (*str==' ' || *str=='\t'))
+               ++str;
+       endptr=str;
+       while(*endptr)
+               ++endptr;
+       do{
+               --endptr;
+       }while(*endptr==' ' || *endptr=='\t');
+       endptr[1]='\0';
+       return str;
+}
+
+void str_reverse(char* buffer){
+       char *i, *j;
+       char c;
+       i=buffer;
+       j=buffer + strlen(buffer)-1;
+       while(i<j){
+               c = *i;
+               *i = *j;
+               *j = c;
+               ++i;
+               --j;
+       }
+}
+
+char* ultoa(unsigned long a, char* buffer, uint8_t radix){
+       if(radix<2 || radix>36){
+               return NULL;
+       }
+       char* ptr=buffer;
+       div_t result;
+       if(a==0){
+               ptr[0] = '0';
+               ptr[1] = '\0';
+               return buffer;
+       }
+       while(a){
+               result = div(a, radix);
+               *ptr = result.rem;
+               if(result.rem<10){
+                       *ptr += '0';
+               }else{
+                       *ptr += 'a'-10;
+               }
+               ++ptr;
+               a = result.quot;
+       }
+       *ptr = '\0';
+       str_reverse(buffer);
+       return buffer;
+}
+
+char* ulltoa(unsigned long long a, char* buffer, uint8_t radix){
+       if(radix<2 || radix>36){
+               return NULL;
+       }
+       char* ptr=buffer;
+       uint8_t rem;
+       if(a==0){
+               ptr[0] = '0';
+               ptr[1] = '\0';
+               return buffer;
+       }
+       while(a){
+               rem = a % radix;
+               a = a / radix;
+               *ptr = rem;
+               if(rem<10){
+                       *ptr += '0';
+               }else{
+                       *ptr += 'a'-10;
+               }
+               ++ptr;
+       }
+       *ptr = '\0';
+       str_reverse(buffer);
+       return buffer;
+}
+
+char* ustoa(unsigned short a, char* buffer, uint8_t radix){
+       return ultoa((unsigned long)a, buffer, radix);
+}
+/*
+void strlwr(char* s){
+       while(*s){
+               *s = tolower(*s);
+               s++;
+       }
+}
+*/
diff --git a/test_src/string-extras.h b/test_src/string-extras.h
new file mode 100644 (file)
index 0000000..bdd45d8
--- /dev/null
@@ -0,0 +1,65 @@
+/* string-extras.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file       string-extras.h
+ * \author  Daniel Otte 
+ * \date    2006-05-16
+ * \license    GPLv3 or later
+ * 
+ */
+#include <stdint.h>
+
+/** \fn stridentcnt_P(char* a, PGM_P b)
+ * \brief counts the number of identic chars
+ * 
+ * This function compares the supplied strings and returns the index of the
+ * first char where the strings differ.
+ * \param a pointer to string in RAM
+ * \param b pointer to string in Flash
+ * \return index of the first char where \c a and \c b differ
+ */
+uint32_t stridentcnt(const char* a, const char* b);
+
+/** \fn firstword_length(char* s)
+ * \brief compute the length of the first word in supplied string
+ * 
+ * This function searches for the first whitespace in the string and returns the
+ * number of chars before the first whitespace.
+ * \param s string
+ * \return number of chars in first word
+ */
+uint16_t firstword_length(const char* s);
+
+/** \fn strstrip(char* str)
+ * \brief removes whitespace at the beginning and the end of a string
+ * 
+ * This function removes whitespaces at the end of a string.
+ * \param str sting
+ * \return pointer to the first non-whitespace char in string
+ */
+char* strstrip(char* str);
+
+void str_reverse(char* buffer);
+
+char* ultoa(unsigned long a, char* buffer, uint8_t radix);
+
+char* ulltoa(unsigned long long a, char* buffer, uint8_t radix);
+
+char* ustoa(unsigned long a, char* buffer, uint8_t radix);
+// void strlwr(char* s);
diff --git a/test_src/sysclock.c b/test_src/sysclock.c
new file mode 100644 (file)
index 0000000..acbfb29
--- /dev/null
@@ -0,0 +1,94 @@
+/* sysclock.c */
+/*
+    This file is part of the OpenARMWare.
+    Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
+
+    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 <stdint.h>
+#include "hw_regs.h"
+
+
+#define CRYSTAL_FREQ 16000000UL
+#define CRYSTAL_CODE 0x15 /* 16 MHz */
+
+#define PIOSC_FREQ 16000000UL
+
+void sysclk_set_rawclock(void){
+       uint32_t tmp_rcc;
+       tmp_rcc = 0; //HW_REG(SYSCTL_BASE+RCC_OFFSET);
+       tmp_rcc &= ~(_BV(RCC_IOSCDIS) | _BV(RCC_MOSCDIS) | _BV(RCC_USESYSDIV));
+       tmp_rcc |= _BV(RCC_BYPASS) | _BV(RCC_PWRDN);
+       tmp_rcc &= ~(3<<RCC_OSCSRC);
+       tmp_rcc |=  (0<<RCC_OSCSRC);
+       HW_REG(SYSCTL_BASE+RCC_OFFSET) = tmp_rcc;
+       HW_REG(SYSCTL_BASE+RCC2_OFFSET) &= ~(_BV(31));
+
+}
+
+void sysclk_mosc_verify_enable(void){
+       HW_REG(SYSCTL_BASE+MOSCCTL_OFFSET) |= 1; // turn on main oscillator verify circuit
+}
+
+void sysclk_mosc_verify_disable(void){
+       HW_REG(SYSCTL_BASE+MOSCCTL_OFFSET) &= ~1UL; // turn on main oscillator verify circuit
+}
+
+void sysclk_set_80MHz(void){
+       uint32_t rcc1, rcc2=0;
+       sysclk_set_rawclock();
+       rcc1 = HW_REG(SYSCTL_BASE+RCC_OFFSET);
+//     rcc2 = HW_REG(SYSCTL_BASE+RCC2_OFFSET);
+       rcc1 &= ~(0x1f<<RCC_XTAL);
+       rcc1 |= CRYSTAL_CODE<<RCC_XTAL;
+       rcc2 = _BV(RCC2_USERCC2) | _BV(RCC2_PWRDN2) | _BV(RCC2_BYPASS2) | _BV(RCC2_USBPWRDN); /* OSCSRC2 is set to 0 */
+       HW_REG(SYSCTL_BASE+RCC_OFFSET)  = rcc1;
+       HW_REG(SYSCTL_BASE+RCC2_OFFSET) = rcc2;
+       rcc2 &= ~_BV(RCC2_PWRDN2);
+       HW_REG(SYSCTL_BASE+RCC2_OFFSET) = rcc2;
+       rcc2 |= _BV(RCC2_DIV400) | 0x04<<RCC2_SYSDIV2LSB;
+       HW_REG(SYSCTL_BASE+RCC2_OFFSET) = rcc2;
+       while(!(HW_REG(SYSCTL_BASE+RIS_OFFSET)&_BV(RIS_PLLLRIS))){
+       }
+       rcc2 &= ~_BV(RCC2_BYPASS2);
+       HW_REG(SYSCTL_BASE+RCC2_OFFSET) = rcc2;
+}
+
+uint32_t sysclk_get_freq(void){
+       uint32_t rcc1, rcc2, basefreq=400000000UL, divider=1;
+       const uint32_t bypass_freq[] = {
+                       CRYSTAL_FREQ, PIOSC_FREQ,  PIOSC_FREQ/4, 30000,
+                       0, 0, 4194304, 32768 };
+       rcc1 = HW_REG(SYSCTL_BASE+RCC_OFFSET);
+       rcc2 = HW_REG(SYSCTL_BASE+RCC2_OFFSET);
+       if(rcc2&_BV(RCC2_USERCC2)){
+               /* use RCC2 */
+               if(rcc2&_BV(RCC2_BYPASS2)){
+                       basefreq = bypass_freq[(rcc2>>RCC2_OSCSR2)&0x07];
+               }
+               if(rcc2&_BV(RCC2_DIV400)){
+                       divider = ((rcc2>>RCC2_SYSDIV2LSB)&0x7F)+1;
+               }else{
+                       divider = ((rcc2>>RCC2_SYSDIV2)&0x3F)+1;
+               }
+       }else{
+               /* use RCC */
+               if(rcc1&_BV(RCC_BYPASS)){
+                        basefreq = bypass_freq[(rcc1>>RCC_OSCSRC)&0x03];
+               }
+               divider = ((rcc1>>RCC_SYSDIV)&0xf)+1;
+       }
+       return basefreq/divider;
+}
diff --git a/test_src/sysclock.h b/test_src/sysclock.h
new file mode 100644 (file)
index 0000000..9ca1a9b
--- /dev/null
@@ -0,0 +1,31 @@
+/* sysclock.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+
+#ifndef SYSCLOCK_H_
+#define SYSCLOCK_H_
+
+#include <stdint.h>
+
+void sysclk_set_rawclock(void);
+void sysclk_mosc_verify_enable(void);
+void sysclk_mosc_verify_disable(void);
+void sysclk_set_80MHz(void);
+uint32_t sysclk_get_freq(void);
+
+#endif /* SYSCLOCK_H_ */
diff --git a/test_src/sysclock.o b/test_src/sysclock.o
new file mode 100644 (file)
index 0000000..912a005
Binary files /dev/null and b/test_src/sysclock.o differ
diff --git a/test_src/testport.conf b/test_src/testport.conf
new file mode 100644 (file)
index 0000000..e10ae61
--- /dev/null
@@ -0,0 +1,14 @@
+# configfile for shavs tests
+
+[PORT]
+port = /dev/ttyUSB1
+baud = 115200
+databits = 8
+stopbits = 1
+paraty = none
+testlogbase = testlog/testlog_
+
+include=testconf/*.conf
+
+
+# END OF CONFIGFILE
diff --git a/test_src/uart_defines.h b/test_src/uart_defines.h
new file mode 100644 (file)
index 0000000..976f2ee
--- /dev/null
@@ -0,0 +1,50 @@
+/* uart_defines.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+
+#ifndef UART_DEFINES_H_
+#define UART_DEFINES_H_
+
+#define UART_0 0
+#define UART_1 1
+#define UART_2 2
+#define UART_MAX 2
+
+#define UART_DATABITS_5 0
+#define UART_DATABITS_6 1
+#define UART_DATABITS_7 2
+#define UART_DATABITS_8 3
+
+#define UART_PARATY_NONE  0
+#define UART_PARATY_EVEN  1
+#define UART_PARATY_ODD   2
+#define UART_PARATY_MARK  3
+#define UART_PARATY_SPACE 4
+
+#define UART_STOPBITS_ONE 0
+#define UART_STOPBITS_TWO 1
+
+#define UART_ERROR_OK              0
+#define UART_ERROR_WRONG_UART      1
+#define UART_ERROR_WRONG_DATABITS  2
+#define UART_ERROR_WRONG_PARATY    3
+#define UART_ERROR_WRONG_STOPBITS  4
+#define UART_ERROR_RX_BUFFER_INIT  5
+#define UART_ERROR_TX_BUFFER_INIT  6
+
+#endif /* UART_DEFINES_H_ */
diff --git a/test_src/uart_i.c b/test_src/uart_i.c
new file mode 100644 (file)
index 0000000..1881988
--- /dev/null
@@ -0,0 +1,253 @@
+/* uart_i.c */
+/*
+    This file is part of the OpenARMWare.
+    Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
+
+    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 <stdint.h>
+#include "sysclock.h"
+#include "hw_regs.h"
+#include "hw_uart_regs.h"
+#include "uart_defines.h"
+#include "circularbytebuffer.h"
+
+
+static const
+uint32_t uart_base[] = { UART0_BASE, UART1_BASE, UART2_BASE };
+
+static const
+uint32_t gpio_base[] =
+       { GPIOA_BASE, GPIOB_BASE, GPIOC_BASE, GPIOD_BASE,
+         GPIOE_BASE, GPIOF_BASE, GPIOG_BASE, GPIOH_BASE,
+         GPIOJ_BASE,
+       };
+
+static const
+uint8_t uart_tx_gpio[] = { GPIOA, GPIOD, GPIOG };
+static const
+uint8_t uart_rx_gpio[] = { GPIOA, GPIOD, GPIOG };
+static const
+uint8_t uart_tx_pin[] = { 1, 1, 1 };
+static const
+uint8_t uart_rx_pin[] = { 0, 0, 0 };
+static const
+uint8_t uart_tx_pctl[] = {1, 5, 1};
+static const
+uint8_t uart_rx_pctl[] = {1, 5, 1};
+static const
+uint8_t uart_isr_vector[] = {5, 6, 33};
+
+static const
+uint32_t uart_rx_buffersize[] = {128, 128, 128};
+static const
+uint32_t uart_tx_buffersize[] = {256, 256, 256};
+
+static
+circularbytebuffer_t uart_rx_buffer[3];
+static
+circularbytebuffer_t uart_tx_buffer[3];
+
+
+static
+void uart_tx_isr(uint8_t uartno);
+static
+void uart_rx_isr(uint8_t uartno);
+
+void uart0_isr(void){
+
+       if(HW_REG(UART0_BASE+UARTMIS_OFFSET)&_BV(UART_TXMIS)){
+//             HW_REG(uart_base[0]+UARTDR_OFFSET) = 'X';
+               uart_tx_isr(UART_0);
+       }
+       if(HW_REG(UART0_BASE+UARTMIS_OFFSET)&_BV(UART_RXMIS)){
+               uart_rx_isr(UART_0);
+       }
+}
+
+static
+void uart_tx_isr(uint8_t uartno){
+       uint32_t tmp;
+       tmp = circularbytebuffer_cnt(&(uart_tx_buffer[uartno]));
+       while(tmp-- && (!(HW_REG(uart_base[uartno]+UARTFR_OFFSET)&_BV(UART_TXFF)))){
+               HW_REG(uart_base[uartno]+UARTDR_OFFSET)
+                               = (uint32_t)circularbytebuffer_get_fifo(&(uart_tx_buffer[uartno]));
+       }
+       HW_REG(uart_base[uartno]+UARTICR_OFFSET) |= _BV(UART_TXIC);
+}
+
+static
+void uart_rx_isr(uint8_t uartno){
+       uint8_t c;
+       while(!HW_REG(uart_base[uartno]+UARTFR_OFFSET)&_BV(UART_RXFE)){
+               c = HW_REG(uart_base[uartno]+UARTDR_OFFSET);
+               circularbytebuffer_append(c, &(uart_rx_buffer[uartno]));
+       }
+       HW_REG(uart_base[uartno]+UARTICR_OFFSET) |= _BV(UART_RXIC);
+}
+
+void calc_baud_values(uint32_t baudrate, uint16_t* intdivider, uint8_t* fracdivider, uint8_t* highspeed){
+       uint32_t tmp;
+       uint32_t uart_freq;
+       uart_freq = sysclk_get_freq();
+       *highspeed = (baudrate*16>uart_freq)?1:0;
+       tmp = (uint64_t)uart_freq*128/((*highspeed?8:16)*baudrate);
+       tmp++;
+       tmp>>=1;
+       *fracdivider = (uint8_t)(tmp&0x3f);
+       *intdivider = tmp>>6;
+}
+
+uint8_t uart_init(uint8_t uartno, uint32_t baudrate, uint8_t databits, uint8_t paraty, uint8_t stopbits){
+       uint32_t tmp;
+       if(databits>=5){
+               databits-=5;
+       }
+       if(uartno>UART_MAX){
+               return UART_ERROR_WRONG_UART;
+       }
+       if(databits>UART_DATABITS_8){
+               return UART_ERROR_WRONG_DATABITS;
+       }
+       if(paraty>UART_PARATY_SPACE){
+               return UART_ERROR_WRONG_PARATY;
+       }
+       if(stopbits>UART_STOPBITS_TWO){
+               return UART_ERROR_WRONG_STOPBITS;
+       }
+       if(0==circularbytebuffer_init(uart_rx_buffersize[uartno], &(uart_rx_buffer[uartno]))){
+               return UART_ERROR_RX_BUFFER_INIT;
+       }
+       if(0==circularbytebuffer_init(uart_tx_buffersize[uartno], &(uart_tx_buffer[uartno]))){
+               return UART_ERROR_TX_BUFFER_INIT;
+       }
+       /* enable clock for uart */
+       HW_REG(SYSCTL_BASE+RCGC1_OFFSET) |= _BV(uartno);
+       /* enable clock for gpio*/
+       HW_REG(SYSCTL_BASE+RCGC2_OFFSET) |= _BV(uart_rx_gpio[uartno]) | _BV(uart_tx_gpio[uartno]);
+    HW_REG(SYSCTL_BASE+RCGC2_OFFSET) |= 1;
+
+    HW_REG(gpio_base[uart_rx_gpio[uartno]] + GPIO_ODR_OFFSET) &= ~_BV(uart_rx_pin[uartno]); /* open drain */
+    HW_REG(gpio_base[uart_tx_gpio[uartno]] + GPIO_ODR_OFFSET) &= ~_BV(uart_tx_pin[uartno]); /* open drain */
+    HW_REG(gpio_base[uart_rx_gpio[uartno]] + GPIO_PUR_OFFSET) &= ~_BV(uart_rx_pin[uartno]); /* pull-up */
+    HW_REG(gpio_base[uart_tx_gpio[uartno]] + GPIO_PUR_OFFSET) &= ~_BV(uart_tx_pin[uartno]); /* pull-up */
+    HW_REG(gpio_base[uart_rx_gpio[uartno]] + GPIO_PDR_OFFSET) &= ~_BV(uart_rx_pin[uartno]); /* pull-down*/
+    HW_REG(gpio_base[uart_tx_gpio[uartno]] + GPIO_PDR_OFFSET) &= ~_BV(uart_tx_pin[uartno]); /* pull-down*/
+    HW_REG(gpio_base[uart_rx_gpio[uartno]] + GPIO_DEN_OFFSET) |=  _BV(uart_rx_pin[uartno]); /* digital enable */
+    HW_REG(gpio_base[uart_tx_gpio[uartno]] + GPIO_DEN_OFFSET) |=  _BV(uart_tx_pin[uartno]); /* digital enable */
+
+       /* switch to alternate function for rx */
+       HW_REG(gpio_base[uart_rx_gpio[uartno]]+GPIO_AFSEL_OFFSET) |= _BV(uart_rx_pin[uartno]);
+        /* switch to alternate function for tx */
+       HW_REG(gpio_base[uart_tx_gpio[uartno]]+GPIO_AFSEL_OFFSET) |= _BV(uart_tx_pin[uartno]);
+       /* switch multiplexer to uart for rx */
+       HW_REG(gpio_base[uart_rx_gpio[uartno]]+GPIO_PCTL_OFFSET) &= ~(0x0f<<(uart_rx_pin[uartno]*4));
+       HW_REG(gpio_base[uart_rx_gpio[uartno]]+GPIO_PCTL_OFFSET) |= ((uart_rx_pctl[uartno])<<(uart_rx_pin[uartno]*4));
+       /* switch multiplexer to uart for tx */
+       HW_REG(gpio_base[uart_tx_gpio[uartno]]+GPIO_PCTL_OFFSET) &= ~(0x0f<<(uart_tx_pin[uartno]*4));
+       HW_REG(gpio_base[uart_tx_gpio[uartno]]+GPIO_PCTL_OFFSET) |= ((uart_tx_pctl[uartno])<<(uart_tx_pin[uartno]*4));
+       /* set pins to be 2mA */
+       HW_REG(gpio_base[uart_rx_gpio[uartno]]+GPIO_DR2R_OFFSET) |= _BV(uart_rx_pin[uartno]);
+       HW_REG(gpio_base[uart_tx_gpio[uartno]]+GPIO_DR2R_OFFSET) |= _BV(uart_tx_pin[uartno]);
+       /* configure rx pin as input */
+       HW_REG(gpio_base[uart_rx_gpio[uartno]]+GPIO_DIR_OFFSET) &= ~_BV(uart_rx_pin[uartno]);
+       /* configure tx pin as output */
+       HW_REG(gpio_base[uart_tx_gpio[uartno]]+GPIO_DIR_OFFSET) |= _BV(uart_tx_pin[uartno]);
+
+       /* disable uart */
+       HW_REG(uart_base[uartno]+UARTCTL_OFFSET) &= ~_BV(UART_UARTEN);
+       /* set baudrate parameters */
+       uint8_t highspeed;
+       calc_baud_values(baudrate,
+                                (uint16_t*)&HW_REG(uart_base[uartno]+UARTIBRD_OFFSET),
+                                (uint8_t*)&HW_REG(uart_base[uartno]+UARTFBRD_OFFSET),
+                                &highspeed);
+       /* wait until uart is no longer busy */
+       while(HW_REG(uart_base[uartno]+UARTFR_OFFSET)&_BV(UART_BUSY))
+               ;
+       /* flush FIFOs */
+       HW_REG(uart_base[uartno]+UARTLCRH_OFFSET) &= ~_BV(UART_FEN);
+       /* set line parameters (bits, paraty, stopbits*/
+       tmp = HW_REG(uart_base[uartno]+UARTLCRH_OFFSET);
+       tmp &= ~0xff;
+       tmp |= (paraty==UART_PARATY_MARK||paraty==UART_PARATY_SPACE)?_BV(7):0; /* set flag for mark or space paraty*/
+       tmp |= databits<<5;
+       tmp |= _BV(UART_FEN); /* enable FIFOs */
+       tmp |= (stopbits==UART_STOPBITS_TWO)?_BV(3):0;
+       tmp |= (paraty==UART_PARATY_EVEN || paraty==UART_PARATY_MARK)?_BV(2):0;
+       tmp |= (paraty!=UART_PARATY_NONE)?_BV(1):0;
+       HW_REG(uart_base[uartno]+UARTLCRH_OFFSET) = tmp;
+       /* set the highspeed bit accordingly */
+       if(highspeed){
+               HW_REG(uart_base[uartno]+UARTCTL_OFFSET) |= _BV(UART_HSE);
+       } else {
+               HW_REG(uart_base[uartno]+UARTCTL_OFFSET) &= ~_BV(UART_HSE);
+       }
+       /* uart interrupt enable */
+       HW_REG(uart_base[uartno]+UARTIM_OFFSET) |= _BV(UART_TXIM) | _BV(UART_RXIM);
+       HW_REG(ISR_ENABLE_VECTOR+uart_isr_vector[uartno]/32) |=
+                       _BV(uart_isr_vector[uartno]%32);
+
+       HW_REG(uart_base[uartno]+UARTCTL_OFFSET) |= _BV(UART_EOT);
+       HW_REG(uart_base[uartno]+UARTFR_OFFSET) = 0;
+       HW_REG(uart_base[uartno]+UARTCTL_OFFSET) |= _BV(UART_RXE) | _BV(UART_TXE);
+       HW_REG(uart_base[uartno]+UARTCTL_OFFSET) |= _BV(UART_UARTEN);
+
+       return UART_ERROR_OK;
+}
+
+
+void uart_putc(uint8_t uartno, uint8_t byte){
+       if(uartno>UART_MAX){
+               return;
+       }
+       /* wait while buffer is full */
+       while(circularbytebuffer_cnt(&(uart_tx_buffer[uartno]))==uart_tx_buffersize[uartno]){
+       }
+       if(circularbytebuffer_cnt(&(uart_tx_buffer[uartno]))>0){
+               circularbytebuffer_append(byte, &(uart_tx_buffer[uartno]));
+               return;
+       }
+       /* if we have a full uart, append to buffer */
+       if(HW_REG(uart_base[uartno]+UARTFR_OFFSET)&_BV(UART_TXFF)){
+               circularbytebuffer_append(byte, &(uart_tx_buffer[uartno]));
+               return;
+       }
+       HW_REG(uart_base[uartno]+UARTDR_OFFSET) = (uint32_t)byte;
+}
+
+uint16_t uart_getc(uint8_t uartno){
+       if(uartno>UART_MAX){
+               return 0xffff;
+       }
+       if(circularbytebuffer_cnt(&(uart_rx_buffer[uartno]))){
+               return circularbytebuffer_get_fifo(&(uart_rx_buffer[uartno]));
+       }
+       /* wait while the FIFO is empty */
+       while(HW_REG(uart_base[uartno]+UARTFR_OFFSET)&_BV(UART_RXFE))
+               ;
+       return (uint16_t)HW_REG(uart_base[uartno]+UARTDR_OFFSET);
+}
+
+uint32_t uart_dataavail(uint8_t uartno){
+       if(uartno>UART_MAX){
+               return 0;
+       }
+       /* wait while the FIFO is empty */
+       if(circularbytebuffer_cnt(&(uart_rx_buffer[uartno]))){
+               return 1;
+       }
+       return(HW_REG(uart_base[uartno]+UARTFR_OFFSET)&_BV(UART_RXFE))?0:1;
+}
diff --git a/test_src/uart_i.h b/test_src/uart_i.h
new file mode 100644 (file)
index 0000000..aff5f85
--- /dev/null
@@ -0,0 +1,139 @@
+/* uart_i.h */
+/*
+    This file is part of the AVR-uart_ni.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+/**
+ * \file     uart_i.h
+ * \email    daniel.otte@rub.de
+ * \author   Daniel Otte 
+ * \date     2009-07-24
+ * \license  GPLv3 or later
+ * \ingroup  uart_i
+ * \brief    declaration for non-interrupt uart
+ */
+
+#ifndef UART_I_H_
+#define UART_I_H_
+
+#include "config.h"
+#include "circularbytebuffer.h"
+#include <stdint.h>
+
+typedef struct{
+       circularbytebuffer_t rxb;
+       circularbytebuffer_t txb;       
+#if UART0_HOOK
+       void(*hook)(uint8_t);
+       volatile uint8_t hook_running;
+#endif
+#if UART0_SWFLOWCTRL
+       volatile uint8_t txon;
+       volatile uint8_t rxon;
+#endif
+} uart0_ctx_t;
+
+
+typedef struct{
+       circularbytebuffer_t rxb;
+       circularbytebuffer_t txb;       
+#if UART1_HOOK
+       void(*hook)(uint8_t);
+       volatile uint8_t hook_running;
+#endif
+#if UART1_SWFLOWCTRL
+       volatile uint8_t txon;
+       volatile uint8_t rxon;
+#endif
+} uart1_ctx_t;
+
+#if UART0_I
+
+/** \fn uart0_init(void)
+ * \brief initialize uart0.
+ * This function initializes the first uart according to the parameter specifyed
+ * in config.h .
+ */
+void uart0_init(void);
+
+/** \fn uart0_putc(uint16_t)
+ * \brief send data through uart0.
+ * This function sends data through the first uart 
+ * (the data size is debfined in config.h).
+ * \param c data to send
+ */
+void uart0_putc(uint16_t c);
+
+/** \fn uart0_getc(void)
+ * \brief read data from uart0.
+ * This function reads data from the first uart 
+ * (the data size is debfined in config.h).
+ * \return data recived by uart0
+ */
+uint16_t uart0_getc(void);
+
+/** \fn uart0_dataavail(void)
+ * \brief checks if data is available.
+ * 
+ * This function checks the state of the input buffer of uart0 and
+ * returns if data is available or not.
+ * \return zero if no data is available else a value different from zero is returned
+ */
+uint8_t uart0_dataavail(void);
+
+#if    UART0_HOOK
+void uart0_sethook(void(*fpt)(uint8_t));
+#endif
+
+
+#endif /* UART0_I */
+
+#if UART1_I
+/** \fn uart1_init(void)
+ * \brief initialize uart1.
+ * This function initializes the second uart according to the parameter specifyed
+ * in config.h .
+ */
+void uart1_init(void);
+
+/** \fn uart1_putc(uint16_t)
+ * \brief send data through uart1.
+ * This function sends data through the second uart 
+ * (the data size is debfined in config.h).
+ * \param c data to send
+ */
+void uart1_putc(uint16_t c);
+
+/** \fn uart1_getc(void)
+ * \brief read data from uart1.
+ * This function reads data from the second uart 
+ * (the data size is debfined in config.h).
+ * \return data recived by uart1
+ */
+uint16_t uart1_getc(void);
+
+/** \fn uart1_dataavail(void)
+ * \brief checks if data is available.
+ * This function checks the state of the input buffer of uart1 and
+ * returns if data is available or not.
+ * \return zero if no data is available else a value different from zero is returned
+ */
+uint8_t uart1_dataavail(void);
+
+void uart0_sethook(void(*fpt)(uint8_t));
+#endif
+
+#endif /* UART_I_H_ */
diff --git a/test_src/uart_lowlevel.c b/test_src/uart_lowlevel.c
new file mode 100644 (file)
index 0000000..a0b5091
--- /dev/null
@@ -0,0 +1,174 @@
+/* uart_lowlevel.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
+
+    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 <stdint.h>
+#include "sysclock.h"
+#include "hw_regs.h"
+#include "hw_uart_regs.h"
+#include "uart_defines.h"
+
+void calc_baud_values(uint32_t baudrate, uint16_t* intdivider, uint8_t* fracdivider, uint8_t* highspeed){
+       uint32_t tmp;
+       uint32_t uart_freq;
+       uart_freq = sysclk_get_freq();
+       *highspeed = (baudrate*16>uart_freq)?1:0;
+       tmp = (uint64_t)uart_freq*128/((*highspeed?8:16)*baudrate);
+       tmp++;
+       tmp>>=1;
+       *fracdivider = (uint8_t)(tmp&0x3f);
+       *intdivider = tmp>>6;
+}
+
+static const
+uint32_t uart_base[] = { UART0_BASE, UART1_BASE, UART2_BASE };
+
+static const
+uint32_t gpio_base[] =
+       { GPIOA_BASE, GPIOB_BASE, GPIOC_BASE, GPIOD_BASE,
+         GPIOE_BASE, GPIOF_BASE, GPIOG_BASE, GPIOH_BASE,
+         GPIOJ_BASE,
+       };
+
+static const
+uint8_t uart_tx_gpio[] = { GPIOA, GPIOD, GPIOG };
+static const
+uint8_t uart_rx_gpio[] = { GPIOA, GPIOD, GPIOG };
+static const
+uint8_t uart_tx_pin[] = { 1, 1, 1 };
+static const
+uint8_t uart_rx_pin[] = { 0, 0, 0 };
+static const
+uint8_t uart_tx_pctl[] = {1, 5, 1};
+static const
+uint8_t uart_rx_pctl[] = {1, 5, 1};
+
+uint8_t uart_init(uint8_t uartno, uint32_t baudrate, uint8_t databits, uint8_t paraty, uint8_t stopbits){
+       uint32_t tmp;
+       if(databits>=5){
+               databits-=5;
+       }
+       if(uartno>UART_MAX){
+               return UART_ERROR_WRONG_UART;
+       }
+       if(databits>UART_DATABITS_8){
+               return UART_ERROR_WRONG_DATABITS;
+       }
+       if(paraty>UART_PARATY_SPACE){
+               return UART_ERROR_WRONG_PARATY;
+       }
+       if(stopbits>UART_STOPBITS_TWO){
+               return UART_ERROR_WRONG_STOPBITS;
+       }
+       /* enable clock for uart */
+       HW_REG(SYSCTL_BASE+RCGC1_OFFSET) |= _BV(uartno);
+       /* enable clock for gpio*/
+       HW_REG(SYSCTL_BASE+RCGC2_OFFSET) |= _BV(uart_rx_gpio[uartno]) | _BV(uart_tx_gpio[uartno]);
+    HW_REG(SYSCTL_BASE+RCGC2_OFFSET) |= 1;
+
+    HW_REG(gpio_base[uart_rx_gpio[uartno]] + GPIO_ODR_OFFSET) &= ~_BV(uart_rx_pin[uartno]); /* open drain */
+    HW_REG(gpio_base[uart_tx_gpio[uartno]] + GPIO_ODR_OFFSET) &= ~_BV(uart_tx_pin[uartno]); /* open drain */
+    HW_REG(gpio_base[uart_rx_gpio[uartno]] + GPIO_PUR_OFFSET) &= ~_BV(uart_rx_pin[uartno]); /* pull-up */
+    HW_REG(gpio_base[uart_tx_gpio[uartno]] + GPIO_PUR_OFFSET) &= ~_BV(uart_tx_pin[uartno]); /* pull-up */
+    HW_REG(gpio_base[uart_rx_gpio[uartno]] + GPIO_PDR_OFFSET) &= ~_BV(uart_rx_pin[uartno]); /* pull-down*/
+    HW_REG(gpio_base[uart_tx_gpio[uartno]] + GPIO_PDR_OFFSET) &= ~_BV(uart_tx_pin[uartno]); /* pull-down*/
+    HW_REG(gpio_base[uart_rx_gpio[uartno]] + GPIO_DEN_OFFSET) |=  _BV(uart_rx_pin[uartno]); /* digital enable */
+    HW_REG(gpio_base[uart_tx_gpio[uartno]] + GPIO_DEN_OFFSET) |=  _BV(uart_tx_pin[uartno]); /* digital enable */
+
+       /* switch to alternate function for rx */
+       HW_REG(gpio_base[uart_rx_gpio[uartno]]+GPIO_AFSEL_OFFSET) |= _BV(uart_rx_pin[uartno]);
+        /* switch to alternate function for tx */
+       HW_REG(gpio_base[uart_tx_gpio[uartno]]+GPIO_AFSEL_OFFSET) |= _BV(uart_tx_pin[uartno]);
+       /* switch multiplexer to uart for rx */
+       HW_REG(gpio_base[uart_rx_gpio[uartno]]+GPIO_PCTL_OFFSET) &= ~(0x0f<<(uart_rx_pin[uartno]*4));
+       HW_REG(gpio_base[uart_rx_gpio[uartno]]+GPIO_PCTL_OFFSET) |= ((uart_rx_pctl[uartno])<<(uart_rx_pin[uartno]*4));
+       /* switch multiplexer to uart for tx */
+       HW_REG(gpio_base[uart_tx_gpio[uartno]]+GPIO_PCTL_OFFSET) &= ~(0x0f<<(uart_tx_pin[uartno]*4));
+       HW_REG(gpio_base[uart_tx_gpio[uartno]]+GPIO_PCTL_OFFSET) |= ((uart_tx_pctl[uartno])<<(uart_tx_pin[uartno]*4));
+       /* set pins to be 2mA */
+       HW_REG(gpio_base[uart_rx_gpio[uartno]]+GPIO_DR2R_OFFSET) |= _BV(uart_rx_pin[uartno]);
+       HW_REG(gpio_base[uart_tx_gpio[uartno]]+GPIO_DR2R_OFFSET) |= _BV(uart_tx_pin[uartno]);
+       /* configure rx pin as input */
+       HW_REG(gpio_base[uart_rx_gpio[uartno]]+GPIO_DIR_OFFSET) &= ~_BV(uart_rx_pin[uartno]);
+       /* configure tx pin as output */
+       HW_REG(gpio_base[uart_tx_gpio[uartno]]+GPIO_DIR_OFFSET) |= _BV(uart_tx_pin[uartno]);
+
+       /* disable uart */
+       HW_REG(uart_base[uartno]+UARTCTL_OFFSET) &= ~_BV(UARTEN);
+       /* set baudrate parameters */
+       uint8_t highspeed;
+       calc_baud_values(baudrate,
+                                (uint16_t*)&HW_REG(uart_base[uartno]+UARTIBRD_OFFSET),
+                                (uint8_t*)&HW_REG(uart_base[uartno]+UARTFBRD_OFFSET),
+                                &highspeed);
+       /* wait until uart is no longer busy */
+       while(HW_REG(uart_base[uartno]+UARTFR_OFFSET)&_BV(UART_BUSY))
+               ;
+       /* flush FIFOs */
+       HW_REG(uart_base[uartno]+UARTLCRH_OFFSET) &= ~_BV(UART_FEN);
+       /* set line parameters (bits, paraty, stopbits*/
+       tmp = HW_REG(uart_base[uartno]+UARTLCRH_OFFSET);
+       tmp &= ~0xff;
+       tmp |= (paraty==UART_PARATY_MARK||paraty==UART_PARATY_SPACE)?_BV(7):0; /* set flag for mark or space paraty*/
+       tmp |= databits<<5;
+       tmp |= _BV(UART_FEN); /* enable FIFOs */
+       tmp |= (stopbits==UART_STOPBITS_TWO)?_BV(3):0;
+       tmp |= (paraty==UART_PARATY_EVEN || paraty==UART_PARATY_MARK)?_BV(2):0;
+       tmp |= (paraty!=UART_PARATY_NONE)?_BV(1):0;
+       HW_REG(uart_base[uartno]+UARTLCRH_OFFSET) = tmp;
+       /* set the highspeed bit accordingly */
+       if(highspeed){
+               HW_REG(uart_base[uartno]+UARTCTL_OFFSET) |= _BV(UART_HSE);
+       } else {
+               HW_REG(uart_base[uartno]+UARTCTL_OFFSET) &= ~_BV(UART_HSE);
+       }
+       HW_REG(uart_base[uartno]+UARTFR_OFFSET) = 0;
+       HW_REG(uart_base[uartno]+UARTCTL_OFFSET) |= _BV(UART_RXE) | _BV(UART_TXE);
+       HW_REG(uart_base[uartno]+UARTCTL_OFFSET) |= _BV(UARTEN);
+
+       return UART_ERROR_OK;
+}
+
+
+void uart_putc(uint8_t uartno, uint8_t byte){
+       if(uartno>UART_MAX){
+               return;
+       }
+       /* wait while the FIFO is full */
+       while(HW_REG(uart_base[uartno]+UARTFR_OFFSET)&_BV(UART_TXFF))
+               ;
+       HW_REG(uart_base[uartno]+UARTDR_OFFSET) = (uint32_t)byte;
+}
+
+uint16_t uart_getc(uint8_t uartno){
+       if(uartno>UART_MAX){
+               return 0xffff;
+       }
+       /* wait while the FIFO is empty */
+       while(HW_REG(uart_base[uartno]+UARTFR_OFFSET)&_BV(UART_RXFE))
+               ;
+       return (uint16_t)HW_REG(uart_base[uartno]+UARTDR_OFFSET);
+}
+
+uint32_t uart_dataavail(uint8_t uartno){
+       if(uartno>UART_MAX){
+               return 0;
+       }
+       /* wait while the FIFO is empty */
+       return(HW_REG(uart_base[uartno]+UARTFR_OFFSET)&_BV(UART_RXFE))?0:1;
+}
diff --git a/test_src/uart_lowlevel.h b/test_src/uart_lowlevel.h
new file mode 100644 (file)
index 0000000..476ae97
--- /dev/null
@@ -0,0 +1,35 @@
+/* uart_lowlevel.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
+
+    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/>.
+*/
+
+#ifndef UART_LOWLEVEL_H_
+#define UART_LOWLEVEL_H_
+
+
+#include <stdint.h>
+#include "hw_regs.h"
+#include "hw_uart_regs.h"
+#include "uart_defines.h"
+
+uint8_t uart_init(uint8_t uartno, uint32_t baudrate, uint8_t databits, uint8_t paraty, uint8_t stopbits);
+
+void uart_putc(uint8_t uartno, uint8_t byte);
+uint16_t uart_getc(uint8_t uartno);
+uint32_t uart_dataavail(uint8_t uartno);
+
+#endif /* UART_LOWLEVEL_H_ */