; ; Copyright © François-Xavier Standaert, 2011. ; e-mail: . ; ; This program is a free software: you can redistribute it ; and/or modify it under the terms of the GNU General Public ; License as published by the Free Software Foundation. ; ; It is distributed without any warranty of correctness nor ; fintess for any particular purpose. See the GNU General ; Public License for more details. ; ; . ; ; Description: SEA 96-bit encryption/descryption. ; Version 1 - June 2011. ; ; ; ---------------------------------------------------- ; | User interface: | ; |----------------------------------------------------| ; |(1) Load plaintext/key in SRAM at the address | ; | pointed by X register (r27:r26): | ; | -> The 12 first bytes are the plaintext, | ; | -> The 12 last bytes are the key. | ; |----------------------------------------------------| ; |(2) Call the encrypt or decrypt routine. | ; |----------------------------------------------------| ; |(3) After the SEA call, the plaintext is overloaded | ; | by its corresponding ciphertext in SRAM, the | ; | key is in its initial state again. | ; ---------------------------------------------------- ; ; ; Constants ; .EQU PTEXT_NUM_BYTE = 12 .EQU CTEXT_NUM_BYTE = 12 .EQU KEY_NUM_BYTE = 12 .EQU ADD_MEM_NUM_BYTE = 0 ;Additional memory for internal computation .EQU TOT_NUM_BYTE = PTEXT_NUM_BYTE+KEY_NUM_BYTE+ADD_MEM_NUM_BYTE .EQU SRAM_PTEXT = SRAM_DATA .EQU SRAM_KEY = SRAM_DATA + PTEXT_NUM_BYTE .EQU SRAM_CTEXT = SRAM_PTEXT ; ; Registers declarations ; ; R >= 16 .def temp = R16 ; temporary storage .def temp2 = R17 ; temporary storage .def x0 = R18 ; state register 0 .def x3 = R19 ; state register 3 .def i = R20 ; round counter ; R < 16 .def x1 = R0 ; state register 1 .def x2 = R1 ; state register 2 .def x4 = R2 ; state register 4 .def x5 = R3 ; state register 5 .def temp3 = R4 ; temporary storage .cseg ; ; SEA encryption subroutines ; ram2reg: ; loads 6 bytes from SRAM to state registers add r26,temp; ld x0,x+; ld x1,x+; ld x2,x+; ld x3,x+; ld x4,x+; ld x5,x+; subi r26,6; sub r26,temp; ret; reg2ram: ; stores 6 states registers in SRAM add r26,temp; st x+,x0; st x+,x1; st x+,x2; st x+,x3; st x+,x4; st x+,x5; subi r26,6; sub r26,temp; ret; switch_ram: ; inverts left and right Feistel branches add r26,temp; ldi x3,0; switch_a: ld x0,x; adiw r27:r26,6; ld x1,x; st x,x0; subi r26,6; st x+,x1; inc x3; cpi x3,6; breq switch_b; rjmp switch_a; switch_b: subi r26,6; sub r26,temp; ret; ram2ram: ; stores right Feistel branch into left one add r26,temp; ldi temp2,0; ram2ram_a: ld temp3,x; adiw r27:r26,6; st x,temp3; subi r26,5; inc temp2; cpi temp2,6; breq ram2ram_b; rjmp ram2ram_a; ram2ram_b: subi r26,6; sub r26,temp; ret r: ; bit rotation clr temp; clc; rol x2; adc x2,temp; ror x0; brcc endr1; ori x0,128; endr1: clc; rol x5; adc x5,temp; ror x3; brcc endr2; ori x3,128; endr2: ret s: ; S-box mov temp,x1; and temp,x2; eor x0,temp; mov temp,x0; and temp,x2; eor x1,temp; mov temp,x1; or temp,x0; eor x2,temp; mov temp,x4; and temp,x5; eor x3,temp; mov temp,x3; and temp,x5; eor x4,temp; mov temp,x4; or temp,x3; eor x5,temp; ret; keyround: ; keyround function ldi temp,12; rcall ram2reg; cpi i,47; brmi keyround_a; ldi temp,93; sub temp,i; add x0,temp; rjmp keyround_b; keyround_a: add x0,i; keyround_b: rcall s; rcall r; adiw r27:r26,24; mov temp2,x5; ld x5,-x; eor x5,x4; ld x4,-x; eor x4,x3; ld x3,-x; eor x3,x2; ld x2,-x; eor x2,x1; ld x1,-x; eor x1,x0; ld x0,-x; eor x0,temp2; subi r26,18 ldi temp,12; rcall ram2ram; rcall reg2ram; ret; round: ; round function ldi temp,0; rcall ram2reg; cpi i,48; brmi round_a; adiw r27:r26,18; ld temp2,x+; add x0,temp2; ld temp2,x+; add x1,temp2; ld temp2,x+; add x2,temp2; ld temp2,x+; add x3,temp2; ld temp2,x+; add x4,temp2; ld temp2,x+; add x5,temp2; subi r26,24; rjmp round_b; round_a: adiw r27:r26,12; ld temp2,x+; add x0,temp2; ld temp2,x+; add x1,temp2; ld temp2,x+; add x2,temp2; ld temp2,x+; add x3,temp2; ld temp2,x+; add x4,temp2; ld temp2,x+; add x5,temp2; subi r26,18; round_b: rcall s; rcall r; brbs 6,round_c; adiw r27:r26,6; ld temp2,x+; eor x0,temp2; ld temp2,x+; eor x1,temp2; ld temp2,x+; eor x2,temp2; ld temp2,x+; eor x3,temp2; ld temp2,x+; eor x4,temp2; ld temp2,x+; eor x5,temp2; subi r26,12; rjmp round_d; round_c: adiw r27:r26,6 ld temp2,x+; eor x1,temp2; ld temp2,x+; eor x2,temp2; ld temp2,x+; eor x3,temp2; ld temp2,x+; eor x4,temp2; ld temp2,x+; eor x5,temp2; ld temp2,x+; eor x0,temp2; subi r26,12; round_d: ldi temp,0; rcall ram2ram; brbs 6,round_e; st x+,x1; st x+,x2; st x+,x3; st x+,x4; st x+,x5; st x+,x0; subi r26,6; rjmp round_f; round_e: ldi temp,0; rcall reg2ram; round_f: ret; sea_encrypt: ; SEA encryption routine rcall round; cpi i,47; brne encrypt_a; ldi temp,12; rcall switch_ram encrypt_a: cpi i,93 breq end; rcall keyround; inc i; rjmp sea_encrypt; end: ;rcall sw; ldi temp,12; rcall switch_ram; ldi temp,0; rcall switch_ram; ret encrypt: ldi i,1 ; reset the round counter bset 6 ; T bit set => encrypt rcall sea_encrypt ret decrypt: ; SEA encryption routine ldi i,1 ; reset the round counter bclr 6 ; T bit set => encrypt rcall sea_encrypt ret