changed arcfour api
This commit is contained in:
parent
b07fb998ba
commit
c58f43feba
|
@ -66,8 +66,8 @@ email: daniel.otte@rub.de
|
|||
3.2. *_init function
|
||||
The *_init function generally takes a pointer to the key as first parameter.
|
||||
For ciphers where the keysize is not fixed the second parameter gives the
|
||||
keysize (in bits regularly) and the last parameter points to a context variable
|
||||
to fill.
|
||||
keysize (in bits regularly) and the last parameter points to the context
|
||||
variable to fill.
|
||||
For some ciphers there are additonal parameters like the number of rounds,
|
||||
these parameters generally occur before the context pointer.
|
||||
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
====================================
|
||||
= Usage of streamciphers =
|
||||
====================================
|
||||
|
||||
Author: Daniel Otte
|
||||
email: daniel.otte@rub.de
|
||||
|
||||
|
||||
0. Foreword
|
||||
This file will describe how to use the streramcipher implementations provided
|
||||
by this library. It will not only show how to call the cryptographic functions
|
||||
but also discuss a little how to build security mechanisms from that.
|
||||
|
||||
1. What a streamcipher does
|
||||
A streamcipher normaly generates a deterministic, random looking stream of
|
||||
bits, known as keystream. For encryption purpose this keystream is XORed with
|
||||
the data stream. So decryption is exactly the same as encryption. The
|
||||
datastream is XORed with the keystream giving the plaintext. So both sides need
|
||||
exactly the same streamcipher in the same state.
|
||||
|
||||
1.1. high frequent parameters:
|
||||
outputsize: 8 bit, 1 bit
|
||||
keysize: 64 bit, 80 bit, 128 bit
|
||||
IVsize: 64 bit
|
||||
|
||||
2. Parts of a streamcipher
|
||||
* generation algorithm
|
||||
* initialisation algorithm
|
||||
* state
|
||||
As we can see all streamciphers seem to utilize an internal state which
|
||||
determines the output. This state is initialized by the initialisation
|
||||
algorithm with a key and an IV (initialisation vector). It is very important
|
||||
for security that _never_ the same key with the same IV is used again. The
|
||||
IV is not required to be kept secret.
|
||||
|
||||
3. streamcipher API
|
||||
The API is not always consistent due to the fact that we tried to optimize the
|
||||
code for size (flash, heap and stack) and speed (runtime of the different
|
||||
components).
|
||||
Generally the API of the implemented streamciphers consists of:
|
||||
|
||||
*_init function, which implements the initialisation
|
||||
*_gen function, which implements the streamcipher algorithm and generates a
|
||||
keystream output
|
||||
*_ctx_t context type, which contains internal state information
|
||||
|
||||
3.1 look at the prototypes
|
||||
Generally the prototypes (defined in the *.h files) will tell you what
|
||||
parameter means what.
|
||||
|
||||
3.1.2 sizes in bits and bytes
|
||||
Working with cryptographical functions involves working with different lengths.
|
||||
Some times you want to know it in bits and sometimes in bytes. To reduce
|
||||
frustration and to avoid bugs we suffix a length parameter with either _b or _B
|
||||
depending on the meaning. _b means in bits and _B means in bytes
|
||||
(big b big word).
|
||||
|
||||
3.2. *_init function
|
||||
The *_init function generally takes a pointer to the key as first parameter.
|
||||
For ciphers where the keysize is not fixed the second parameter gives the
|
||||
keysize (in bits regularly) followed by a pointer to the IV and a length
|
||||
parameter for not fixed IV sizes (both are omitted if the algorithm does not
|
||||
specify IV handling, in this case a part of the key should be used as IV).
|
||||
The last parameter points to the context variable to fill.
|
||||
|
||||
3.3. *_gen function
|
||||
The *_gen function updates the internal state to which a pointer is given as
|
||||
parameter and returns a fixed length part of the keystream as return value.
|
||||
|
||||
|
||||
|
126
arcfour-asm.S
126
arcfour-asm.S
|
@ -26,68 +26,106 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
|
||||
.macro push_ p1:req, p2:vararg
|
||||
push \p1
|
||||
.ifnb \p2
|
||||
push_ \p2
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro pop_ p1:req, p2:vararg
|
||||
pop \p1
|
||||
.ifnb \p2
|
||||
pop_ \p2
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro push_range from:req, to:req
|
||||
push \from
|
||||
.if \to-\from
|
||||
push_range "(\from+1)",\to
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro pop_range from:req, to:req
|
||||
pop \to
|
||||
.if \to-\from
|
||||
pop_range \from,"(\to-1)"
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro stack_alloc size:req, reg1=r30, reg2=r31
|
||||
in \reg1, _SFR_IO_ADDR(SPL)
|
||||
in \reg2, _SFR_IO_ADDR(SPH)
|
||||
sbiw r30, \size
|
||||
out _SFR_IO_ADDR(SPH), \reg2
|
||||
out _SFR_IO_ADDR(SPL), \reg1
|
||||
.endm
|
||||
|
||||
.macro stack_free size:req, reg1=r30, reg2=r31
|
||||
in \reg1, _SFR_IO_ADDR(SPL)
|
||||
in \reg2, _SFR_IO_ADDR(SPH)
|
||||
adiw r30, \size
|
||||
out _SFR_IO_ADDR(SPH), \reg2
|
||||
out _SFR_IO_ADDR(SPL), \reg1
|
||||
.endm
|
||||
|
||||
/* +---+---+---------------------+
|
||||
* | i | j | ......<256>........ |
|
||||
* +---+---+---------------------+
|
||||
*/
|
||||
|
||||
.global arcfour_init
|
||||
|
||||
;== arcfour_init ==
|
||||
; this function initialises the context
|
||||
; param1: 16-bit pointer to a ctx struct
|
||||
; given in r25,r24
|
||||
; param2: 16-bit pointer to a key
|
||||
; given in r23,r22
|
||||
; param1: 8-bit integer indicating keylength in byte
|
||||
; given in r20
|
||||
|
||||
/*
|
||||
*== arcfour_init ==
|
||||
* this function initialises the context
|
||||
* param1: 16-bit pointer to the key
|
||||
* given in r24:r25
|
||||
* param2: 8-bit integer indicating keylength in byte
|
||||
* given in r22
|
||||
* param3: 16-bit pointer to a ctx struct
|
||||
* given in r20:r21
|
||||
*/
|
||||
arcfour_init:
|
||||
push r29
|
||||
push r28
|
||||
push r2
|
||||
|
||||
movw r26, r24 /* X points to ctx */
|
||||
movw r30, r22 /* Z points to key */
|
||||
push_ r2, r28, r29
|
||||
movw r26, r20 /* X points to ctx */
|
||||
movw r30, r24 /* Z points to key */
|
||||
st X+, r1
|
||||
st X+, r1 /* X points to S */
|
||||
st X+, r1 /* X points to S */
|
||||
movw r20, r26 /* store pointer to S in r21:r20 */
|
||||
|
||||
1:
|
||||
st X+, r1
|
||||
inc r1
|
||||
brne 1b
|
||||
|
||||
adiw r24, 2 /* r24:r25 points to S */
|
||||
clr r21 /* r21 is j */
|
||||
mov r18, r20 /* r18 is keyindex counter */
|
||||
movw r26, r20
|
||||
clr r18 /* r18 is keyindex counter */
|
||||
clr r0
|
||||
clr r19
|
||||
2:
|
||||
movw r26, r24
|
||||
ld r19, Z+
|
||||
add r21, r19 /* j+= key[i%length] */
|
||||
|
||||
add r26, r1
|
||||
adc r27, r0
|
||||
ld r19, X
|
||||
add r21, r19 /* j += S[i] */
|
||||
|
||||
dec r18 /* check the key-index counter */
|
||||
brne 3f
|
||||
movw r30, r22
|
||||
mov r18, r20
|
||||
3: /* now swap(S[i], S[j]) */ /* r19 is still S[i] */
|
||||
movw r28, r24
|
||||
add r28, r21
|
||||
adc r29, r0 /* Y points to S[j]*/
|
||||
ld r23, X
|
||||
ld r2, Z+
|
||||
add r19, r2
|
||||
add r19, r23
|
||||
movw r28, r20 /* load pointer to S in Y */
|
||||
add r28, r19
|
||||
adc r29, r1
|
||||
ld r2, Y
|
||||
st Y, r19
|
||||
st X, r2
|
||||
inc r1
|
||||
st Y, r23
|
||||
st X+, r2
|
||||
inc r18
|
||||
cp r18, r22
|
||||
brne 3f
|
||||
movw r30, r24
|
||||
clr r18
|
||||
3:
|
||||
inc r0
|
||||
brne 2b
|
||||
|
||||
pop r2
|
||||
pop r28
|
||||
pop r29
|
||||
pop_ r29, r28, r2
|
||||
ret
|
||||
|
||||
/*
|
||||
|
|
|
@ -33,15 +33,16 @@
|
|||
* length is length of key in bytes!
|
||||
*/
|
||||
|
||||
void arcfour_init(arcfour_ctx_t *ctx, void *key, uint8_t length_B){
|
||||
void arcfour_init(const void *key, uint8_t length_B, arcfour_ctx_t *ctx){
|
||||
uint8_t t;
|
||||
unsigned x,y=0;
|
||||
uint16_t x,y=0;
|
||||
for(x=0; x<= 255; ++x)
|
||||
ctx->s[x]=x;
|
||||
|
||||
for(x=0; x<= 255; ++x){
|
||||
y += ctx->s[x] + ((uint8_t*)key)[x % length_B];
|
||||
y &= 0xff;
|
||||
/* ctx->s[y] <--> ctx->s[x] */
|
||||
t = ctx->s[y];
|
||||
ctx->s[y] = ctx->s[x];
|
||||
ctx->s[x] = t;
|
||||
|
|
|
@ -74,7 +74,7 @@ typedef struct arcfour_ctx_st {
|
|||
* \param length_B length of the key in bytes (between 1 and 255)
|
||||
*/
|
||||
|
||||
void arcfour_init(arcfour_ctx_t *ctx, void *key, uint8_t length_B);
|
||||
void arcfour_init(const void *key, uint8_t length_B, arcfour_ctx_t *ctx);
|
||||
|
||||
/** \fn uint8_t arcfour_gen(arcfour_ctx_t *ctx)
|
||||
* \brief generates a byte of keystream
|
||||
|
|
|
@ -38,7 +38,7 @@ char* cipher_name = "Arcfour";
|
|||
* additional validation-functions *
|
||||
*****************************************************************************/
|
||||
void arcfour_genctx_dummy(uint8_t* key, uint16_t keysize, void* ctx){
|
||||
arcfour_init(ctx, key, (keysize+7)/8);
|
||||
arcfour_init(key, (uint8_t)((keysize+7)/8), ctx);
|
||||
}
|
||||
|
||||
|
||||
|
@ -55,6 +55,17 @@ void testrun_nessie_arcfour(void){
|
|||
nessie_stream_run();
|
||||
}
|
||||
|
||||
void testrun_performance_arcfour(void){
|
||||
nessie_stream_ctx.outsize_b = 8; /* actually unused */
|
||||
nessie_stream_ctx.keysize_b = 128; /* this is theone we have refrence vectors for */
|
||||
nessie_stream_ctx.ivsize_b = (uint16_t)-1;
|
||||
nessie_stream_ctx.name = cipher_name;
|
||||
nessie_stream_ctx.ctx_size_B = sizeof(arcfour_ctx_t);
|
||||
nessie_stream_ctx.cipher_genctx = (nessie_stream_genctx_fpt)arcfour_genctx_dummy;
|
||||
nessie_stream_ctx.cipher_enc = (nessie_stream_genenc_fpt)arcfour_gen;
|
||||
|
||||
nessie_stream_run();
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
|
|
Loading…
Reference in New Issue