; ; Copyright © François Koeune, 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: TEA encryption (little-endian version). ; Version 1 - June 2011. ; ; ; ; ---------------------------------------------------- ; | User interface: | ; |----------------------------------------------------| ; |(1) Load plaintext in SRAM at the address | ; | pointed by X register (r27:r26) | ; | -> The 8 first bytes are the plaintext | ; | -> The next 16 bytes are the key | ; |----------------------------------------------------| ; |(2) Call the encrypt routine. | ; |----------------------------------------------------| ; |(3) After the ENCRYPT call, the plaintext is | ; | overloaded by its corresponding ciphertext in | ; | SRAM, the key is in its initial state again. | ; ---------------------------------------------------- ; ; ; Constants ; .EQU PTEXT_NUM_BYTE = 8 .EQU CTEXT_NUM_BYTE = 8 .EQU KEY_NUM_BYTE = 16 .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 ; ======================================================================== ; We use little-endian approach, i.e. ; [r0,r1,r2,r3] corresponds to the 32-bit value ; r3*2^24 + r2*2^16 + r1*8 + r0 ; ======================================================================== ; ======================================================================== ; Registers allocation ; ======================================================================== .def v00 = r0 ; v0 .def v01 = r1 .def v02 = r2 .def v03 = r3 .def v10 = r4 ; v1 .def v11 = r5 .def v12 = r6 .def v13 = r7 .def bufv0 = r16 ; bufv (buffer where v0,v1 updates are built) .def bufv1 = r17 .def bufv2 = r18 .def bufv3 = r19 .def tmp0 = r20 ; tmp (scratch buffer) .def tmp1 = r21 .def tmp2 = r22 .def tmp3 = r23 .def tmp4 = r12 .def tmp5 = r13 .def tmp6 = r14 .def tmp7 = r15 .def sum0 = r8 ; sum .def sum1 = r9 .def sum2 = r10 .def sum3 = r11 .def loop1 = r27 ; loop counter 1 .def loop2 = r26 ; ======================================================================== .cseg ; ======================================================================== ; encryption round ; ======================================================================== encround: ; sum+=delta ldi tmp0,$b9 ; tmp = delta ldi tmp1,$79 ldi tmp2,$37 ldi tmp3,$9e add sum0,tmp0 ; sum += tmp adc sum1,tmp1 adc sum2,tmp2 adc sum3,tmp3 ; v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1); ld bufv0,z+ ; bufv = k0 ld bufv1,z+ ld bufv2,z+ ld bufv3,z+ mov tmp0,v10 ; tmp = v1 << 4 mov tmp1,v11 mov tmp2,v12 mov tmp3,v13 ldi loop2,4 encround_loop1: lsl tmp0 rol tmp1 rol tmp2 rol tmp3 dec loop2 brne encround_loop1 add bufv0,tmp0 ; bufv += tmp adc bufv1,tmp1 adc bufv2,tmp2 adc bufv3,tmp3 mov tmp0,v10 ; tmp = v1 + sum mov tmp1,v11 mov tmp2,v12 mov tmp3,v13 add tmp0,sum0 adc tmp1,sum1 adc tmp2,sum2 adc tmp3,sum3 eor bufv0,tmp0 ; bufv ^= tmp eor bufv1,tmp1 eor bufv2,tmp2 eor bufv3,tmp3 mov tmp4,v10 ; tmp = v1 >> 5 mov tmp0,v11 mov tmp1,v12 mov tmp2,v13 ldi tmp3,0 ldi loop2,3 encround_loop2: lsl tmp4 rol tmp0 rol tmp1 rol tmp2 rol tmp3 dec loop2 brne encround_loop2 ld tmp4,z+ ; tmp2 = k1 ld tmp5,z+ ld tmp6,z+ ld tmp7,z+ add tmp0,tmp4 ; tmp += tmp2 adc tmp1,tmp5 adc tmp2,tmp6 adc tmp3,tmp7 eor bufv0,tmp0 ; bufv ^= tmp eor bufv1,tmp1 eor bufv2,tmp2 eor bufv3,tmp3 add v00,bufv0 ; v0 += bufv adc v01,bufv1 adc v02,bufv2 adc v03,bufv3 ; v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3); ld bufv0,z+ ; bufv = k2 ld bufv1,z+ ld bufv2,z+ ld bufv3,z+ mov tmp0,v00 ; tmp = v0 << 4 mov tmp1,v01 mov tmp2,v02 mov tmp3,v03 ldi loop2,4 encround_loop3: lsl tmp0 rol tmp1 rol tmp2 rol tmp3 dec loop2 brne encround_loop3 add bufv0,tmp0 ; bufv += tmp adc bufv1,tmp1 adc bufv2,tmp2 adc bufv3,tmp3 mov tmp0,v00 ; tmp = v0 + sum mov tmp1,v01 mov tmp2,v02 mov tmp3,v03 add tmp0,sum0 adc tmp1,sum1 adc tmp2,sum2 adc tmp3,sum3 eor bufv0,tmp0 ; bufv ^= tmp eor bufv1,tmp1 eor bufv2,tmp2 eor bufv3,tmp3 mov tmp4,v00 ; tmp = v0 >> 5 mov tmp0,v01 mov tmp1,v02 mov tmp2,v03 ldi tmp3,0 ldi loop2,3 encround_loop4: lsl tmp4 rol tmp0 rol tmp1 rol tmp2 rol tmp3 dec loop2 brne encround_loop4 ld tmp4,z+ ; tmp2 = k3 ld tmp5,z+ ld tmp6,z+ ld tmp7,z add tmp0,tmp4 ; tmp += tmp2 adc tmp1,tmp5 adc tmp2,tmp6 adc tmp3,tmp7 eor bufv0,tmp0 ; bufv ^= tmp eor bufv1,tmp1 eor bufv2,tmp2 eor bufv3,tmp3 add v10,bufv0 ; v1 += bufv adc v11,bufv1 adc v12,bufv2 adc v13,bufv3 sbiw zh:zl,15 ; reset key pointer ret ; ======================================================================== ; decryption round ; ======================================================================== decround: ; v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3); adiw zh:zl,8 ; bufv = k2 ld bufv0,z+ ld bufv1,z+ ld bufv2,z+ ld bufv3,z+ mov tmp0,v00 ; tmp = v0 << 4 mov tmp1,v01 mov tmp2,v02 mov tmp3,v03 ldi loop2,4 decround_loop1: lsl tmp0 rol tmp1 rol tmp2 rol tmp3 dec loop2 brne decround_loop1 add bufv0,tmp0 ; bufv += tmp adc bufv1,tmp1 adc bufv2,tmp2 adc bufv3,tmp3 mov tmp0,v00 ; tmp = v0 + sum mov tmp1,v01 mov tmp2,v02 mov tmp3,v03 add tmp0,sum0 adc tmp1,sum1 adc tmp2,sum2 adc tmp3,sum3 eor bufv0,tmp0 ; bufv ^= tmp eor bufv1,tmp1 eor bufv2,tmp2 eor bufv3,tmp3 mov tmp4,v00 ; tmp = v0 >> 5 mov tmp0,v01 mov tmp1,v02 mov tmp2,v03 ldi tmp3,0 ldi loop2,3 decround_loop2: lsl tmp4 rol tmp0 rol tmp1 rol tmp2 rol tmp3 dec loop2 brne decround_loop2 ld tmp4,z+ ; tmp2 = k3 ld tmp5,z+ ld tmp6,z+ ld tmp7,z+ add tmp0,tmp4 ; tmp += tmp2 adc tmp1,tmp5 adc tmp2,tmp6 adc tmp3,tmp7 eor bufv0,tmp0 ; bufv ^= tmp eor bufv1,tmp1 eor bufv2,tmp2 eor bufv3,tmp3 sub v10,bufv0 ; v1 -= bufv sbc v11,bufv1 sbc v12,bufv2 sbc v13,bufv3 ; v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1); sbiw zh:zl,16 ; bufv = k0 ld bufv0,z+ ld bufv1,z+ ld bufv2,z+ ld bufv3,z+ mov tmp0,v10 ; tmp = v1 << 4 mov tmp1,v11 mov tmp2,v12 mov tmp3,v13 ldi loop2,4 decround_loop3: lsl tmp0 rol tmp1 rol tmp2 rol tmp3 dec loop2 brne decround_loop3 add bufv0,tmp0 ; bufv += tmp adc bufv1,tmp1 adc bufv2,tmp2 adc bufv3,tmp3 mov tmp0,v10 ; tmp = v1 + sum mov tmp1,v11 mov tmp2,v12 mov tmp3,v13 add tmp0,sum0 adc tmp1,sum1 adc tmp2,sum2 adc tmp3,sum3 eor bufv0,tmp0 ; bufv ^= tmp eor bufv1,tmp1 eor bufv2,tmp2 eor bufv3,tmp3 mov tmp4,v10 ; tmp = v1 >> 5 mov tmp0,v11 mov tmp1,v12 mov tmp2,v13 ldi tmp3,0 ldi loop2,3 decround_loop4: lsl tmp4 rol tmp0 rol tmp1 rol tmp2 rol tmp3 dec loop2 brne decround_loop4 ld tmp4,z+ ; tmp2 = k1 ld tmp5,z+ ld tmp6,z+ ld tmp7,z add tmp0,tmp4 ; tmp += tmp2 adc tmp1,tmp5 adc tmp2,tmp6 adc tmp3,tmp7 eor bufv0,tmp0 ; bufv ^= tmp eor bufv1,tmp1 eor bufv2,tmp2 eor bufv3,tmp3 sub v00,bufv0 ; v0 -= bufv sbc v01,bufv1 sbc v02,bufv2 sbc v03,bufv3 sbiw zh:zl,7 ; reset key pointer ; sum-=delta ldi tmp0,$b9 ; tmp = delta ldi tmp1,$79 ldi tmp2,$37 ldi tmp3,$9e sub sum0,tmp0 ; sum += tmp sbc sum1,tmp1 sbc sum2,tmp2 sbc sum3,tmp3 ret ; ======================================================================== ; encryption ; ======================================================================== encrypt: movw YH:YL, XH:XL movw ZH:ZL, XH:XL adiw ZH:ZL,PTEXT_NUM_BYTE ld v00,y+ ; load v0,v1 from RAM ld v01,y+ ld v02,y+ ld v03,y+ ld v10,y+ ld v11,y+ ld v12,y+ ld v13,y+ ldi tmp0,$0 ; sum = 0 mov sum0,tmp0 mov sum1,tmp0 mov sum2,tmp0 mov sum3,tmp0 ldi loop1,32 ; round loop encrypt_loop: rcall encround dec loop1 brne encrypt_loop st -y,v13 ; store v0,v1 to RAM st -y,v12 st -y,v11 st -y,v10 st -y,v03 st -y,v02 st -y,v01 st -y,v00 ret ; ======================================================================== ; decryption ; ======================================================================== decrypt: movw YH:YL, XH:XL movw ZH:ZL, XH:XL adiw ZH:ZL,PTEXT_NUM_BYTE ld v00,y+ ; load v0,v1 from RAM ld v01,y+ ld v02,y+ ld v03,y+ ld v10,y+ ld v11,y+ ld v12,y+ ld v13,y+ ldi tmp0,$20 ; sum = 0xc6ef3720 ldi tmp1,$37 ldi tmp2,$ef ldi tmp3,$c6 mov sum0,tmp0 mov sum1,tmp1 mov sum2,tmp2 mov sum3,tmp3 ldi loop1,32 ; round loop decrypt_loop: rcall decround dec loop1 brne decrypt_loop st -y,v13 ; store v0,v1 to RAM st -y,v12 st -y,v11 st -y,v10 st -y,v03 st -y,v02 st -y,v01 st -y,v00 ret ret