 |
;(C)2005 wek http://www.efton.sk
;free for personal use
;for commercial use, please contact wek@efton.sk
;implementation of original TEA algorithm by Needham&Wheeler for AVR
;
;uses 8 bytes of SRAM (input/output data) and 14 registers
;!!! uses reordered key !!!
;;!!! reordered key !!! k[1]k[0]k[3]k[2]
;6861 cycles
;5E=94 words = 188 bytes, excl. key
;no stack
;key can be easily placed into SRAM - replace lpm xxx,Z+ by ld xxx,Z+
;for devices which don't support lpm xxx,Z+ replace it by lpm; mov xxx,r0
.dseg
ydata: .byte 4
zdata: .byte 4
;register definitions
.def ZL = r30
.def ZH = r31
.def YL = r28
.def YH = r29
.def tmp0 = r1
.def tmp1 = r2
.def tmp2 = r3
.def tmp3 = r4
.def tmp4 = r5
.def tmp5 = r6
.def tmp6 = r7
.def tmp7 = r8
.def tmp8 = r9
.def sum0 = r16
.def sum1 = r17
.def sum2 = r18
.def sum3 = r19
.def RoundCnt = r20
.cseg
Tea:
ldi RoundCnt,2*32
clr sum0
clr sum1
clr sum2
clr sum3
ldi YL,LOW(zdata)
ldi YH,HIGH(zdata)
ldd tmp0,Y+0
ldd tmp1,Y+1
ldd tmp2,Y+2
ldd tmp3,Y+3
TeaRound:
ldi ZL,LOW(Key*2)
ldi ZH,HIGH(Key*2)
subi sum0,$47
sbci sum1,$86
sbci sum2,$C8
sbci sum3,$61
TeaSubRound:
clr tmp4 ;z>>5 but as (z<<3)>>8 (simultaneously preparing for z<<4)
lsl tmp0
rol tmp1
rol tmp2
rol tmp3
rol tmp4
lsl tmp0
rol tmp1
rol tmp2
rol tmp3
rol tmp4
lsl tmp0
rol tmp1
rol tmp2
rol tmp3
rol tmp4
lpm tmp5,Z+ ;!!! reordered key !!! k[1]k[0]k[3]k[2]
add tmp5,tmp1 ;z>>5 + key[1]
lpm tmp6,Z+
adc tmp6,tmp2
lpm tmp7,Z+
adc tmp7,tmp3
lpm tmp8,Z+
adc tmp8,tmp4
lsl tmp0 ;last shift for z<<4
rol tmp1
rol tmp2
rol tmp3
lpm tmp4,Z+ ;z<<4 + key[0]
add tmp0,tmp4
lpm tmp4,Z+
adc tmp1,tmp4
lpm tmp4,Z+
adc tmp2,tmp4
lpm tmp4,Z+
adc tmp3,tmp4
eor tmp5,tmp0 ;xor the first two parts
eor tmp6,tmp1
eor tmp7,tmp2
eor tmp8,tmp3
ldd tmp0,Y+0 ;z+sum
ldd tmp1,Y+1
ldd tmp2,Y+2
ldd tmp3,Y+3
add tmp0,sum0
adc tmp1,sum1
adc tmp2,sum2
adc tmp3,sum3
eor tmp0,tmp5
eor tmp1,tmp6
eor tmp2,tmp7
eor tmp3,tmp8
sbrc RoundCnt,0 ;in the first subround increment sum (AVR: decrement by its neg)
rjmp TeaRoundX3
ldi YL,LOW(ydata) ;and set pointer to ydata to add the calculated value in tmp (and it remains valid for the next
subround, too)
ldi YH,HIGH(ydata)
rjmp TeaRoundX4
TeaRoundX3:
ldi YL,LOW(zdata) ;in the second subround only set pointer to zdata
ldi YH,HIGH(zdata)
TeaRoundX4:
ldd tmp4,Y+0 ;add the calculated value to y or z
add tmp0,tmp4
std Y+0,tmp0
ldd tmp4,Y+1
adc tmp1,tmp4
std Y+1,tmp1
ldd tmp4,Y+2
adc tmp2,tmp4
std Y+2,tmp2
ldd tmp4,Y+3
adc tmp3,tmp4
std Y+3,tmp3
dec RoundCnt
brne TeaRoundA
ret
TeaRoundA:
sbrs RoundCnt,0
rjmp TeaRound
rjmp TeaSubRound
Key:
; .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.db $0f,$1e,$2d,$3c
.db $4b,$5a,$69,$78
.db $87,$96,$a5,$b4
.db $c3,$d2,$e1,$f0
|