bug fix + docu
This commit is contained in:
parent
8fcc613257
commit
6cddae4d0f
|
@ -78,10 +78,8 @@ SRC_LEN_0 = 20
|
|||
SRC_LEN_1 = 21
|
||||
SCALE_0 = 18
|
||||
SCALE_1 = 19
|
||||
DST_CTX_0 = 6
|
||||
DST_CTX_1 = 7
|
||||
SRC_CTX_0 = 8
|
||||
SRC_CTX_1 = 9
|
||||
DST_CTX_0 = 8
|
||||
DST_CTX_1 = 9
|
||||
TMP_0 = 10
|
||||
TMP_1 = 11
|
||||
|
||||
|
@ -89,7 +87,14 @@ bigint_add_scale_u:
|
|||
movw r30, r24 /* dest ptr */
|
||||
movw r26, r22 /* src ptr */
|
||||
movw r24, r20 /* scale */
|
||||
/* check if scale is zero */
|
||||
movw SCALE_0, r24
|
||||
adiw r24, 0
|
||||
brne 10f
|
||||
movw r24, r30
|
||||
movw r20, r30
|
||||
rjmp bigint_add_u
|
||||
10: /* check if src is zero */
|
||||
ld r24, X+
|
||||
ld r25, X+
|
||||
adiw r24, 0
|
||||
|
@ -97,9 +102,8 @@ bigint_add_scale_u:
|
|||
ret
|
||||
10:
|
||||
movw SRC_LEN_0, r24
|
||||
push_range 6, 11
|
||||
push_range 8, 11
|
||||
movw DST_CTX_0, r30
|
||||
movw SRC_CTX_0, r26
|
||||
|
||||
/* pad dest with zeros to length of SRC_LENGTH + scale */
|
||||
adiw r26, 1
|
||||
|
@ -126,7 +130,6 @@ bigint_add_scale_u:
|
|||
rjmp 10b
|
||||
11:
|
||||
/* start of copy */
|
||||
|
||||
movw r24, SRC_LEN_0
|
||||
|
||||
12: /* copy loop */
|
||||
|
@ -144,13 +147,12 @@ bigint_add_scale_u:
|
|||
std Z+1, TMP_1
|
||||
movw r24, r30
|
||||
99:
|
||||
pop_range 6, 11
|
||||
pop_range 8, 11
|
||||
rjmp bigint_adjust
|
||||
40:
|
||||
/* TODO */
|
||||
/* Z points at DST_WORDV */
|
||||
/* X points at SRC_WORDV */
|
||||
/* r24:r25 contains scale - DST_LEN (negativ) */
|
||||
/* r24:r25 and TMP contain scale - DST_LEN (negativ) */
|
||||
/* set T bit if DST_LEN > SCR_LEN + scale */
|
||||
clt
|
||||
add r30, SCALE_0
|
||||
|
@ -172,36 +174,24 @@ bigint_add_scale_u:
|
|||
+-------+-------+ SRC + scale
|
||||
+------------+ DST
|
||||
*/
|
||||
com r24 /* negate r24:r25 */
|
||||
com r24 /* negate r24:r25 ==> DST_LEN - scale */
|
||||
com r25
|
||||
adiw r24, 1
|
||||
breq 50f
|
||||
44:
|
||||
inc r25
|
||||
clc
|
||||
45:
|
||||
dec r24
|
||||
brpl 46f
|
||||
dec r25
|
||||
brmi 50f
|
||||
46: ld TMP_0, X+
|
||||
ld TMP_1, Z
|
||||
adc TMP_0, TMP_1
|
||||
st Z+, TMP_0
|
||||
rjmp 45b
|
||||
dec r24
|
||||
brne 46b
|
||||
dec r25
|
||||
brne 46b
|
||||
|
||||
50:
|
||||
/* do the overhaning part */
|
||||
rol r1
|
||||
movw r24, r30
|
||||
movw r30, DST_CTX_0
|
||||
ldd TMP_0, Z+3
|
||||
ldd TMP_1, Z+4
|
||||
movw r30, TMP_0
|
||||
add r30, DST_LEN_0
|
||||
adc r31, DST_LEN_1
|
||||
adiw r30, 1
|
||||
st Z, r1
|
||||
movw r30, r24
|
||||
ror r1
|
||||
50: ;st Z, r1
|
||||
brtc 60f
|
||||
51: brcc 53f
|
||||
52: ld TMP_0, Z
|
||||
|
@ -209,34 +199,42 @@ bigint_add_scale_u:
|
|||
st Z+, TMP_0
|
||||
brcs 52b
|
||||
53:
|
||||
/* TODO */
|
||||
/* epilogue */
|
||||
movw r24, r30
|
||||
movw r30, DST_CTX_0
|
||||
ldd TMP_0, Z+3
|
||||
ldd TMP_1, Z+4
|
||||
sub r24, TMP_0
|
||||
sbc r25, TMP_1
|
||||
cp r24, DST_LEN_0
|
||||
cpc r25, DST_LEN_1
|
||||
brmi 54f
|
||||
std Z+0, r24
|
||||
std Z+1, r25
|
||||
movw r24, r30
|
||||
54: movw r24, r30
|
||||
rjmp 99b
|
||||
|
||||
60: rol r1 /* backup carry */
|
||||
60: st Z, r1
|
||||
rol r1 /* backup carry */
|
||||
movw r24, SRC_LEN_0
|
||||
add r24, SCALE_0
|
||||
adc r25, SCALE_1
|
||||
sub r24, DST_LEN_0
|
||||
sbc r25, DST_LEN_1
|
||||
|
||||
adiw r24, 0
|
||||
breq 63f
|
||||
inc r25
|
||||
ror r1 /* restore carry */
|
||||
|
||||
61: dec r24
|
||||
brpl 62f
|
||||
dec r25
|
||||
brmi 63f
|
||||
61:
|
||||
62: ld TMP_0, X+
|
||||
adc TMP_0, r1
|
||||
st Z+, TMP_0
|
||||
rjmp 61b
|
||||
dec r24
|
||||
brne 62b
|
||||
dec r25
|
||||
brne 62b
|
||||
63:
|
||||
brcc 53b
|
||||
ldi r24, 1
|
||||
|
|
|
@ -30,8 +30,117 @@ of documenting the structure of the API so you know what to do when you want
|
|||
to use the library.
|
||||
|
||||
@chapter Generic stuff
|
||||
@section Requirements
|
||||
You should have the following software tools to build the library, the version
|
||||
mentioned is the version used on the test system, older or newer versions may
|
||||
or may not work):
|
||||
@table @asis
|
||||
@item a recent toolchain
|
||||
for AVR targets:
|
||||
@table @asis
|
||||
@item gcc for AVR (avr-gcc)
|
||||
4.3.5
|
||||
@item GNU binutils for AVR
|
||||
2.21
|
||||
@item avr-libc
|
||||
1.6.8-2
|
||||
@end table
|
||||
for ARM targets:
|
||||
@table @asis
|
||||
@item gcc for ARM (arm-elf-gcc)
|
||||
@item GNU binutils for ARM
|
||||
@item newlib with enabled malloc()
|
||||
@end table
|
||||
@item a flash tool to program your device
|
||||
for AVR targets:
|
||||
@table @asis
|
||||
@item avrdude
|
||||
5.10
|
||||
@end table
|
||||
for ARM targets:
|
||||
@table @asis
|
||||
@item openocd
|
||||
0.4.0
|
||||
@end table
|
||||
|
||||
@item GNU make
|
||||
3.81
|
||||
@item ruby (for the testing system)
|
||||
1.8.7.302-2
|
||||
@table @asis
|
||||
@item rubygems
|
||||
1.3.7
|
||||
@item serialport
|
||||
1.0.4
|
||||
@item getopt
|
||||
1.4.0
|
||||
@end table
|
||||
@end table
|
||||
|
||||
@section File organisation
|
||||
|
||||
|
||||
@section Build process
|
||||
The build process is managed by a large relative complex @file{Makefile} and
|
||||
a bunch of more specific Makefile-stubs (@file{*.mk} in the @file{mkfiles}
|
||||
directory).
|
||||
|
||||
|
||||
|
||||
@subsection make-stubs
|
||||
All stubs are included by the main Makefile automatically, so the addition of
|
||||
algorithms should not require modifications to the Makefile.
|
||||
|
||||
Because all stubs are included by the main Makefile you can use all features
|
||||
of your make system when writing them. Currently we use GNU make and we
|
||||
recommend using GNU make when building the crypto library.
|
||||
|
||||
Each algorithm implementation has its own stub. A stub looks like the following:
|
||||
@verbatim
|
||||
# Makefile for AES
|
||||
ALGO_NAME := AES128_C
|
||||
|
||||
# comment out the following line for removement of AES from the build process
|
||||
BLOCK_CIPHERS += $(ALGO_NAME)
|
||||
|
||||
$(ALGO_NAME)_DIR := aes/
|
||||
$(ALGO_NAME)_INCDIR := gf256mul/ bcal/
|
||||
$(ALGO_NAME)_OBJ := aes_enc.o aes_dec.o aes_sbox.o aes_invsbox.o \
|
||||
aes_keyschedule.o gf256mul.o aes128_enc.o aes128_dec.o
|
||||
$(ALGO_NAME)_TEST_BIN := main-aes128-test.o $(CLI_STD) $(BCAL_STD) \
|
||||
bcal_aes128.o
|
||||
$(ALGO_NAME)_NESSIE_TEST := test nessie
|
||||
$(ALGO_NAME)_PERFORMANCE_TEST := performance
|
||||
@end verbatim
|
||||
|
||||
The most important thing is defining an unambiguous name for the implementation,
|
||||
in this case it is AES128_C.
|
||||
The next step is chaining the implementation into a category. Uncategorized
|
||||
implementations will be ignored. So if you want to exclude an implementation
|
||||
from the build process you can simply comment out the line which chains it into
|
||||
a category.
|
||||
|
||||
The following lines declare ''Attributes'' of the implementation.
|
||||
@table @var
|
||||
@item _DIR
|
||||
defines the directory where the implementation resides
|
||||
@item _INCDIR
|
||||
defines directorys to search for additional files
|
||||
@item _OBJ
|
||||
defines the names of the objects which shoud be considered the implementations
|
||||
core
|
||||
@item _TESTBIN
|
||||
defines the names of the objects required to build the test suit
|
||||
@item _NESSIE_TEST
|
||||
(currently unused) defines the string which should be send to the test system
|
||||
to perform nessie standard tests
|
||||
@item _NESSIE_TEST
|
||||
(currently unused) defines the string which should be send to the test system
|
||||
to perform a performance tests
|
||||
@item _DEF
|
||||
defines macros to use while compiling
|
||||
@end table
|
||||
|
||||
@section Testing system
|
||||
@section Sizes in bits and bytes
|
||||
Working with cryptographic functions involves working with different
|
||||
|
@ -42,7 +151,7 @@ to use the library.
|
|||
_b means in bits and _B means in bytes (big b big word) and _w meaning words.
|
||||
|
||||
@chapter Symmetric primitives
|
||||
|
||||
@include acl_keysizes.texi
|
||||
@include acl_blockciphers.texi
|
||||
|
||||
@section Modes of operation
|
||||
|
|
|
@ -135,7 +135,7 @@ The BCAL is split up in different parts:
|
|||
@item BCAL basic functions
|
||||
@end itemize
|
||||
|
||||
@subsubsection BCAL declaration for BCAL decriptors
|
||||
@subsection BCAL declaration for BCAL decriptors
|
||||
The BCAL descriptor is a structure which is usually placed in FLASH or ROM since
|
||||
modification is unnecessary. It contains all information required to use the
|
||||
according block cipher.
|
||||
|
@ -220,7 +220,7 @@ typedef struct {
|
|||
that the chosen keysize is valid
|
||||
@end table
|
||||
|
||||
@subsubsection BCAL-Basic context
|
||||
@subsection BCAL-Basic context
|
||||
Besides the context types for individual ciphers there is a generic context
|
||||
type for BCAL. This is the context to use when using BCAL based functions.
|
||||
The BCAL context has the following structure:
|
||||
|
@ -242,14 +242,13 @@ pointer to the cipher specific context
|
|||
|
||||
|
||||
|
||||
@subsubsection BCAL-Basic
|
||||
@subsection BCAL-Basic
|
||||
BCAL-Basic provides the basic features of an block cipher on top of the
|
||||
BCAL. To use it you simply have to include the algorithms you want to use,
|
||||
the BCAL descriptor file and of course the BCAL-Basic implementation.
|
||||
|
||||
The following functions are provided:
|
||||
@table @code
|
||||
@item bcal_cipher_init
|
||||
@subsubsection @code{bcal_cipher_init}
|
||||
@code{uint8_t bcal_cipher_init(const bcdesc_t* cipher_descriptor, const void* key, uint16_t keysize_b, bcgen_ctx_t* ctx)}
|
||||
this function initializes a BCAL context based on the given BCAL descriptor
|
||||
pointer (first parameter) with a given key (second parameter) of a given length
|
||||
|
@ -270,109 +269,29 @@ The following functions are provided:
|
|||
for the selected cipher.
|
||||
@end table
|
||||
|
||||
@item bcal_cipher_free
|
||||
@subsubsection @code{bcal_cipher_free}
|
||||
@code{void bcal_cipher_free(bcgen_ctx_t* ctx)} this function frees the memory
|
||||
allocated by the init function and should be called whenever you are finished
|
||||
with BCAL context. It automatically also calls the @code{free} function if
|
||||
necessary.
|
||||
|
||||
@item bcal_cipher_enc
|
||||
@subsubsection @code{bcal_cipher_enc}
|
||||
@code{void bcal_cipher_enc(void* block, const bcgen_ctx_t* ctx)}
|
||||
this function encrypts a block in-place using a given BCAL contex.
|
||||
|
||||
@item bcal_cipher_dec
|
||||
@subsubsection @code{bcal_cipher_dec}
|
||||
@code{void bcal_cipher_dec(void* block, const bcgen_ctx_t* ctx)}
|
||||
this function decrypts a block in-place using a given BCAL contex.
|
||||
|
||||
@item bcal_cipher_getBlocksize_b
|
||||
@subsubsection @code{bcal_cipher_getBlocksize_b}
|
||||
@code{uint16_t bcal_cipher_getBlocksize_b(const bcdesc_t* desc)}
|
||||
this function returns the block size of a given cipher by using the BCAL
|
||||
descriptor (to which a pointer must be passed).
|
||||
|
||||
@item bcal_cipher_getKeysizeDesc
|
||||
@subsubsection @code{bcal_cipher_getKeysizeDesc}
|
||||
@code{PGM_VOID_P bcal_cipher_getKeysizeDesc(const bcdesc_t* desc)}
|
||||
this function returns a pointer to the keysize descriptor of a given cipher by
|
||||
using the BCAL descriptor (to which a pointer must be passed).
|
||||
|
||||
@end table
|
||||
|
||||
@subsection Keysize descriptors
|
||||
There are a lot of different block ciphers or cryptographic algorithms in
|
||||
general which put several constrains to the number of bits which can be used
|
||||
as key.
|
||||
|
||||
Our approach is to find a simple and compact way do specify which lengths are
|
||||
valid and which are not. The system is quite simple, we use a list of patterns
|
||||
(with parameters) and if any matches the keysize is valid, if none matches the
|
||||
keysize is unsupported.
|
||||
|
||||
The patterns are:
|
||||
@itemize @bullet
|
||||
@item simple list of valid keysizes
|
||||
@item range of keysizes
|
||||
@item augmented range of keysizes
|
||||
@end itemize
|
||||
|
||||
@subsubsection simple list of valid keysizes
|
||||
The simple keysize list has the following structure:
|
||||
@verbatim
|
||||
typedef struct{ /* keysize is valid if listed in items */
|
||||
uint8_t n_items; /* number of items (value 0 is reserved) */
|
||||
uint16_t items[]; /* list of valid lengths */
|
||||
}keysize_desc_list_t;
|
||||
@end verbatim
|
||||
First we specify how many keysizes we want to declare valid (this is limited to
|
||||
255 keysizes but that should not impose any real world constrains). And follow
|
||||
it by the keysizes as 16bit unsigned values.
|
||||
|
||||
If you want to declare a lot of keys please check first the other methods since
|
||||
they may give a more compact definition.
|
||||
|
||||
@subsubsection range of keysizes
|
||||
This method specifies an entire range of keys a valid using the following
|
||||
structure:
|
||||
@verbatim
|
||||
typedef struct{ /* keysize is valid if min<=keysize<=max */
|
||||
uint16_t min;
|
||||
uint16_t max;
|
||||
}keysize_desc_range_t;
|
||||
@end verbatim
|
||||
So all keysizes between @code{min} and @code{max} (including @code{min} and
|
||||
@code{max}) are valid. Please note that in most cases also keysizes which
|
||||
are not a multiple of 8 (so are not full bytes) are also matched.
|
||||
If you want to avoid this see the augmented range of keysizes.
|
||||
|
||||
@subsubsection augmented range of keysizes
|
||||
The augmented range of keysizes uses the following structure:
|
||||
@verbatim
|
||||
typedef struct{ /* keysize is valid if min<=keysize<=max and if keysize mod distance == offset */
|
||||
uint16_t min;
|
||||
uint16_t max;
|
||||
uint16_t distance;
|
||||
uint16_t offset;
|
||||
}keysize_desc_arg_range_t;
|
||||
@end verbatim
|
||||
The restriction to a range is the same as with the simpler range of keysizes,
|
||||
but also another restriction is imposed. A valid keysize must have a reminder
|
||||
of @code{offset} when divided by @code{distance}. So you can limit a keysize
|
||||
to full bytes by simply setting @code{distance} to @samp{8} and @code{offset}
|
||||
to @samp{0}.
|
||||
|
||||
@subsubsection the actual descriptor
|
||||
The keysize descriptor is a list of the former patterns. Each pattern is
|
||||
preceded by byte designating the type of pattern and the list is terminated
|
||||
by a @code{NULL} byte.
|
||||
|
||||
The designator byte can have one of the following values:
|
||||
@table @samp
|
||||
@item 0x00
|
||||
Terminator byte, signals the end of the list
|
||||
@item 0x01
|
||||
simple list of keysizes
|
||||
@item 0x02
|
||||
simple range of keysizes
|
||||
@item 0x03
|
||||
augmented range of keysizes
|
||||
@end table
|
||||
|
||||
|
||||
|
|
|
@ -83,5 +83,172 @@
|
|||
|
||||
|
||||
@subsection Hash function abstraction layer (HFAL)
|
||||
The HashFunctionAbstractionLayer (BCAL) is an abstraction layer which allows
|
||||
usage of all implemented hash functions in a simple way. It abstracts specific
|
||||
function details and is suitable for implementations which want to be flexible
|
||||
in the choosing of specific hash functions. Another important aspect is that this
|
||||
abstraction layer enables the implementation of hash function operating modes
|
||||
independently from concrete hash function. It is very simple to use and reassembles
|
||||
the API used to implement individual hash functions.
|
||||
|
||||
The main component is a hash function descriptor which contains the details of
|
||||
the individual hash functions.
|
||||
|
||||
@subsection Parts of HFAL
|
||||
The HFAL is split up in different parts:
|
||||
@itemize @bullet
|
||||
@item HFAL declaration for HFAL decriptors
|
||||
@item algorithm specific definitions of HFAL decriptors
|
||||
@item HFAL basic context type
|
||||
@item HFAL basic functions
|
||||
@end itemize
|
||||
|
||||
@subsection HFAL declaration for HFAL decriptors
|
||||
The HFAL descriptor is a structure which is usually placed in FLASH or ROM since
|
||||
modification is unnecessary. It contains all information required to use the
|
||||
according hash function.
|
||||
|
||||
@verbatim
|
||||
typedef struct {
|
||||
uint8_t type; /* 2 == hashfunction */
|
||||
uint8_t flags;
|
||||
PGM_P name;
|
||||
uint16_t ctxsize_B;
|
||||
uint16_t blocksize_b;
|
||||
uint16_t hashsize_b;
|
||||
hf_init_fpt init;
|
||||
hf_nextBlock_fpt nextBlock;
|
||||
hf_lastBlock_fpt lastBlock;
|
||||
hf_ctx2hash_fpt ctx2hash;
|
||||
hf_free_fpt free;
|
||||
hf_mem_fpt mem;
|
||||
} hfdesc_t; /* hashfunction descriptor type */
|
||||
@end verbatim
|
||||
|
||||
@table @var
|
||||
@item type
|
||||
should be set to @samp{2} to indicate that this descriptor is for a
|
||||
hash function.
|
||||
|
||||
@item flags
|
||||
currently unused, should be set to zero.
|
||||
|
||||
@item name
|
||||
is a pointer to a zero terminated ASCII string giving the name of the
|
||||
implemented primitive. On targets with Harvard-architecture the string resides
|
||||
in code memory (FLASH, ROM, ...).
|
||||
|
||||
@item ctxsize_B
|
||||
is the number of bytes which should be allocated for the context variable.
|
||||
|
||||
@item blocksize_b
|
||||
is the number of bits on which are hashed by one iteration of the nextBlock
|
||||
function.
|
||||
|
||||
@item hashsize_b
|
||||
is the number of bits on which are outputed as final hash value.
|
||||
|
||||
@item init
|
||||
is a pointer to the init function.
|
||||
|
||||
@item nextBlock
|
||||
is a pointer to the algorithm specific nextBlock function.
|
||||
|
||||
@item lastBlock
|
||||
is a pointer to the algorithm specific lastBlock function.
|
||||
|
||||
@item ctx2hash
|
||||
is a pointer to the algorithm specific ctx2hash function.
|
||||
|
||||
@item free
|
||||
is a pointer to the free function or NULL if there is no free function.
|
||||
|
||||
@item mem
|
||||
is a pointer to the algorithm specific mem function. This function hashes
|
||||
a complete message which has to reside entirely in RAM. This value may be
|
||||
NULL if there is no such function.
|
||||
@end table
|
||||
|
||||
@subsection HFAL-Basic context
|
||||
Besides the context types for individual hash functions there is a generic context
|
||||
type for HFAL. This is the context to use when using HFAL based functions.
|
||||
The HFAL context has the following structure:
|
||||
@verbatim
|
||||
typedef struct{
|
||||
hfdesc_t* desc_ptr;
|
||||
void* ctx;
|
||||
} hfgen_ctx_t;
|
||||
@end verbatim
|
||||
@table @code
|
||||
@item desc_ptr
|
||||
a pointer to the HFAL descriptor
|
||||
@item ctx
|
||||
pointer to the hash function specific context
|
||||
@end table
|
||||
|
||||
@subsection HFAL-Basic
|
||||
HFAL-Basic provides the basic features of an hash function on top of the
|
||||
HFAL. To use it you simply have to include the algorithms you want to use,
|
||||
the HFAL descriptor file and of course the HFAL-Basic implementation.
|
||||
|
||||
The following functions are provided:
|
||||
|
||||
@subsubsection @code{hfal_hash_init}
|
||||
@code{uint8_t hfal_hash_init(const hfdesc_t* hash_descriptor, hfgen_ctx_t* ctx)}
|
||||
this function initializes a HFAL context based on the given HFAL descriptor
|
||||
pointer (first parameter). The context to initialize is designated by the
|
||||
pointer passed as second parameter.
|
||||
|
||||
If everything works fine @samp{0} is returned. In the case something fails
|
||||
the following codes are returned:
|
||||
@table @samp
|
||||
@item 3
|
||||
It was not possible to allocate enough memory to hold the context variable
|
||||
for the selected hash function.
|
||||
@end table
|
||||
|
||||
@subsubsection @code{hfal_hash_nextBlock}
|
||||
@code{ void hfal_hash_nextBlock(hfgen_ctx_t* ctx, const void* block)}
|
||||
this function hashes a block of memory (of algorithm specific length) and
|
||||
updates the context accordingly.
|
||||
|
||||
@subsubsection @code{hfal_hash_lastBlock}
|
||||
@code{ void hfal_hash_lastBlock(hfgen_ctx_t* ctx, const void* block, uint16_t length_b)}
|
||||
this function is used to hash the last block of a message. Since messages are
|
||||
not required to consist of full blocks (or even full bytes) the length of the
|
||||
block must be given in bits. The context is updated accordingly. This function
|
||||
already performs padding and related stuff.
|
||||
|
||||
@subsubsection @code{hfal_hash_ctx2hash}
|
||||
@code{ void hfal_hash_ctx2hash(void* dest, hfgen_ctx_t* ctx)}
|
||||
this function converts a context into an actual hash value which is stored in
|
||||
@code{dest}. The application is responsible for allocating enough room.
|
||||
|
||||
@subsubsection @code{hfal_hash_free}
|
||||
@code{ void hfal_hash_free(hfgen_ctx_t* ctx)}
|
||||
this function differs from the individual hash functions @code{free} function
|
||||
in that it is allways provided and must be called to avoid memory holes.
|
||||
This function also automatically calls the implementation specific @code{free}
|
||||
function if one is provided.
|
||||
|
||||
@subsubsection @code{hfal_hash_mem}
|
||||
@code{ void hfal_hash_mem(const hfdesc_t* hash_descriptor, void* dest, const void* msg, uint32_t length_b)}
|
||||
this function is allways provided (even if the actual algorithm does not
|
||||
specify a @code{mem} function. It hashes an entire message which resides in
|
||||
RAM and stores the hash value in @code{dest}. @code{msg} is the pointer to the
|
||||
message and @code{length_b} is the message length in bits.
|
||||
|
||||
@subsubsection @code{hfal_hash_getBlocksize}
|
||||
@code{ uint16_t hfal_hash_getBlocksize(const hfdesc_t* hash_descriptor)}
|
||||
returns the blocksize of the described (@code{hash_descriptor}) hash function.
|
||||
|
||||
@subsubsection @code{hfal_hash_getHashsize}
|
||||
@code{ uint16_t hfal_hash_getHashsize(const hfdesc_t* hash_descriptor)}
|
||||
returns the hash value size of the described (@code{hash_descriptor}) hash function.
|
||||
|
||||
@subsubsection @code{hfal_hash_getCtxsize}
|
||||
@code{ uint16_t hfal_hash_getCtxsize_B(const hfdesc_t* hash_descriptor)}
|
||||
returns the size of a context variable of the described (@code{hash_descriptor}) hash function.
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
@c acl_keysizes.texi
|
||||
|
||||
@section Keysize descriptors
|
||||
There are a lot of different block ciphers or cryptographic algorithms in
|
||||
general which put several constrains to the number of bits which can be used
|
||||
as key.
|
||||
|
||||
Our approach is to find a simple and compact way do specify which lengths are
|
||||
valid and which are not. The system is quite simple, we use a list of patterns
|
||||
(with parameters) and if any matches the keysize is valid, if none matches the
|
||||
keysize is unsupported.
|
||||
|
||||
The patterns are:
|
||||
@itemize @bullet
|
||||
@item simple list of valid keysizes
|
||||
@item range of keysizes
|
||||
@item augmented range of keysizes
|
||||
@end itemize
|
||||
|
||||
@subsection simple list of valid keysizes
|
||||
The simple keysize list has the following structure:
|
||||
@verbatim
|
||||
typedef struct{ /* keysize is valid if listed in items */
|
||||
uint8_t n_items; /* number of items (value 0 is reserved) */
|
||||
uint16_t items[]; /* list of valid lengths */
|
||||
}keysize_desc_list_t;
|
||||
@end verbatim
|
||||
First we specify how many keysizes we want to declare valid (this is limited to
|
||||
255 keysizes but that should not impose any real world constrains). And follow
|
||||
it by the keysizes as 16bit unsigned values.
|
||||
|
||||
If you want to declare a lot of keys please check first the other methods since
|
||||
they may give a more compact definition.
|
||||
|
||||
@subsection range of keysizes
|
||||
This method specifies an entire range of keys a valid using the following
|
||||
structure:
|
||||
@verbatim
|
||||
typedef struct{ /* keysize is valid if min<=keysize<=max */
|
||||
uint16_t min;
|
||||
uint16_t max;
|
||||
}keysize_desc_range_t;
|
||||
@end verbatim
|
||||
So all keysizes between @code{min} and @code{max} (including @code{min} and
|
||||
@code{max}) are valid. Please note that in most cases also keysizes which
|
||||
are not a multiple of 8 (so are not full bytes) are also matched.
|
||||
If you want to avoid this see the augmented range of keysizes.
|
||||
|
||||
@subsection augmented range of keysizes
|
||||
The augmented range of keysizes uses the following structure:
|
||||
@verbatim
|
||||
typedef struct{ /* keysize is valid if min<=keysize<=max and if keysize mod distance == offset */
|
||||
uint16_t min;
|
||||
uint16_t max;
|
||||
uint16_t distance;
|
||||
uint16_t offset;
|
||||
}keysize_desc_arg_range_t;
|
||||
@end verbatim
|
||||
The restriction to a range is the same as with the simpler range of keysizes,
|
||||
but also another restriction is imposed. A valid keysize must have a reminder
|
||||
of @code{offset} when divided by @code{distance}. So you can limit a keysize
|
||||
to full bytes by simply setting @code{distance} to @samp{8} and @code{offset}
|
||||
to @samp{0}.
|
||||
|
||||
@subsection the actual descriptor
|
||||
The keysize descriptor is a list of the former patterns. Each pattern is
|
||||
preceded by byte designating the type of pattern and the list is terminated
|
||||
by a @code{NULL} byte.
|
||||
|
||||
The designator byte can have one of the following values:
|
||||
@table @samp
|
||||
@item 0x00
|
||||
Terminator byte, signals the end of the list
|
||||
@item 0x01
|
||||
simple list of keysizes
|
||||
@item 0x02
|
||||
simple range of keysizes
|
||||
@item 0x03
|
||||
augmented range of keysizes
|
||||
@end table
|
||||
|
||||
|
|
@ -127,6 +127,9 @@ end
|
|||
################################################################################
|
||||
|
||||
def init_system(test_prog)
|
||||
begin
|
||||
line = $sp.gets()
|
||||
end while line!=nil
|
||||
$sp.print("echo off \r")
|
||||
print("DBG i: " + "echo off \r"+"\n") if $debug
|
||||
sleep 0.1
|
||||
|
@ -135,6 +138,27 @@ def init_system(test_prog)
|
|||
sleep 1
|
||||
end
|
||||
|
||||
################################################################################
|
||||
# wait_for_prompt #
|
||||
################################################################################
|
||||
|
||||
def wait_for_prompt(prompt)
|
||||
prompt = /[\s]*#{prompt}[\s]*/ if(prompt.class == String)
|
||||
start_time = Time.now.to_i
|
||||
begin
|
||||
line = $sp.gets()
|
||||
puts("DBG got (#{__LINE__}): "+line) if $debug && line
|
||||
line = "" if line==nil
|
||||
if /^(Error:|Crypto-VS).*/.match(line)
|
||||
puts line
|
||||
return false
|
||||
end
|
||||
if (Time.now.to_i- start_time) > $max_timeout
|
||||
return false
|
||||
end
|
||||
end while not m=prompt.match(line)
|
||||
return m
|
||||
end
|
||||
|
||||
################################################################################
|
||||
# screen_progress #
|
||||
|
@ -249,59 +273,42 @@ end
|
|||
################################################################################
|
||||
# add_scale_test #
|
||||
################################################################################
|
||||
def add_scale_test_dummy(a, b, scale)
|
||||
should = a + (b<<(8*scale))
|
||||
printf("[dummy] %s + %s <<8*%04x = %s\n",a.to_s(16), b.to_s(16), scale, should.to_s(16))
|
||||
end
|
||||
|
||||
def add_scale_test(a, b, scale)
|
||||
begin
|
||||
line = $sp.gets()
|
||||
line = "" if line==nil
|
||||
puts("DBG got (#{__LINE__}): "+line) if $debug
|
||||
if /^Error:.*/.match(line)
|
||||
puts line
|
||||
return false
|
||||
end
|
||||
end while not /[\s]*enter a:[\s]*/.match(line)
|
||||
m = wait_for_prompt("enter a:")
|
||||
return false if !m
|
||||
puts("DBG put (#{__LINE__}): "+a.to_s(16)+" ") if $debug
|
||||
$sp.print(a.to_s(16)+" ")
|
||||
begin
|
||||
line = $sp.gets()
|
||||
line = "" if line==nil
|
||||
puts("DBG got (#{__LINE__}): "+line) if $debug
|
||||
if /^Error:.*/.match(line)
|
||||
puts line
|
||||
return false
|
||||
end
|
||||
end while not /[\s]*enter b:[\s]*/.match(line)
|
||||
m = wait_for_prompt("enter b:")
|
||||
return false if !m
|
||||
puts("DBG put (#{__LINE__}): "+b.to_s(16)+" ") if $debug
|
||||
$sp.print(b.to_s(16)+" ")
|
||||
begin
|
||||
line = $sp.gets()
|
||||
line = "" if line==nil
|
||||
puts("DBG got (#{__LINE__}): "+line) if $debug
|
||||
if /^Error:.*/.match(line)
|
||||
puts line
|
||||
return false
|
||||
end
|
||||
end while not /[\s]*enter scale:[\s]*/.match(line)
|
||||
m = wait_for_prompt("enter scale:")
|
||||
return false if !m
|
||||
puts("DBG put (#{__LINE__}): "+scale.to_s(10)+" ") if $debug
|
||||
$sp.print(scale.to_s(10)+"\r")
|
||||
begin
|
||||
line = $sp.gets()
|
||||
line = "" if line==nil
|
||||
puts("DBG got (#{__LINE__}): "+line) if $debug
|
||||
if /^Error:.*/.match(line)
|
||||
puts line
|
||||
should = a + (b<<(8*scale))
|
||||
m = wait_for_prompt(/[\s]*([-]?[0-9a-fA-F]+)[\s]+\+[\s]+([+-]?[0-9a-fA-F]+)[\s]*<<8\*[\s]*([+-]?[0-9a-fA-F]+)[\s]*=[\s]*([+-]?[0-9a-fA-F]+)/)
|
||||
if !m
|
||||
$logfile.printf("[fail (CRASH)]:")
|
||||
$logfile.printf(" ; should %s + %s << 8*%s = %s\n", a.to_s(16), b.to_s(16), scale.to_s(16), should.to_s(16))
|
||||
return false
|
||||
end
|
||||
end while not m=/[\s]*([-]?[0-9a-fA-F]*)[\s]+\+[\s]+([+-]?[0-9a-fA-F]*)[\s]*<<8\*[\s]*([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line)
|
||||
line = m[0]
|
||||
a_ = m[1].to_i(16)
|
||||
b_ = m[2].to_i(16)
|
||||
s_ = m[3].to_i(16)
|
||||
c_ = m[4].to_i(16)
|
||||
line.chomp!
|
||||
should = a + (b<<(8*scale))
|
||||
if(a_== a && b_ == b && s_ == scale && c_ == should )
|
||||
$logfile.printf("[pass]: %s\n", line)
|
||||
return true
|
||||
else
|
||||
$logfile.printf("[fail (%s%s%s)]: %s", (a==a_)?"":"a", (b==b_)?"":"b", (scale==s_)?"":"s",(c_==should)?"":"c",line)
|
||||
$logfile.printf("[fail (%s%s%s%s)]: %s", (a==a_)?"":"a", (b==b_)?"":"b", (scale==s_)?"":"s",(c_==should)?"":"c",line)
|
||||
$logfile.printf(" ; should %s + %s << 8*%s = %s\n", a.to_s(16), b.to_s(16), scale.to_s(16), should.to_s(16))
|
||||
return false
|
||||
end
|
||||
|
@ -563,7 +570,7 @@ def run_test_add_scale(skip=0)
|
|||
length_b_B = skip+1
|
||||
begin
|
||||
$size = length_a_B
|
||||
(0..16).each do |i|
|
||||
(0..4).each do |i|
|
||||
scales = [0, 300]
|
||||
16.times { scales << rand(301) }
|
||||
scales.sort!
|
||||
|
@ -576,7 +583,42 @@ def run_test_add_scale(skip=0)
|
|||
screen_progress(v)
|
||||
end
|
||||
end
|
||||
(0..16).each do |i|
|
||||
(0..4).each do |i|
|
||||
scales = [0, 300]
|
||||
16.times { scales << rand(301) }
|
||||
scales.sort!
|
||||
scales.each do |scale|
|
||||
b_size = rand(length_b_B+1)+1
|
||||
a = rand(256**length_a_B)
|
||||
b = rand(256**b_size)
|
||||
v = add_scale_test(a, b, scale)
|
||||
screen_progress(v)
|
||||
v = add_scale_test(b, a, scale)
|
||||
screen_progress(v)
|
||||
end
|
||||
end
|
||||
length_a_B += 10
|
||||
length_b_B += 10
|
||||
end while length_a_B<4096/8
|
||||
end
|
||||
|
||||
def run_test_add_scale_dummy(skip=0)
|
||||
length_a_B = skip+1
|
||||
length_b_B = skip+1
|
||||
begin
|
||||
$size = length_a_B
|
||||
(0..4).each do |i|
|
||||
scales = [0, 300]
|
||||
16.times { scales << rand(301) }
|
||||
scales.sort!
|
||||
scales.each do |scale|
|
||||
a = rand(256**length_a_B)
|
||||
b = rand(256**length_a_B)
|
||||
v = add_scale_test_dummy(a, b, scale)
|
||||
v = add_scale_test_dummy(b, a, scale)
|
||||
end
|
||||
end
|
||||
(0..4).each do |i|
|
||||
scales = [0, 300]
|
||||
16.times { scales << rand(301) }
|
||||
scales.sort!
|
||||
|
@ -584,10 +626,8 @@ def run_test_add_scale(skip=0)
|
|||
b_size = rand(length_b_B+1)
|
||||
a = rand(256**length_a_B)
|
||||
b = rand(256**b_size)
|
||||
v = add_scale_test(a, b, scale)
|
||||
screen_progress(v)
|
||||
v = add_scale_test(b, a, scale)
|
||||
screen_progress(v)
|
||||
v = add_scale_test_dummy(a, b, scale)
|
||||
v = add_scale_test_dummy(b, a, scale)
|
||||
end
|
||||
end
|
||||
length_a_B += 10
|
||||
|
@ -733,20 +773,7 @@ def run_test_gcdext(skip=0)
|
|||
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
|
||||
|
||||
def init_serialport(conf)
|
||||
puts("serial port interface version: " + SerialPort::VERSION);
|
||||
$linewidth = 64
|
||||
$linepos = 0
|
||||
|
@ -774,6 +801,24 @@ $sp.read_timeout=1000; # 5 minutes
|
|||
$sp.flow_control = SerialPort::SOFT
|
||||
|
||||
reset_system()
|
||||
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
|
||||
init_serialport(conf)
|
||||
|
||||
$max_timeout = 2 * 60
|
||||
|
||||
if opts['d']
|
||||
$debug = true
|
||||
|
|
|
@ -125,13 +125,6 @@ void test_add_scale_bigint(void){
|
|||
return;
|
||||
}
|
||||
*/
|
||||
cli_putstr_P(PSTR("\r\n "));
|
||||
bigint_print_hex(&a);
|
||||
cli_putstr_P(PSTR(" + "));
|
||||
bigint_print_hex(&b);
|
||||
cli_putstr_P(PSTR("<<8*"));
|
||||
cli_hexdump_rev(&scale, 2);
|
||||
cli_putstr_P(PSTR(" = "));
|
||||
uint8_t *c_b;
|
||||
c_b = malloc(((a.length_B>(b.length_B+scale))?a.length_B:(b.length_B+scale))+2);
|
||||
if(c_b==NULL){
|
||||
|
@ -143,6 +136,13 @@ void test_add_scale_bigint(void){
|
|||
c.wordv = c_b;
|
||||
bigint_copy(&c, &a);
|
||||
bigint_add_scale_u(&c, &b, scale);
|
||||
cli_putstr_P(PSTR("\r\n "));
|
||||
bigint_print_hex(&a);
|
||||
cli_putstr_P(PSTR(" + "));
|
||||
bigint_print_hex(&b);
|
||||
cli_putstr_P(PSTR("<<8*"));
|
||||
cli_hexdump_rev(&scale, 2);
|
||||
cli_putstr_P(PSTR(" = "));
|
||||
bigint_print_hex(&c);
|
||||
cli_putstr_P(PSTR("\r\n"));
|
||||
free(a.wordv);
|
||||
|
|
Loading…
Reference in New Issue