;
; XTEA decipher routine
;
; *******************************************************************
; DECLARACIONES
; *******************************************************************
#include <avr/io.h>
#define XTEA_ROUNDS 32
#define DELTA 0x9E3779B9
#define XTEA_KEY1 0x87654321
#define XTEA_KEY2 0x87654321
#define XTEA_KEY3 0x87654321
#define XTEA_KEY4 0x87654321
#define DELTA_SUMA (DELTA*XTEA_ROUNDS)
// Call saved registers
#define data0 r2
#define data1 r3
#define data2 r4
#define data3 r5
#define data4 r6
#define data5 r7
#define data6 r8
#define data7 r9
#define temp0 r10
#define temp1 r11
#define temp2 r12
#define temp3 r13
#define buff0 r14
#define buff1 r15
#define ZL r30
// Free registers
#define rounds r17
#define suma0 r18
#define suma1 r19
#define suma2 r20
#define suma3 r21
#define r_index r22
#define temp4 r24
#define temp5 r25
#define temp6 r26
#define temp7 r27
#define ZH r31
; *******************************************************************
; DATOS EN RAM
; *******************************************************************
.data
.comm save_reg, 20
; *******************************************************************
; PROGRAMA
; *******************************************************************
.text
; xtea_decode
;
; Inputs:
; data0 ... data7 = 8 bytes of coded data
;
; Outputs:
; data0 ... data7 = 8 bytes of decoded data
;
.global xtea_decode
xtea_decode:
; Save registers
rcall xtea_save_reg
; suma = 0xC6EF3720 = DELTA*32
ldi suma0, lo8(DELTA_SUMA)
ldi suma1, hi8(DELTA_SUMA)
ldi suma2, hlo8(DELTA_SUMA)
ldi suma3, hhi8(DELTA_SUMA)
; rounds = 64
ldi rounds, XTEA_ROUNDS*2
; do {
xtea_decode_loop:
; temp_a = data0
movw temp0, data0
movw temp2, data2
; temp_b = data0
movw temp4, data0
movw temp6, data2
; data0 = data1
movw data0, data4
movw data2, data6
; data1 = temp_a
movw data4, temp0
movw data6, temp2
; temp_a <<= 4
ldi r_index, 4
xtea_shift_left:
lsl temp0
rol temp1
rol temp2
rol temp3
dec r_index
brne xtea_shift_left
; temp_b >>= 5
ldi r_index, 5
xtea_shift_right:
lsr temp7
ror temp6
ror temp5
ror temp4
dec r_index
brne xtea_shift_right
; temp_a ^= temp_b
eor temp0, temp4
eor temp1, temp5
eor temp2, temp6
eor temp3, temp7
; temp_a += data1
add temp0, data4
adc temp1, data5
adc temp2, data6
adc temp3, data7
; if ((rounds & 1) == 0):
; r1 = ((suma>>11) & 3)*4
sbrc rounds, 0
rjmp xtea_label_1
mov r_index, suma1
lsr r_index
rjmp xtea_label_2
; else:
; r1 = (suma & 3)*4
xtea_label_1:
mov r_index, suma0
lsl r_index
lsl r_index
xtea_label_2:
andi r_index, 0x0C
; temp_b = xtea_key[r1*4]
ldi ZL, lo8(xtea_key_table)
ldi ZH, hi8(xtea_key_table)
add ZL, r_index
ldi r_index, 0
adc ZH, r_index
lpm temp4, Z+
lpm temp5, Z+
lpm temp6, Z+
lpm temp7, Z+
; temp_b += suma
add temp4, suma0
adc temp5, suma1
adc temp6, suma2
adc temp7, suma3
; temp_a ^= temp_b
eor temp0, temp4
eor temp1, temp5
eor temp2, temp6
eor temp3, temp7
; data0 -= temp_a
sub data0, temp0
sbc data1, temp1
sbc data2, temp2
sbc data3, temp3
; if ((rounds & 1) == 0):
; suma -= 0x9E3779B9
sbrc rounds, 0
rjmp xtea_label_3
subi suma0, lo8(DELTA)
sbci suma1, hi8(DELTA)
sbci suma2, hlo8(DELTA)
sbci suma3, hhi8(DELTA)
xtea_label_3:
; rounds -= 1
; } while(rounds);
dec rounds
breq xtea_end_loop
rjmp xtea_decode_loop
xtea_end_loop:
; Load registers
rcall xtea_load_reg
ret
; *******************************************************************
; FUNCIONES DE APOYO
; *******************************************************************
xtea_save_reg:
; Save registers in sram
sts save_reg+1, data0
sts save_reg+1, data1
sts save_reg+2, data2
sts save_reg+3, data3
sts save_reg+4, data4
sts save_reg+5, data5
sts save_reg+6, data6
sts save_reg+7, data7
sts save_reg+8, temp0
sts save_reg+9, temp1
sts save_reg+10, temp2
sts save_reg+11, temp3
sts save_reg+12, buff0
sts save_reg+13, buff1
sts save_reg+14, ZL
sts save_reg+15, ZH
movw buff0, r24
movw ZL, buff0
ld data0, Z+
ld data1, Z+
ld data2, Z+
ld data3, Z+
ld data4, Z+
ld data5, Z+
ld data6, Z+
ld data7, Z+
ret
xtea_load_reg:
; Load registers from sram
movw ZL, buff0
st Z+, data0
st Z+, data1
st Z+, data2
st Z+, data3
st Z+, data4
st Z+, data5
st Z+, data6
st Z+, data7
lds data0, save_reg+1
lds data1, save_reg+1
lds data2, save_reg+2
lds data3, save_reg+3
lds data4, save_reg+4
lds data5, save_reg+5
lds data6, save_reg+6
lds data7, save_reg+7
lds temp0, save_reg+8
lds temp1, save_reg+9
lds temp2, save_reg+10
lds temp3, save_reg+11
lds buff0, save_reg+12
lds buff1, save_reg+13
lds ZL, save_reg+14
lds ZH, save_reg+15
ret
; *******************************************************************
; DATOS EN FLASH
; *******************************************************************
xtea_key_table:
.long XTEA_KEY1
.long XTEA_KEY2
.long XTEA_KEY3
.long XTEA_KEY4