/* serpent_asm.S */
/*
- This file is part of the Crypto-avr-lib/microcrypt-lib.
+ This file is part of the AVR-Crypto-Lib.
Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
This program is free software: you can redistribute it and/or modify
*/
#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){
T2 = 22
T3 = 23
-.global serpent_lt
serpent_lt:
push_range 4, 17
movw r26, r24
pop_range 4, 17
ret
-
#endif
+
T0 = 22
T1 = 23
T2 = 24
brne 1b
ret
-.global serpent_lt
serpent_lt:
/* X0 := X0 <<< 13 */
movw r26, r24
rcall memrotr32
ret
-.global serpent_inv_lt
serpent_inv_lt:
/* X0 := X0 >>> 5 */
movw r26, r24
* 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]*/
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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+