; ; Copyright © S. Kerckhof, 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: HIGHT encryption/descryption. ; Version 1 - June 2011. ; ; ; ---------------------------------------------------- ; | User interface: | ; |----------------------------------------------------| ; |(1) Load plaintext/key in SRAM at the address | ; | pointed by X register (r27:r26): | ; | -> The 8 first bytes are the plaintext, | ; | -> The 16 last bytes are the key. | ; |----------------------------------------------------| ; |(2) Call the encrypt or decrypt routine. | ; |----------------------------------------------------| ; |(3) After the HIGHT call, the plaintext is over- | ; | loaded by its corresponding ciphertext in SRAM | ; | the key is in its initial state again. | ; | Note: The 8 bytes following the last key byte | ; | are also used by HIGHT for intermediate | ; | rounds output values. | ; ---------------------------------------------------- ; ; ; Constants ; .EQU PTEXT_NUM_BYTE = 8 .EQU CTEXT_NUM_BYTE = 8 .EQU KEY_NUM_BYTE = 16 .EQU ADD_MEM_NUM_BYTE = 8 ;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 ; .def x0 = r0 .def x1 = r1 .def mk = r2 .def enc = r3 .def delta = r16 .def round = r17 .def i = r18 .def j = r19 .def k = r20 .def temp = r21 .def temp2 = r22 .def count = r23 ; Constants use by F_aux F_shift: .db 1, 1, 5 .db 3, 1, 2 ; ; Constant generation ; Linear Feedback Shift Register with polynomial x^7+x^3+1 ; d(7) = d(3) xor d(0) ; d = lsr d ; cstg_enc: ldi temp2, 1 sbrc delta, 3 ;if d(3) = 0, new input bit = d(0) else = d(0) xor d(3) eor delta, temp2 lsr delta brbc 0, noupd ;if carry = 1, d(6) must be updated with 1 ori delta, $40 noupd: ret ; ; Constant generation ; Linear Feedback Shift Register with polynomial x^7+x^3+1 ; d = lsl d ; d(0) = d(3) xor d(7) ; cstg_dec: ldi temp2, $80 lsl delta sbrc delta, 3 ;if d(3) = 0, new input bit = d(0) else = d(0) xor d(3) eor delta, temp2 inc temp2 sbrc delta, 7 ;if d(7) = 1 => d(0) = 1 and clear d(7) eor delta, temp2 ret ; ; Subkey generation ; Generates 8 subkeys at a time and stores them in SRAM from position (XH:XL+24) ; Reading MK_j-imod8 in SRAM corresponds to rotate left (for encryption,right ; for decryption) the MK values in SRAM and read from MK0 to MK7 (MK7 to MK0) ; Input : ; XH:XL points on msb byte of data (X7) ; YH:YL points on msb byte of master key (MK15) ; SKey: ldi i, 8 adiw XH:XL, 24 ;X now points on SK7 sbrs round, 1 ;depending on the round, subkeys are generated with master key bytes MK0 to MK7 or key bytes MK8 to MK15 adiw YH:YL, 8 ;Y points on MK15 if round(1)=1, MK7 otherwise ld temp, y ;temp=MK15 or MK7 adiw YH:YL, 7 ;Y now points on MK8 or MK0 if T=1 ld mk, y ;for decryption rotation must begin at lsb key byte and then go on from msb sbrs enc, 0 sbiw YH:YL, 8 ;points on msb key byte address - 1 for decryption brtc SKDec1stLoop adiw XH:XL, 7 ;X points on SK0 if T=1 SKLoop: ld mk, y st y, temp sbrc enc, 0 rcall cstg_enc sbrs enc, 0 SKDec1stLoop: rcall cstg_dec mov temp, mk add mk, delta st x, mk dec i brbs 1, SKLoopOut sbiw YH:YL, 1 ;Left roation of key when Encryption sbiw XH:XL, 1 brts SKLoop adiw YH:YL, 2 ;Right rotation of key when Decryption adiw XH:XL, 2 rjmp SKLoop SKLoopOut: brts SKRet ;Performs one more store when decrypt adiw YH:YL, 1 st y, temp ;Stores MK lsb byte in msb position sbiw YH:YL, 7 sbiw XH:XL, 7 SKRet: sbrs round, 1 sbiw YH:YL, 8 sbiw XH:XL, 24 ret ; ;Initial Transformation ; Plaintext is transformed using 4 whitening-key bytes (WKi) ; Output of initial transformation is writen in SRAM. ; EncInit: adiw YH:YL, 4 ;Y points on first whitening key + 1 (WK0 = MK12) adiw XH:XL, 8 ;X points on first plaintext byte + 1 ldi i,4 EInitLoop: ld x0, -x ;Even bytes (X0,X2,X4 or X6) are consecutively stored in x0 ld mk, -y ;Key bytes are stored in mk sbrc i,0 ;an addition is performed when i is even, a xor otherwise rjmp EILoopOdd EILoopEven: sbrc enc, 0 add x0, mk sbrs enc, 0 sub x0, mk rjmp EILoopEnd EILoopOdd: eor x0, mk EILoopEnd: st x, x0 sbiw XH:XL, 1 dec i brbc 1, EInitLoop ret ; ;RoundFunction ; Intermediate text is transformed and written back in SRAM. ; Rotation of bytes at each round has been removed for more genericity ; Therefore, the position of the first byte needed for computation ; change for each round. ; Input: ; round contains actual round number ; enc = 1 if encryption, 0 if decryption ; XH:XL points on Xi_7 (msb byte of intermediate text) ; YH:YL points on MK15 (msb byte of master key) ; RoundFunc: ldi count, 7 add count, round andi count, $7 ;first data to read is in position SRAM_START+(6+enc+round)mod8 inc count ;add one to count because of pre-decrementation clr temp add XL, count adc XH, temp adiw YL:YH, 20 sbrs round, 0 adiw YH:YL, 4 ldi i, 4 RoundLoop: ld x0, -x rcall UpdCnt ld x1, -x ld mk, -y clr temp sbrs i,0 ;F_0 must be performed when i is odd and F_1 otherwise ldi temp, 1 rcall F_aux sbrc i,0 ;Functions on x and mk depends on i value. rjmp RLoopOdd RLoopEven: eor x0, mk sbrc enc, 0 add x1, x0 ;Function in case of encryption sbrs enc, 0 sub x1, x0 ;Function in case of decryption rjmp RLoopEnd RLoopOdd: add x0, mk eor x1, x0 RLoopEnd: st x, x1 rcall UpdCnt dec i brbc 1, RoundLoop clr temp sub XL, count sbc XH, temp sbiw YH:YL, 16 sbrs round, 0 sbiw YH:YL, 4 ret UpdCnt: ; Modulo 8 counter dec count brbc 1, UpdCntEnd ldi count, 8 adiw XH:XL, 8 UpdCntEnd: ret ; ; Auxilairy Functions ; F0(X) = X<<<1 xor X<<<2 xor X<<<7 ; F1(X) = X<<<3 xor X<<<4 xor X<<<6 ; Register temp must contain 0 for F0, 1 for F1 ; Register x0 contains the X variable ; F_aux: ldi ZH, high(F_shift<<1) ldi ZL, low(F_shift<<1) clr temp2 lsl temp lsl temp add ZL, temp adc ZH, temp2 ;Z now points on the first rotation to perform clr temp ldi j,3 ;3 different shift operation F_loop_j: lpm k, z+ F_loop_k: lsl x0 adc x0,temp2 ;1 bit Rotation dec k brbc 1, F_loop_k eor temp,x0 dec j brbc 1, F_loop_j mov x0, temp ret ; ;Encryption Final Transformation ; Text is transformed using 4 whitening-key bytes (WKi) ; Input: ; XH:XL points on Xi_7 (msb byte of intermediate text) ; YH:YL points on MK15 (msb byte of master key) ; EncFinal: adiw YH:YL, 12 ;Y points on MK3 and X points on X31_7 ldi i, 4 EFinalLoop : ld x0, x st x+, x1 ld x1, x ld mk, y+ sbrs i,0 eor x0, mk ;XOR when i is even (x0 = X31_7 or X31_3) sbrc i, 0 add x0, mk ;Add when i is odd (x0 = X31_5 or X31_1) EFLoopEnd: st x+, x0 dec i brbc 1, EFinalLoop sbiw XH:XL, 8 st x, x1 sbiw YH:YL, 16 ret ; ;Decryption Initial Transformation ; Text is transformed using 4 whitening-key bytes (WKi) ; Input: ; XH:XL points on Xi_7 (msb byte of intermediate text) ; YH:YL points on MK15 (msb byte of master key) ; DecInit: adiw YH:YL, 16 ld x1, x adiw XH:XL, 8 ldi i, 4 DInitLoop : ld x0, -x st x, x1 ld x1, -x ld mk, -y sbrs i,0 sub x0, mk ;Sub when i is even (x0 = C0 or C4) sbrc i, 0 eor x0, mk ;XOR when i is odd (x0 = C2 or C6) DILoopEnd: st x, x0 dec i brbc 1, DinitLoop sbiw YH:YL, 12 ret ; ; HIGHT encryption routine ; encrypt: bset 6 bld enc, 0 ;bit 0 of enc is set is encryption cleared otherwise ldi delta, $35 ;load d127 ldi round, 0 movw YH:YL, XH:XL ;Y points on first ptext byte adiw YH:YL, 8 ;Y points on first key byte rcall EncInit enc_loop: sbrs round, 0 ;key schedule is performed every 2 rounds rcall SKey rcall RoundFunc inc round cpi round, 32 brne enc_loop rcall EncFinal ret ; ; HIGHT decryption routine ; decrypt: bclr 6 bld enc, 0 ;bit 0 of enc is set is encryption cleared otherwise ldi delta, $6D ;load d1 ldi round, 31 movw YH:YL, XH:XL ;Y points on first ptext byte adiw YH:YL, 8 ;Y points on first key byte rcall DecInit dec_loop: sbrc round, 0 rcall SKey rcall RoundFunc dec round brbc 2, dec_loop rcall EncInit ret