diff options
Diffstat (limited to 'pyecsca/codegen')
32 files changed, 912 insertions, 29 deletions
diff --git a/pyecsca/codegen/Makefile b/pyecsca/codegen/Makefile index 50c1940..d99a1ce 100644 --- a/pyecsca/codegen/Makefile +++ b/pyecsca/codegen/Makefile @@ -1,12 +1,14 @@ TARGET = pyecsca-codegen -SRC += main.c ecdh.c ecdsa.c hash/hash.c +SRC += main.c bn.c ecdh.c ecdsa.c hash/hash.c prng/prng.c -CDEFS += -DHASH=HASH_SHA1 +CDEFS += -DHASH=HASH_SHA224 -MKDIR_LIST += hash +MKDIR_LIST += hash prng -EXTRAINCDIRS += hash +EXTRAINCDIRS += hash prng ../../ext/libtommath/ + +LDFLAGS += ../../ext/libtommath/libtommath.a include simpleserial/Makefile.simpleserial diff --git a/pyecsca/codegen/bn.c b/pyecsca/codegen/bn.c new file mode 100644 index 0000000..dfd433a --- /dev/null +++ b/pyecsca/codegen/bn.c @@ -0,0 +1,9 @@ +#include "bn.h" + +bn_err bn_init(bn_t *bn) { + return mp_init(bn); +} + +void bn_clear(bn_t *bn) { + mp_clear(bn); +}
\ No newline at end of file diff --git a/pyecsca/codegen/bn.h b/pyecsca/codegen/bn.h index 01519c1..ff0ba37 100644 --- a/pyecsca/codegen/bn.h +++ b/pyecsca/codegen/bn.h @@ -1,17 +1,18 @@ #ifndef BN_H_ #define BN_H_ -//bn_t definition is variable -//BN_SIZE definition is variable +#include <tommath.h> + +#define bn_t mp_int +#define bn_err mp_err typedef struct { char name; bn_t value; } named_bn_t; -//heap based -bn_t *bn_new(); -void bn_free(bn_t *bn);) +bn_err bn_init(bn_t *bn); +void bn_clear(bn_t *bn); int bn_from_hex(const char *data, bn_t *out); int bn_from_int(uint64_t value, bn_t *out); @@ -22,5 +23,6 @@ void bn_mod_div(bn_t *one, bn_t *other, bn_t *mod, bn_t *out); void bn_mod_inv(bn_t *one, bn_t *mod, bn_t *out); int bn_get_bit(bn_t *bn, int which); void bn_set_bit(bn_t *bn, int which, int value); +int bn_bit_length(bn_t *bn); #endif //BN_H_
\ No newline at end of file diff --git a/pyecsca/codegen/coords.h b/pyecsca/codegen/coords.h index 9f3323d..751aeb6 100644 --- a/pyecsca/codegen/coords.h +++ b/pyecsca/codegen/coords.h @@ -10,6 +10,14 @@ typedef struct { } point_t; */ +point_t *point_new(); + +point_t *point_copy(const point_t *from); + +void point_set(const point_t *from, point_t *out); + +void point_free(point_t *point); + int point_to_affine(point_t *point, const char coord, curve_t *curve, bn_t *out); int point_from_affine(bn_t *x, bn_t *y, curve_t *curve, point_t *out); diff --git a/pyecsca/codegen/curve.h b/pyecsca/codegen/curve.h index 5ac7b1a..81eb526 100644 --- a/pyecsca/codegen/curve.h +++ b/pyecsca/codegen/curve.h @@ -4,8 +4,8 @@ //curve_t definition is variable /* typedef struct { - bn_t a; - bn_t b; + bn_t n; + point_t *neutral; } curve_t; */ diff --git a/pyecsca/codegen/formulas.h b/pyecsca/codegen/formulas.h index 1566f98..6cd6120 100644 --- a/pyecsca/codegen/formulas.h +++ b/pyecsca/codegen/formulas.h @@ -1,16 +1,16 @@ #ifndef FORMULAS_H_ #define FORMULAS_H_ -int point_add(point_t *one, point_t *other, curve_t *curve, point_t *out); +int point_add(const point_t *one, const point_t *other, const curve_t *curve, point_t *out); -int point_dbl(point_t *one, curve_t *curve, point_t *out); +int point_dbl(const point_t *one, const curve_t *curve, point_t *out); -int point_neg(point_t *one, curve_t *curve, point_t *out); +int point_neg(const point_t *one, const curve_t *curve, point_t *out); -int point_scl(point_t *one, curve_t *curve, point_t *out); +int point_scl(const point_t *one, const curve_t *curve, point_t *out); -int point_dadd(point_t *one, point_t *other, point_t *diff, curve_t *curve, point_t *out); +int point_dadd(const point_t *one, const point_t *other, const point_t *diff, const curve_t *curve, point_t *out); -int point_ldr(point_t *one, point_t *other, point_t *diff, curve_t *curve, point_t *out_one, point_t *out_other); +int point_ldr(const point_t *one, const point_t *other, const point_t *diff, const curve_t *curve, point_t *out_one, point_t *out_other); #endif //FORMULAS_H_
\ No newline at end of file diff --git a/pyecsca/codegen/hal/Makefile.hal b/pyecsca/codegen/hal/Makefile.hal index 14d4c97..3c81d00 100644 --- a/pyecsca/codegen/hal/Makefile.hal +++ b/pyecsca/codegen/hal/Makefile.hal @@ -20,6 +20,8 @@ define KNOWN_PLATFORMS +-------------------------------------------------------+ | CW308_STM32F3 | CW308T-STM32F3 (ST Micro STM32F3) | +-------------------------------------------------------+ +| HOST | Host machine | ++-------------------------------------------------------+ endef @@ -44,6 +46,9 @@ else ifeq ($(PLATFORM),CW308_STM32F0) else ifeq ($(PLATFORM),CW308_STM32F3) HAL = stm32f3 PLTNAME = CW308T: STM32F3 Target +else ifeq ($(PLATFORM),HOST) + HAL = host + PLTNAME = HOST: Host machine target else $(error Invalid or empty PLATFORM: $(PLATFORM). Known platforms: $(KNOWN_PLATFORMS)) endif diff --git a/pyecsca/codegen/hal/hal.h b/pyecsca/codegen/hal/hal.h index 831276f..b14dacf 100644 --- a/pyecsca/codegen/hal/hal.h +++ b/pyecsca/codegen/hal/hal.h @@ -24,6 +24,7 @@ void platform_init(void); #define HAL_xmega 1 #define HAL_stm32f0 2 #define HAL_stm32f3 3 +#define HAL_host 4 #if HAL == HAL_xmega #include <avr/io.h> @@ -34,6 +35,8 @@ void platform_init(void); #include "stm32f0/stm32f0_hal.h" #elif HAL == HAL_stm32f3 #include "stm32f3/stm32f3_hal.h" +#elif HAL == HAL_host + #include "host/host_hal.h" #else #error "Unsupported HAL Type" #endif diff --git a/pyecsca/codegen/hal/host/Makefile.host b/pyecsca/codegen/hal/host/Makefile.host new file mode 100644 index 0000000..933c899 --- /dev/null +++ b/pyecsca/codegen/hal/host/Makefile.host @@ -0,0 +1,10 @@ +VPATH += :$(HALPATH)/host +SRC += uart.c host_hal.c +EXTRAINCDIRS += $(HALPATH)/host + +CC = gcc +OBJCOPY = objcopy +OBJDUMP = objdump +SIZE = size +AR = ar rcs +NM = nm
\ No newline at end of file diff --git a/pyecsca/codegen/hal/host/host_hal.c b/pyecsca/codegen/hal/host/host_hal.c new file mode 100644 index 0000000..fe71aab --- /dev/null +++ b/pyecsca/codegen/hal/host/host_hal.c @@ -0,0 +1,2 @@ + +void platform_init(void) {}
\ No newline at end of file diff --git a/pyecsca/codegen/hal/host/host_hal.h b/pyecsca/codegen/hal/host/host_hal.h new file mode 100644 index 0000000..b78172c --- /dev/null +++ b/pyecsca/codegen/hal/host/host_hal.h @@ -0,0 +1,14 @@ +#ifndef HOST_HAL_H_ +#define HOST_HAL_H_ + +#include "uart.h" + +#define trigger_setup() +#define trigger_high() +#define trigger_low() + +#define init_uart init_uart0 +#define putch output_ch_0 +#define getch input_ch_0 + +#endif //HOST_HAL_H_ diff --git a/pyecsca/codegen/hal/host/uart.c b/pyecsca/codegen/hal/host/uart.c new file mode 100644 index 0000000..3931d6d --- /dev/null +++ b/pyecsca/codegen/hal/host/uart.c @@ -0,0 +1,7 @@ +#include "uart.h" + +void init_uart0(void) {} + +char input_ch_0(void) { return getchar(); } + +void output_ch_0(char data) { putchar(data); }
\ No newline at end of file diff --git a/pyecsca/codegen/hal/host/uart.h b/pyecsca/codegen/hal/host/uart.h new file mode 100644 index 0000000..d6063bc --- /dev/null +++ b/pyecsca/codegen/hal/host/uart.h @@ -0,0 +1,13 @@ +#ifndef UART_H_ +#define UART_H_ + +#include <stdio.h> + + +void init_uart0(void); + +char input_ch_0(void); + +void output_ch_0(char data); + +#endif //UART_H_
\ No newline at end of file diff --git a/pyecsca/codegen/hash/sha1.c b/pyecsca/codegen/hash/sha1.c index 8ef9723..cf6ca3e 100644 --- a/pyecsca/codegen/hash/sha1.c +++ b/pyecsca/codegen/hash/sha1.c @@ -24,7 +24,9 @@ #include <stdlib.h> #include "sha1.h" +#ifndef LITTLE_ENDIAN #define LITTLE_ENDIAN +#endif /********************************************************************************************************/ diff --git a/pyecsca/codegen/hash/sha2.c b/pyecsca/codegen/hash/sha2.c index fb33650..d2ddf6f 100644 --- a/pyecsca/codegen/hash/sha2.c +++ b/pyecsca/codegen/hash/sha2.c @@ -49,7 +49,9 @@ #define CH(x,y,z) (((x)&(y)) ^ ((~(x))&(z))) #define MAJ(x,y,z) (((x)&(y)) ^ ((x)&(z)) ^ ((y)&(z))) +#ifndef LITTLE_ENDIAN #define LITTLE_ENDIAN +#endif #if HASH == HASH_SHA224 || HASH == HASH_SHA256 #define SIGMA_0(x) (rotr32((x), 2) ^ rotr32((x),13) ^ rotl32((x),10)) diff --git a/pyecsca/codegen/main.c b/pyecsca/codegen/main.c index 65cf444..fba5dc2 100644 --- a/pyecsca/codegen/main.c +++ b/pyecsca/codegen/main.c @@ -4,22 +4,22 @@ #include "hal/hal.h" #include "simpleserial/simpleserial.h" #include "hash/hash.h" +#include "bn.h" +#include "prng.h" +#include <string.h> -uint8_t cmd_set_curve(uint8_t *data, uint16_t len) { +uint8_t cmd_init_prng(uint8_t *data, uint16_t len) { + prng_seed(data, len); return 0; } int main(void) { platform_init(); + prng_init(); init_uart(); trigger_setup(); simpleserial_init(); - void *ctx = hash_new_ctx(); - uint8_t thing[10] = {1,2,3,4,5,6,7,8,9,10}; - uint8_t out[hash_size(10)]; - hash_init(ctx); - hash_final(ctx, 10, thing, out); - simpleserial_addcmd('a', 256, cmd_set_curve); + simpleserial_addcmd('i', 4, cmd_init_prng); while(1) simpleserial_get(); return 0; diff --git a/pyecsca/codegen/mult/double_and_add.c b/pyecsca/codegen/mult/double_and_add.c index 91ad6e3..1fd3c9e 100644 --- a/pyecsca/codegen/mult/double_and_add.c +++ b/pyecsca/codegen/mult/double_and_add.c @@ -1,5 +1,18 @@ #include "mult.h" void scalar_mult(bn_t *scalar, point_t *point, curve_t *curve, point_t *out) { - + point_t *q = point_copy(point); + point_t *r = point_copy(curve->neutral); + + int nbits = bn_bit_length(curve->n); + for (int i = nbits; i >= 0; i--) { + point_dbl(r, curve, r); + if (bn_get_bit(scalar, i) == 1) { + point_add(q, r, curve, r); + } + } + point_scl(r, curve, r); + point_set(r, out); + point_free(q); + point_free(r); }
\ No newline at end of file diff --git a/pyecsca/codegen/prng/KeccakDuplex-common.h b/pyecsca/codegen/prng/KeccakDuplex-common.h new file mode 100644 index 0000000..6371611 --- /dev/null +++ b/pyecsca/codegen/prng/KeccakDuplex-common.h @@ -0,0 +1,37 @@ +/* +Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, +Michaël Peeters, Gilles Van Assche and Ronny Van Keer, +hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _KeccakDuplexCommon_h_ +#define _KeccakDuplexCommon_h_ + +#include "align.h" + +#define KCP_DeclareDuplexStructure(prefix, size, alignment) \ + ALIGN(alignment) typedef struct prefix##_DuplexInstanceStruct { \ + unsigned char state[size]; \ + unsigned int rate; \ + unsigned int byteInputIndex; \ + unsigned int byteOutputIndex; \ + } prefix##_DuplexInstance; + +#define KCP_DeclareDuplexFunctions(prefix) \ + int prefix##_DuplexInitialize(prefix##_DuplexInstance *duplexInstance, unsigned int rate, unsigned int capacity); \ + int prefix##_Duplexing(prefix##_DuplexInstance *duplexInstance, const unsigned char *sigmaBegin, unsigned int sigmaBeginByteLen, unsigned char *Z, unsigned int ZByteLen, unsigned char delimitedSigmaEnd); \ + int prefix##_DuplexingFeedPartialInput(prefix##_DuplexInstance *duplexInstance, const unsigned char *input, unsigned int inputByteLen); \ + int prefix##_DuplexingFeedZeroes(prefix##_DuplexInstance *duplexInstance, unsigned int inputByteLen); \ + int prefix##_DuplexingOverwritePartialInput(prefix##_DuplexInstance *duplexInstance, const unsigned char *input, unsigned int inputByteLen); \ + int prefix##_DuplexingOverwriteWithZeroes(prefix##_DuplexInstance *duplexInstance, unsigned int inputByteLen); \ + int prefix##_DuplexingGetFurtherOutput(prefix##_DuplexInstance *duplexInstance, unsigned char *out, unsigned int outByteLen); \ + int prefix##_DuplexingGetFurtherOutputAndAdd(prefix##_DuplexInstance *duplexInstance, const unsigned char *input, unsigned char *output, unsigned int outputByteLen); + +#endif diff --git a/pyecsca/codegen/prng/KeccakDuplex.inc b/pyecsca/codegen/prng/KeccakDuplex.inc new file mode 100644 index 0000000..bd58043 --- /dev/null +++ b/pyecsca/codegen/prng/KeccakDuplex.inc @@ -0,0 +1,192 @@ +/* +Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, +Michaël Peeters, Gilles Van Assche and Ronny Van Keer, +hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#define JOIN0(a, b) a ## b +#define JOIN(a, b) JOIN0(a, b) + +#define DuplexInstance JOIN(prefix, _DuplexInstance) +#define DuplexInitialize JOIN(prefix, _DuplexInitialize) +#define Duplexing JOIN(prefix, _Duplexing) +#define DuplexingFeedPartialInput JOIN(prefix, _DuplexingFeedPartialInput) +#define DuplexingFeedZeroes JOIN(prefix, _DuplexingFeedZeroes) +#define DuplexingOverwritePartialInput JOIN(prefix, _DuplexingOverwritePartialInput) +#define DuplexingOverwriteWithZeroes JOIN(prefix, _DuplexingOverwriteWithZeroes) +#define DuplexingGetFurtherOutput JOIN(prefix, _DuplexingGetFurtherOutput) +#define DuplexingGetFurtherOutputAndAdd JOIN(prefix, _DuplexingGetFurtherOutputAndAdd) + +#define SnP_stateSizeInBytes JOIN(SnP, _stateSizeInBytes) +#define SnP_stateAlignment JOIN(SnP, _stateAlignment) +#define SnP_StaticInitialize JOIN(SnP, _StaticInitialize) +#define SnP_Initialize JOIN(SnP, _Initialize) +#define SnP_AddByte JOIN(SnP, _AddByte) +#define SnP_AddBytes JOIN(SnP, _AddBytes) +#define SnP_OverwriteBytes JOIN(SnP, _OverwriteBytes) +#define SnP_OverwriteWithZeroes JOIN(SnP, _OverwriteWithZeroes) +#define SnP_ExtractBytes JOIN(SnP, _ExtractBytes) +#define SnP_ExtractAndAddBytes JOIN(SnP, _ExtractAndAddBytes) + +int DuplexInitialize(DuplexInstance *instance, unsigned int rate, unsigned int capacity) +{ + if (rate+capacity != SnP_width) + return 1; + if ((rate <= 2) || (rate > SnP_width)) + return 1; + SnP_StaticInitialize(); + instance->rate = rate; + SnP_Initialize(instance->state); + instance->byteInputIndex = 0; + instance->byteOutputIndex = (instance->rate+7)/8; + return 0; +} + +int Duplexing(DuplexInstance *instance, const unsigned char *sigmaBegin, unsigned int sigmaBeginByteLen, unsigned char *Z, unsigned int ZByteLen, unsigned char delimitedSigmaEnd) +{ + const unsigned int rho_max = instance->rate - 2; + + if (delimitedSigmaEnd == 0) + return 1; + if ((instance->byteInputIndex+sigmaBeginByteLen)*8 > rho_max) + return 1; + if (rho_max - sigmaBeginByteLen*8 < 7) { + unsigned int maxBitsInDelimitedSigmaEnd = rho_max - sigmaBeginByteLen*8; + if (delimitedSigmaEnd >= (1 << (maxBitsInDelimitedSigmaEnd+1))) + return 1; + } + if (ZByteLen > (instance->rate+7)/8) + return 1; /* The output length must not be greater than the rate (rounded up to a byte) */ + + SnP_AddBytes(instance->state, sigmaBegin, instance->byteInputIndex, sigmaBeginByteLen); + #ifdef KeccakReference + { + unsigned char block[SnP_width/8]; + memcpy(block, sigmaBegin, sigmaBeginByteLen); + block[sigmaBeginByteLen] = delimitedSigmaEnd; + memset(block+sigmaBeginByteLen+1, 0, sizeof(block)-sigmaBeginByteLen-1); + block[(instance->rate-1)/8] |= 1 << ((instance->rate-1) % 8); + displayBytes(1, "Block to be absorbed (after padding)", block, (instance->rate+7)/8); + } + #endif + + /* Last few bits, whose delimiter coincides with first bit of padding */ + SnP_AddByte(instance->state, delimitedSigmaEnd, instance->byteInputIndex+sigmaBeginByteLen); + /* Second bit of padding */ + SnP_AddByte(instance->state, (unsigned char)1 << ((instance->rate - 1)%8), (instance->rate - 1)/8); + SnP_Permute(instance->state); + SnP_ExtractBytes(instance->state, Z, 0, ZByteLen); + + if (ZByteLen*8 > instance->rate) { + unsigned char mask = (unsigned char)(1 << (instance->rate % 8)) - 1; + Z[ZByteLen-1] &= mask; + } + + instance->byteInputIndex = 0; + instance->byteOutputIndex = ZByteLen; + + return 0; +} + +int DuplexingFeedPartialInput(DuplexInstance *instance, const unsigned char *input, unsigned int inputByteLen) +{ + const unsigned int rho_max = instance->rate - 2; + + if ((instance->byteInputIndex+inputByteLen)*8 > rho_max) + return 1; + + SnP_AddBytes(instance->state, input, instance->byteInputIndex, inputByteLen); + instance->byteInputIndex += inputByteLen; + return 0; +} + +int DuplexingFeedZeroes(DuplexInstance *instance, unsigned int inputByteLen) +{ + const unsigned int rho_max = instance->rate - 2; + + if ((instance->byteInputIndex+inputByteLen)*8 > rho_max) + return 1; + + instance->byteInputIndex += inputByteLen; + return 0; +} + +int DuplexingOverwritePartialInput(DuplexInstance *instance, const unsigned char *input, unsigned int inputByteLen) +{ + const unsigned int rho_max = instance->rate - 2; + + if ((instance->byteInputIndex+inputByteLen)*8 > rho_max) + return 1; + + SnP_OverwriteBytes(instance->state, input, instance->byteInputIndex, inputByteLen); + instance->byteInputIndex += inputByteLen; + return 0; +} + +int DuplexingOverwriteWithZeroes(DuplexInstance *instance, unsigned int inputByteLen) +{ + const unsigned int rho_max = instance->rate - 2; + + if ((instance->byteInputIndex != 0) || (inputByteLen*8 > rho_max)) + return 1; + + SnP_OverwriteWithZeroes(instance->state, inputByteLen); + instance->byteInputIndex = inputByteLen; + + return 0; +} + +int DuplexingGetFurtherOutput(DuplexInstance *instance, unsigned char *output, unsigned int outputByteLen) +{ + if ((outputByteLen+instance->byteOutputIndex) > (instance->rate+7)/8) + return 1; /* The output length must not be greater than the rate (rounded up to a byte) */ + + SnP_ExtractBytes(instance->state, output, instance->byteOutputIndex, outputByteLen); + instance->byteOutputIndex += outputByteLen; + if (instance->byteOutputIndex*8 > instance->rate) { + unsigned char mask = (1 << (instance->rate % 8)) - 1; + output[outputByteLen-1] &= mask; + } + return 0; +} + +int DuplexingGetFurtherOutputAndAdd(DuplexInstance *instance, const unsigned char *input, unsigned char *output, unsigned int outputByteLen) +{ + if ((outputByteLen+instance->byteOutputIndex) > (instance->rate+7)/8) + return 1; /* The output length must not be greater than the rate (rounded up to a byte) */ + + SnP_ExtractAndAddBytes(instance->state, input, output, instance->byteOutputIndex, outputByteLen); + instance->byteOutputIndex += outputByteLen; + if (instance->byteOutputIndex*8 > instance->rate) { + unsigned char mask = (1 << (instance->rate % 8)) - 1; + output[outputByteLen-1] &= mask; + } + return 0; +} + +#undef DuplexInstance +#undef DuplexInitialize +#undef Duplexing +#undef DuplexingFeedPartialInput +#undef DuplexingFeedZeroes +#undef DuplexingOverwritePartialInput +#undef DuplexingOverwriteWithZeroes +#undef DuplexingGetFurtherOutput +#undef DuplexingGetFurtherOutputAndAdd +#undef SnP_stateSizeInBytes +#undef SnP_stateAlignment +#undef SnP_StaticInitialize +#undef SnP_Initialize +#undef SnP_AddByte +#undef SnP_AddBytes +#undef SnP_OverwriteBytes +#undef SnP_OverwriteWithZeroes +#undef SnP_ExtractBytes +#undef SnP_ExtractAndAddBytes diff --git a/pyecsca/codegen/prng/KeccakDuplexWidth200.c b/pyecsca/codegen/prng/KeccakDuplexWidth200.c new file mode 100644 index 0000000..d6f56d2 --- /dev/null +++ b/pyecsca/codegen/prng/KeccakDuplexWidth200.c @@ -0,0 +1,29 @@ +/* +Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, +Michaël Peeters, Gilles Van Assche and Ronny Van Keer, +hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#include "KeccakDuplexWidth200.h" + +#ifndef KeccakP200_excluded + #include "KeccakP-200-SnP.h" + + #define prefix KeccakWidth200 + #define SnP KeccakP200 + #define SnP_width 200 + #define SnP_Permute KeccakP200_Permute_18rounds + #include "KeccakDuplex.inc" + #undef prefix + #undef SnP + #undef SnP_width + #undef SnP_Permute + #undef SnP_FastLoop_Absorb +#endif diff --git a/pyecsca/codegen/prng/KeccakDuplexWidth200.h b/pyecsca/codegen/prng/KeccakDuplexWidth200.h new file mode 100644 index 0000000..8bb76f4 --- /dev/null +++ b/pyecsca/codegen/prng/KeccakDuplexWidth200.h @@ -0,0 +1,25 @@ +/* +Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, +Michaël Peeters, Gilles Van Assche and Ronny Van Keer, +hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _KeccakDuplexWidth200_h_ +#define _KeccakDuplexWidth200_h_ + +#include "KeccakDuplex-common.h" + +#ifndef KeccakP200_excluded + #include "KeccakP-200-SnP.h" + KCP_DeclareDuplexStructure(KeccakWidth200, KeccakP200_stateSizeInBytes, KeccakP200_stateAlignment) + KCP_DeclareDuplexFunctions(KeccakWidth200) +#endif + +#endif diff --git a/pyecsca/codegen/prng/KeccakP-200-SnP.h b/pyecsca/codegen/prng/KeccakP-200-SnP.h new file mode 100644 index 0000000..4acf932 --- /dev/null +++ b/pyecsca/codegen/prng/KeccakP-200-SnP.h @@ -0,0 +1,34 @@ +/* +Implementation by Ronny Van Keer, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ + +--- + +Please refer to SnP-documentation.h for more details. +*/ + +#ifndef _KeccakP_200_SnP_h_ +#define _KeccakP_200_SnP_h_ + +#define KeccakP200_implementation "8-bit compact implementation" +#define KeccakP200_stateSizeInBytes 25 +#define KeccakP200_stateAlignment 1 + +#define KeccakP200_StaticInitialize() +void KeccakP200_Initialize(void *state); +void KeccakP200_AddByte(void *state, unsigned char data, unsigned int offset); +void KeccakP200_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP200_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP200_OverwriteWithZeroes(void *state, unsigned int byteCount); +void KeccakP200_Permute_Nrounds(void *state, unsigned int nrounds); +void KeccakP200_Permute_18rounds(void *state); +void KeccakP200_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP200_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length); + +#endif diff --git a/pyecsca/codegen/prng/KeccakP-200-compact.c b/pyecsca/codegen/prng/KeccakP-200-compact.c new file mode 100644 index 0000000..42c972b --- /dev/null +++ b/pyecsca/codegen/prng/KeccakP-200-compact.c @@ -0,0 +1,185 @@ +/* +Implementation by Ronny Van Keer, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ + +--- + +This file implements Keccak-p[200] in a SnP-compatible way. +Please refer to SnP-documentation.h for more details. + +This implementation comes with KeccakP-200-SnP.h in the same folder. +Please refer to LowLevel.build for the exact list of other files it must be combined with. +*/ + +#include <string.h> +#include <stdlib.h> +#include "KeccakP-200-SnP.h" + +// #define DIVISION_INSTRUCTION /* comment if no division instruction or more compact when not using division */ +#define UNROLL_CHILOOP /* comment if more compact using for loop */ + +typedef unsigned char UINT8; +typedef unsigned int tSmallUInt; /*INFO It could be more optimized to use "unsigned char" on an 8-bit CPU */ +typedef UINT8 tKeccakLane; + +#define ROL8(a, offset) (UINT8)((((UINT8)a) << (offset&7)) ^ (((UINT8)a) >> (8-(offset&7)))) + +const UINT8 KeccakP200_RotationConstants[25] = +{ + 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 +}; + +const UINT8 KeccakP200_PiLane[25] = +{ + 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 +}; + +#if defined(DIVISION_INSTRUCTION) +#define MOD5(argValue) ((argValue) % 5) +#else +const UINT8 KeccakP200_Mod5[10] = +{ + 0, 1, 2, 3, 4, 0, 1, 2, 3, 4 +}; +#define MOD5(argValue) KeccakP200_Mod5[argValue] +#endif + +const UINT8 KeccakF200_RoundConstants[] = +{ + 0x01, 0x82, 0x8a, 0x00, 0x8b, 0x01, 0x81, 0x09, 0x8a, 0x88, 0x09, 0x0a, 0x8b, 0x8b, 0x89, 0x03, 0x02, 0x80 +}; + +/* ---------------------------------------------------------------- */ + +void KeccakP200_Initialize(void *argState) +{ + memset( argState, 0, 25 * sizeof(tKeccakLane) ); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP200_AddByte(void *argState, unsigned char byte, unsigned int offset) +{ + ((tKeccakLane*)argState)[offset] ^= byte; +} + +/* ---------------------------------------------------------------- */ + +void KeccakP200_AddBytes(void *argState, const unsigned char *data, unsigned int offset, unsigned int length) +{ + tSmallUInt i; + tKeccakLane * state = (tKeccakLane*)argState + offset; + for(i=0; i<length; i++) + state[i] ^= data[i]; +} + +/* ---------------------------------------------------------------- */ + +void KeccakP200_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length) +{ + memcpy((unsigned char*)state+offset, data, length); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP200_OverwriteWithZeroes(void *state, unsigned int byteCount) +{ + memset(state, 0, byteCount); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP200_Permute_Nrounds(void *argState, unsigned int nr) +{ + tSmallUInt x, y; + tKeccakLane temp; + tKeccakLane BC[5]; + tKeccakLane *state; + const tKeccakLane *rc; + + state = (tKeccakLane*)argState; + rc = KeccakF200_RoundConstants + 18 - nr; + do + { + /* Theta */ + for ( x = 0; x < 5; ++x ) + { + BC[x] = state[x] ^ state[5 + x] ^ state[10 + x] ^ state[15 + x] ^ state[20 + x]; + } + for ( x = 0; x < 5; ++x ) + { + temp = BC[MOD5(x+4)] ^ ROL8(BC[MOD5(x+1)], 1); + for ( y = 0; y < 25; y += 5 ) + { + state[y + x] ^= temp; + } + } + + /* Rho Pi */ + temp = state[1]; + for ( x = 0; x < 24; ++x ) + { + BC[0] = state[KeccakP200_PiLane[x]]; + state[KeccakP200_PiLane[x]] = ROL8( temp, KeccakP200_RotationConstants[x] ); + temp = BC[0]; + } + + /* Chi */ + for ( y = 0; y < 25; y += 5 ) + { +#if defined(UNROLL_CHILOOP) + BC[0] = state[y + 0]; + BC[1] = state[y + 1]; + BC[2] = state[y + 2]; + BC[3] = state[y + 3]; + BC[4] = state[y + 4]; +#else + for ( x = 0; x < 5; ++x ) + { + BC[x] = state[y + x]; + } +#endif + for ( x = 0; x < 5; ++x ) + { + state[y + x] = BC[x] ^((~BC[MOD5(x+1)]) & BC[MOD5(x+2)]); + } + } + + /* Iota */ + temp = *(rc++); + state[0] ^= temp; + } + while( temp != 0x80 ); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP200_Permute_18rounds(void *argState) +{ + KeccakP200_Permute_Nrounds(argState, 18); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP200_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length) +{ + memcpy(data, (UINT8*)state+offset, length); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP200_ExtractAndAddBytes(const void *argState, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) +{ + unsigned int i; + tKeccakLane * state = (tKeccakLane*)argState + offset; + for(i=0; i<length; i++) + output[i] = input[i] ^ state[i]; +} + +/* ---------------------------------------------------------------- */ diff --git a/pyecsca/codegen/prng/KeccakPRG-common.h b/pyecsca/codegen/prng/KeccakPRG-common.h new file mode 100644 index 0000000..eca5d2e --- /dev/null +++ b/pyecsca/codegen/prng/KeccakPRG-common.h @@ -0,0 +1,28 @@ +/* +Implementation by Gilles Van Assche, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _KeccakPRGCommon_h_ +#define _KeccakPRGCommon_h_ + +#include "align.h" + +#define KCP_DeclareSpongePRG_Structure(prefix, size, alignment) \ + ALIGN(alignment) typedef struct prefix##_SpongePRG_InstanceStruct { \ + prefix##_DuplexInstance duplex; \ + } prefix##_SpongePRG_Instance; + +#define KCP_DeclareSpongePRG_Functions(prefix) \ + int prefix##_SpongePRG_Initialize(prefix##_SpongePRG_Instance *instance, unsigned int capacity); \ + int prefix##_SpongePRG_Feed(prefix##_SpongePRG_Instance *instance, const unsigned char *input, unsigned int inputByteLen); \ + int prefix##_SpongePRG_Fetch(prefix##_SpongePRG_Instance *Instance, unsigned char *out, unsigned int outByteLen); \ + int prefix##_SpongePRG_Forget(prefix##_SpongePRG_Instance *instance); + +#endif diff --git a/pyecsca/codegen/prng/KeccakPRG.h b/pyecsca/codegen/prng/KeccakPRG.h new file mode 100644 index 0000000..83a2144 --- /dev/null +++ b/pyecsca/codegen/prng/KeccakPRG.h @@ -0,0 +1,20 @@ +/* +Implementation by Gilles Van Assche, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _KeccakPRG_h_ +#define _KeccakPRG_h_ + +/* For the documentation, please follow the link: */ +/* #include "KeccakPRG-documentation.h" */ + +#include "KeccakPRGWidth200.h" + +#endif diff --git a/pyecsca/codegen/prng/KeccakPRG.inc b/pyecsca/codegen/prng/KeccakPRG.inc new file mode 100644 index 0000000..aa65db0 --- /dev/null +++ b/pyecsca/codegen/prng/KeccakPRG.inc @@ -0,0 +1,123 @@ +/* +Implementation by Gilles Van Assche, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#define JOIN0(a, b) a ## b +#define JOIN(a, b) JOIN0(a, b) + +#define SpongePRG_Instance JOIN(prefix, _SpongePRG_Instance) +#define SpongePRG_Initialize JOIN(prefix, _SpongePRG_Initialize) +#define SpongePRG_Feed JOIN(prefix, _SpongePRG_Feed) +#define SpongePRG_Fetch JOIN(prefix, _SpongePRG_Fetch) +#define SpongePRG_Forget JOIN(prefix, _SpongePRG_Forget) + +#define DuplexInstance JOIN(prefix, _DuplexInstance) +#define DuplexInitialize JOIN(prefix, _DuplexInitialize) +#define Duplexing JOIN(prefix, _Duplexing) +#define DuplexingFeedPartialInput JOIN(prefix, _DuplexingFeedPartialInput) +#define DuplexingOverwriteWithZeroes JOIN(prefix, _DuplexingOverwriteWithZeroes) +#define DuplexingGetFurtherOutput JOIN(prefix, _DuplexingGetFurtherOutput) +#define DuplexGetInputIndex(duplex) (duplex)->byteInputIndex +#define DuplexGetOutputIndex(duplex) (duplex)->byteOutputIndex +#define DuplexSetOutputIndex(duplex, i) (duplex)->byteOutputIndex = (i) + +int SpongePRG_Initialize(SpongePRG_Instance *instance, unsigned int capacity) +{ + unsigned int rate; + unsigned int rhoInBytes; + + if (capacity > (SnP_width-10)) + return 1; + + rate = SnP_width - capacity; + rhoInBytes = (rate-2)/8; + + if ( (rhoInBytes == 0) || (rhoInBytes >= SnP_width/8) ) + return 1; + return DuplexInitialize(&instance->duplex, rate, capacity); +} + +int SpongePRG_Feed(SpongePRG_Instance *instance, const unsigned char *input, unsigned int inputByteLen) +{ + unsigned int rhoInBytes = (instance->duplex.rate-2)/8; + int error = 0; + + while( !error && ((DuplexGetInputIndex(&instance->duplex) + inputByteLen) >= rhoInBytes)) { + unsigned int localSize = rhoInBytes - DuplexGetInputIndex(&instance->duplex); + error |= DuplexingFeedPartialInput(&instance->duplex, input, localSize); + error |= Duplexing(&instance->duplex, 0, 0, 0, 0, 0x01); + input += localSize; + inputByteLen -= localSize; + } + if (!error) + error = DuplexingFeedPartialInput(&instance->duplex, input, inputByteLen); + DuplexSetOutputIndex(&instance->duplex, rhoInBytes); + return error; +} + +int SpongePRG_Fetch(SpongePRG_Instance *instance, unsigned char *output, unsigned int outputByteLen) +{ + unsigned int rhoInBytes = (instance->duplex.rate-2)/8; + int error = 0; + + if (DuplexGetOutputIndex(&instance->duplex) < rhoInBytes) { + unsigned int localSize = rhoInBytes - DuplexGetOutputIndex(&instance->duplex); + localSize = (localSize <= outputByteLen) ? localSize : outputByteLen; + error = DuplexingGetFurtherOutput(&instance->duplex, output, localSize); + output += localSize; + outputByteLen -= localSize; + } + + while( !error && (outputByteLen > 0) ) { + error = Duplexing(&instance->duplex, 0, 0, 0, 0, 0x01); + if (!error) { + unsigned int localSize = (rhoInBytes <= outputByteLen) ? rhoInBytes : outputByteLen; + error = DuplexingGetFurtherOutput(&instance->duplex, output, localSize); + output += localSize; + outputByteLen -= localSize; + } + } + return error; +} + +int SpongePRG_Forget(SpongePRG_Instance *instance) +{ + unsigned int rhoInBytes = (instance->duplex.rate-2)/8; + unsigned int capacity = SnP_width - instance->duplex.rate; + int error; + + if ((rhoInBytes*8) < capacity) + return 1; + + error = Duplexing(&instance->duplex, 0, 0, 0, 0, 0x01); + if ( !error ) { + error = DuplexingOverwriteWithZeroes(&instance->duplex, rhoInBytes); + if ( !error ) + error = Duplexing(&instance->duplex, 0, 0, 0, 0, 0x01); + } + DuplexSetOutputIndex(&instance->duplex, rhoInBytes); + return error; +} + +#undef SpongePRG_Instance +#undef SpongePRG_Initialize +#undef SpongePRG_Feed +#undef SpongePRG_Fetch +#undef SpongePRG_Forget + +#undef DuplexInstance +#undef DuplexInitialize +#undef Duplexing +#undef DuplexingFeedPartialInput +#undef DuplexingOverwriteWithZeroes +#undef DuplexingGetFurtherOutput +#undef DuplexGetInputIndex +#undef DuplexGetOutputIndex +#undef DuplexSetOutputIndex diff --git a/pyecsca/codegen/prng/KeccakPRGWidth200.c b/pyecsca/codegen/prng/KeccakPRGWidth200.c new file mode 100644 index 0000000..067375e --- /dev/null +++ b/pyecsca/codegen/prng/KeccakPRGWidth200.c @@ -0,0 +1,22 @@ +/* +Implementation by Gilles Van Assche, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#include "KeccakPRGWidth200.h" + +#ifndef KeccakP200_excluded + #include "KeccakP-200-SnP.h" + + #define prefix KeccakWidth200 + #define SnP_width 200 + #include "KeccakPRG.inc" + #undef prefix + #undef SnP_width +#endif diff --git a/pyecsca/codegen/prng/KeccakPRGWidth200.h b/pyecsca/codegen/prng/KeccakPRGWidth200.h new file mode 100644 index 0000000..d7cfcc9 --- /dev/null +++ b/pyecsca/codegen/prng/KeccakPRGWidth200.h @@ -0,0 +1,24 @@ +/* +Implementation by Gilles Van Assche, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _KeccakPRGWidth200_h_ +#define _KeccakPRGWidth200_h_ + +#include "KeccakDuplexWidth200.h" +#include "KeccakPRG-common.h" + +#ifndef KeccakP200_excluded + #include "KeccakP-200-SnP.h" + KCP_DeclareSpongePRG_Structure(KeccakWidth200, KeccakP200_stateSizeInBytes, KeccakP200_stateAlignment) + KCP_DeclareSpongePRG_Functions(KeccakWidth200) +#endif + +#endif diff --git a/pyecsca/codegen/prng/align.h b/pyecsca/codegen/prng/align.h new file mode 100644 index 0000000..90c1b37 --- /dev/null +++ b/pyecsca/codegen/prng/align.h @@ -0,0 +1,32 @@ +/* +Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, +Michaël Peeters, Gilles Van Assche and Ronny Van Keer, +hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _align_h_ +#define _align_h_ + +/* on Mac OS-X and possibly others, ALIGN(x) is defined in param.h, and -Werror chokes on the redef. */ +#ifdef ALIGN +#undef ALIGN +#endif + +#if defined(__GNUC__) +#define ALIGN(x) __attribute__ ((aligned(x))) +#elif defined(_MSC_VER) +#define ALIGN(x) __declspec(align(x)) +#elif defined(__ARMCC_VERSION) +#define ALIGN(x) __align(x) +#else +#define ALIGN(x) +#endif + +#endif diff --git a/pyecsca/codegen/prng/prng.c b/pyecsca/codegen/prng/prng.c new file mode 100644 index 0000000..934fe72 --- /dev/null +++ b/pyecsca/codegen/prng/prng.c @@ -0,0 +1,28 @@ +#include "KeccakPRG.h" +#include "KeccakP-200-compact.c" +#include "KeccakDuplexWidth200.c" +#include "KeccakPRGWidth200.c" +#include "prng.h" +#include <tommath.h> + + +static KeccakWidth200_SpongePRG_Instance keccak; + +mp_err prng_mp_rand(void *out, size_t size) { + return (prng_get(out, size) == 0) ? MP_OKAY : MP_ERR; +} + +void prng_init(void) { + KeccakWidth200_SpongePRG_Initialize(&keccak, 70); + mp_rand_source(prng_mp_rand); +} + +int prng_get(uint8_t *out, size_t size) { + return KeccakWidth200_SpongePRG_Fetch(&keccak, out, size); +} + +void prng_seed(uint8_t *seed, size_t size) { + KeccakWidth200_SpongePRG_Feed(&keccak, seed, size); + KeccakWidth200_SpongePRG_Forget(&keccak); +} + diff --git a/pyecsca/codegen/prng/prng.h b/pyecsca/codegen/prng/prng.h new file mode 100644 index 0000000..b399a6c --- /dev/null +++ b/pyecsca/codegen/prng/prng.h @@ -0,0 +1,8 @@ +#include <stdint.h> + +void prng_init(void); + +int prng_get(uint8_t *out, size_t size); + +void prng_seed(uint8_t *seed, size_t size); + diff --git a/pyecsca/codegen/simpleserial/simpleserial.c b/pyecsca/codegen/simpleserial/simpleserial.c index 8205ed4..ca7c54d 100644 --- a/pyecsca/codegen/simpleserial/simpleserial.c +++ b/pyecsca/codegen/simpleserial/simpleserial.c @@ -3,6 +3,7 @@ #include "simpleserial.h" #include <stdint.h> #include "hal.h" +#include <stdio.h> typedef struct ss_cmd { @@ -28,10 +29,13 @@ static char hex_lookup[16] = int hex_decode(int len, char* ascii_buf, uint8_t* data_buf) { - for(int i = 0; i < len; i++) + if (len % 2 != 0) + return 1; + + for(int i = 0; i < len; i+=2) { - char n_hi = ascii_buf[2*i]; - char n_lo = ascii_buf[2*i+1]; + char n_hi = ascii_buf[i]; + char n_lo = ascii_buf[i+1]; if(n_lo >= '0' && n_lo <= '9') data_buf[i] = n_lo - '0'; @@ -125,7 +129,7 @@ void simpleserial_get(void) // Callback uint8_t ret[1]; - ret[0] = commands[cmd].fp(data_buf, i); + ret[0] = commands[cmd].fp(data_buf, i/2); // Acknowledge (if version is 1.1) #if SS_VER == SS_VER_1_1 |
