]> git.cryptolib.org Git - avr-crypto-lib.git/blobdiff - serpent-asm.S
serpent sboxes in asm bitslice
[avr-crypto-lib.git] / serpent-asm.S
index a16f6af26bf2c97bc028d39b17d104b165ab7fe8..50e2082ae94f98ff8ab722d941ad74ed333e622b 100644 (file)
  */
  
 #include <avr/io.h>
-
-/*******************************************************************************
-*  MACRO SECTION                                                               *
-*******************************************************************************/
-
-.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 r0, _SFR_IO_ADDR(SREG)
-       cli
-       in \reg1, _SFR_IO_ADDR(SPL)
-       in \reg2, _SFR_IO_ADDR(SPH)
-       sbiw \reg1, \size 
-       out _SFR_IO_ADDR(SPH), \reg2
-       out _SFR_IO_ADDR(SPL), \reg1
-       out _SFR_IO_ADDR(SREG), r0
-.endm
-
-.macro stack_free size:req, reg1=r30, reg2=r31
-       in r0, _SFR_IO_ADDR(SREG)
-       cli
-       in \reg1, _SFR_IO_ADDR(SPL)
-       in \reg2, _SFR_IO_ADDR(SPH)
-       adiw \reg1, \size 
-       out _SFR_IO_ADDR(SPH), \reg2
-       out _SFR_IO_ADDR(SPL), \reg1
-       out _SFR_IO_ADDR(SREG), r0
-.endm
-
-/*******************************************************************************
-* END of MACRO SECTION                                                         *
-*******************************************************************************/
+#include "avr-asm-macros.S"
 
 /*
 static void serpent_lt(uint8_t *b){
@@ -123,7 +66,6 @@ T1 = 21
 T2 = 22
 T3 = 23
 
-.global serpent_lt
 serpent_lt:
        push_range 4, 17
        movw r26, r24
@@ -278,8 +220,8 @@ serpent_lt:
        
        pop_range 4, 17
        ret
-
 #endif
+
 T0 = 22
 T1 = 23
 T2 = 24
@@ -339,7 +281,6 @@ memeor32:
   brne 1b
   ret
 
-.global serpent_lt
 serpent_lt:
         /* X0 := X0 <<< 13 */
        movw r26, r24
@@ -432,7 +373,6 @@ serpent_lt:
        rcall memrotr32
        ret
 
-.global serpent_inv_lt
 serpent_inv_lt:
         /* X0 := X0 >>> 5 */
        movw r26, r24
