]> git.cryptolib.org Git - avr-crypto-lib.git/commitdiff
changed arcfour api
authorbg <bg@b1d182e4-1ff8-0310-901f-bddb46175740>
Wed, 6 Aug 2008 18:04:23 +0000 (18:04 +0000)
committerbg <bg@b1d182e4-1ff8-0310-901f-bddb46175740>
Wed, 6 Aug 2008 18:04:23 +0000 (18:04 +0000)
USAGE.blockciphers
USAGE.streamciphers [new file with mode: 0644]
arcfour-asm.S
arcfour.c
arcfour.h
test_src/main-arcfour-test.c

index f0bc9d823392b17ed5cfae86623b3f7ea0f20757..54fb7833c7e451ddede0c86e3d30bd81eb38f2f5 100644 (file)
@@ -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.
  
diff --git a/USAGE.streamciphers b/USAGE.streamciphers
new file mode 100644 (file)
index 0000000..68fb197
--- /dev/null
@@ -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.
+
\ No newline at end of file
index d3ecadbf4857f6fc7e4cfd627c5b38a11120e094..05cac9255180b52b5dc5dbb7554a9936631d465e 100644 (file)
  * 
  */
  
+#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
 
 /*
index 13fb159e7aff4e559e69e91327935e2feb93aca9..7c35a0353f3fef055708ca56ea39f5fd13f32448 100644 (file)
--- a/arcfour.c
+++ b/arcfour.c
  * 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;
index 1f5af2fe6ce82445e119cb64620b813e7dd251ce..23fb458aad26cb272a24806b6166de15c8cfe3b3 100644 (file)
--- a/arcfour.h
+++ b/arcfour.h
@@ -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
index 0e0be9181b9a986971ae360b5c516fff31b08d91..7ebe5277b9db008026b693f2657dd9b9cbca1edc 100644 (file)
@@ -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();    
+}
 
 
 /*****************************************************************************