]> git.cryptolib.org Git - avr-crypto-lib.git/commitdiff
+A5/1
authorbg <bg@b1d182e4-1ff8-0310-901f-bddb46175740>
Mon, 28 Apr 2008 02:48:49 +0000 (02:48 +0000)
committerbg <bg@b1d182e4-1ff8-0310-901f-bddb46175740>
Mon, 28 Apr 2008 02:48:49 +0000 (02:48 +0000)
A5_1.c
A5_1.h

diff --git a/A5_1.c b/A5_1.c
index 6e6407822339cfcb0e0767cae38b6c9769174b01..ff1bb9606e816ebfd4bd4aa09973ad9183a6f229 100644 (file)
--- a/A5_1.c
+++ b/A5_1.c
  */
  
 #include <stdint.h>
+#include <string.h>
 #include "A5_1.h"
+#include <avr/pgmspace.h>
+
+uint8_t a5_1_clock_core(a5_1_ctx_t *c, uint8_t clockoverride);
+
 
 /*
  * length is length of key in bytes!
  */
-#define BYTEn(p,s) (*(((uint8_t*)&(p))+s))
-
-void           a5_1_init(a5_1_ctx_t *c, uint8_t *key, uint8_t length);
-
-bool    a5_1_clock(a5_1_ctx_t *c){
-       bool x1,x2,x3, maj;
-       x1 = PARITY_LOOKUP & (1<< ((BYTEn(c->r1,2)+BYTEn(c->r1,1)>>5) & 0x7);
-       x2 = PARITY_LOOKUP & (1<< (BYTEn(c->r2,2)>>4));
-       x3 = PARITY_LLOKUP & (1<< ((BYTEn(c->r3,2)>>4+BYTEn(c->r3,0)>>7) & 0x7));
-       maj = (((c->r1 & (1<<R1_CLK))?1:0)+((c->r2 & (1<<R2_CLK))?1:0)+((c->r3 & (1<<R3_CLK))?1:0))>=2;
-       if (((c->r1 & (1<<R1_CLK))>>R1_CLK) == maj)
-               c->r1 = c->r1<<1 + x1;
-       if (((c->r2 & (1<<R2_CLK))>>R2_CLK) == maj)
-               c->r2 = c->r2<<1 + x2;
-       if (((c->r3 & (1<<R3_CLK))>>R3_CLK) == maj)
-               c->r3 = c->r3<<1 + x3;
-               
-       return ((c->r1)>>(R1_LENGTH-1)+(c->r2)>>(R2_LENGTH-1)+(c->r3)>>(R3_LENGTH-1))&0x1;
+
+void a5_1_init(a5_1_ctx_t *c, void* key, uint8_t keylength_b, void* iv, uint8_t ivlength_b){
+       uint8_t i,t;
+       memset(c->r1, 0, 3);
+       memset(c->r2, 0, 3);
+       memset(c->r3, 0, 3);
+       for(i=0; i<keylength_b; ++i){
+               t=((uint8_t*)key)[i/8];
+               t=1&(t>>i);
+               c->r1[0] ^= t;
+               c->r2[0] ^= t;
+               c->r3[0] ^= t;
+               a5_1_clock_core(c, 0x7);
+       }
+       for(i=0; i<ivlength_b; ++i){
+               t=((uint8_t*)iv)[i/8];
+               t=1&(t>>i);
+               c->r1[0] ^= t;
+               c->r2[0] ^= t;
+               c->r3[0] ^= t;
+               a5_1_clock_core(c, 0x7);
+       }
+       for(i=0; i<100; ++i)
+               a5_1_clock_core(c,0);
+}
+
+static
+void shiftreg(uint8_t* d){
+       uint8_t c, c2;
+       c=d[0]>>7;
+       d[0] <<= 1;
+       c2=d[1]>>7;
+       d[1] = (d[1]<<1) | c;
+       d[2] = (d[2]<<1) | c2;
+} 
+
+       uint8_t parity3_lut[] PROGMEM = {0, 1, 1, 0,
+                                            1, 0, 0, 1};       
+       uint8_t clock_lut[] PROGMEM =  {0x7, 0x6, 0x5, 0x3,
+                                           0x3, 0x5, 0x6, 0x7}; 
+                                           
+uint8_t a5_1_clock_core(a5_1_ctx_t *c, uint8_t clockoverride){
+       uint8_t ret,clk,fb;
+       ret = (0x04&c->r1[2]) | (0x20&c->r2[2]) | (0x40&c->r3[2]);
+       ret = ret^(ret>>6);
+       ret &= 0x7;
+       ret = pgm_read_byte(parity3_lut+ret);
+       clk = (0x08&c->r1[1]) | (0x10&c->r2[1]) | (0x20&c->r3[1]);
+       clk >>= 3;
+       clk = pgm_read_byte(clock_lut+clk);
+       clk |= clockoverride;
+       
+       if(clk&1){
+               fb = c->r1[2] ^ (1&((c->r1[1])>>5));
+               fb &= 0x7;
+               fb = pgm_read_byte(parity3_lut+fb);
+               shiftreg(c->r1);
+               c->r1[0] |= fb;
+               c->r1[2] &= 0x07;
+       }
+       clk>>=1;
+       if(clk&1){
+               fb = c->r2[2]>>4 ;
+               fb &= 0x7;
+               fb = pgm_read_byte(parity3_lut+fb);
+               shiftreg(c->r2);
+               c->r2[0] |= fb;
+               c->r2[2] &= 0x3F;
+       
+       }
+       clk>>=1;
+       if(clk&1){
+               fb = (c->r3[2]>>4) ^ (1&((c->r3[0])>>7));
+               fb &= 0x7;
+               fb = pgm_read_byte(parity3_lut+fb);
+               shiftreg(c->r3);
+               c->r3[0] |= fb;
+               c->r3[2] &= 0x7F;
+       }
+       return ret;
 }
 
-uint8_t a5_1_gen(a5_   1_ctx_t *c){
+uint8_t a5_1_clock(a5_1_ctx_t *c){
+       return a5_1_clock_core(c, 0);
+}
+
+
+uint8_t a5_1_gen(a5_1_ctx_t *c){
        uint8_t ret=0;
        ret = a5_1_clock(c);
        ret <<= 1;
diff --git a/A5_1.h b/A5_1.h
index 8803198b644698283761b4c5e1105054670af0b1..a6f963a1c89b212988ad0028957cc6474ec1b214 100644 (file)
--- a/A5_1.h
+++ b/A5_1.h
 #define PARITY_LOOKUP 0x96
 
 typedef struct {
-       uint32_t r1,r2,r3; /* the three regs, 19,22,23 bit in length  */
+       /* we are wasting one byte here but this allows a much faster implementation */
+       uint8_t r1[3], r2[3], r3[3]; /* the three regs, 19,22,23 bit in length  */
 } a5_1_ctx_t;
  
 
-void           a5_1_init(a5_1_ctx_t *c, uint8_t *key, uint8_t length);
-bool           a5_1_clock(a5_1_ctx_t *c);
-uint8_t a5_1_gen(a5_   1_ctx_t *c);
+void           a5_1_init(a5_1_ctx_t *c, void* key, uint8_t keylength_b, void* iv, uint8_t ivlength_b);
+uint8_t                a5_1_clock(a5_1_ctx_t *c);
+uint8_t        a5_1_gen(a5_1_ctx_t *c);
 
 #endif