@@ -538,7 +478,9 @@ static uint32_t serpent_gen_w(uint32_t * b, uint8_t i){
  * param i is passed in r22
  * return value is returned in r22.r23.r24.r25
  */
-.global serpent_gen_w
+ /* trashes:
+  *  r20-r25, r30-r31
+  */
 serpent_gen_w:
        movw r30, r24
        /* ^i^b[0]*/
@@ -589,3 +531,224 @@ serpent_gen_w:
        brne 1b
        ret
 
+/*
+ * void serpent_init(const void* key, uint16_t keysize_b, serpent_ctx_t* ctx)
+ */
+/*
+ * param key     is passed in r24:r25
+ * param keysize is passed in r22:r23
+ * param ctx     is passed in r20:r21
+ */
+.global serpent_init
+serpent_init:
+    stack_alloc 32
+    adiw r30, 1
+       push_ r30, r31
+    movw r26, r22
+    adiw r26, 7
+    tst r27
+    breq 1f
+       ldi r26, 32
+       rjmp 2f
+1:
+       lsr r26
+       lsr r26
+       lsr r26
+2:     
+       mov r22, r26
+       bst r22, 5 /* store in T if we have to do the "append 1 thing"*/
+       ldi r27, 32
+3:     /* set buffer to zero */
+       st Z+, r1
+       dec r27
+       brne 3b
+       
+       movw r26, r24 /* X points to the key */
+       sbiw r30, 32
+       tst r22
+       breq 5f /* if keylength_b==0 */
+4:     /* copy keybytes to buffer */
+       ld r19, X+
+       st Z+, r19
+       dec r22
+       brne 4b
+5:
+       brts 7f /* if keylength_b == 256 */
+       ldi r18, 0x01
+       andi r22, 0x07
+       brne 6f
+       st Z, r18
+       rjmp 7f
+6:     /* shift the one to the right position */
+       lsl r18
+       dec r22
+       brne 6b
+       or r18, r19
+       st -Z, r18
+7: /* post "appending 1 thing" buffer is ready for subkey generation */
+       movw r26, r20  /* X points to the context */
+       
+       pop_ r19, r18 /* r18:r19 points to the buffer */
+       push r16
+       clr r16
+8:
+       movw r24, r18
+       mov  r22, r16
+       rcall serpent_gen_w
+       movw r30, r18
+       ldi r20, 7*4
+1: /* the memmove */
+       ldd r0, Z+4
+       st Z+, r0
+       dec r20
+       brne 1b
+  /* store new word in buffer and context */   
+       st Z+, r22
+       st Z+, r23
+       st Z+, r24
+       st Z+, r25
+       st X+, r22
+       st X+, r23
+       st X+, r24
+       st X+, r25
+       
+       inc r16
+       cpi r16, 132
+       brne 8b 
+       
+       push_ r28, r29
+       movw r28, r26
+       subi r28, lo8(132*4)
+       sbci r29, hi8(132*4)
+       ldi r16, 33
+2:
+       movw r24, r28
+       adiw r28, 16
+       ldi r22, 2
+       add r22, r16
+       rcall sbox128
+       dec r16
+       brne 2b
+       pop_ r29, r28, r16
+       stack_free 32
+       ret
+
+/*
+ * void serpent_enc(void* buffer, const serpent_ctx_t* ctx){
+ */
+/*
+ * param buffer is passed in r24:r25
+ * param ctx    is passed in r22:r23
+ */
+.global serpent_enc
+serpent_enc:
+
+       push_ r12, r13, r14, r15, r16 
+       clr r16
+       movw r14, r24
+       movw r12, r22
+1:
+       movw r24, r14
+       movw r22, r12
+       ldi r20, 16
+       add r12, r20
+       adc r13, r1
+       clr r21
+       rcall memxor
+       movw r24, r14
+       mov r22, r16
+       rcall sbox128
+       movw r24, r14
+       rcall serpent_lt
+       
+       inc r16
+       cpi r16, 31
+       brne 1b
+       
+       movw r24, r14
+       movw r22, r12
+       ldi r20, 16
+       add r12, r20
+       adc r13, r1
+       clr r21
+       rcall memxor
+       movw r24, r14
+       mov r22, r16
+       rcall sbox128
+       
+       inc r16
+       movw r24, r14
+       movw r22, r12
+       ldi r20, 16
+       clr r21
+       pop_ r16, r15, r14, r13, r12
+       rjmp memxor
+
+/*
+ * void serpent_dec(void* buffer, const serpent_ctx_t* ctx){
+ */
+/*
+ * param buffer is passed in r24:r25
+ * param ctx    is passed in r22:r23
+ */
+.global serpent_dec
+serpent_dec:
+       push_ r12, r13, r14, r15, r16 
+       movw r14, r24
+//     ldi r16, lo8(32*16)
+//     add r22, r16
+       ldi r16, hi8(32*16)
+       add r23, r16
+       movw r12, r22
+       ldi r20, 16
+       clr r21
+       rcall memxor
+       
+       movw r24, r14
+       ldi r22, 31
+       call inv_sbox128
+       
+       movw r24, r14
+       ldi r20, 16
+       sub r12, r20
+       sbc r13, r1
+       movw r22, r12
+       clr r21
+       rcall memxor
+       ldi r16, 31
+1:
+       dec r16
+       movw r24, r14
+       rcall serpent_inv_lt
+       movw r24, r14
+       mov r22, r16
+       rcall inv_sbox128
+       movw r24, r14
+       ldi r20, 16
+       sub r12, r20
+       sbc r13, r1
+       movw r22, r12
+       clr r21
+       rcall memxor
+       
+       tst r16
+       brne 1b
+       pop_ r16, r15, r14, r13, r12
+       ret     
+       
+       
+       
+
+
+
+
+
+
+
+
+
+
+
+
+
+