| CODE |
;*************************************************************************** ;* A P P L I C A T I O N N O T E F O R T H E A V R F A M I L Y ;* ;* Number : ;* File Name :"des.asm" ;* Title :Data Encryption Standard algorithm ;* Date : ;* Version :1.0 ;* Support telephone :+33 1 49 75 17 22 (Guy Lecurieux Lafayette) ;* Support fax :+33 1 49 75 17 30 (ATMEL France) ;* Support email :glafayette@atmel.com ;* Target MCU :AT90S ;* ;* DESCRIPTION ;* This Application note realise the encryption/decryption algorithm for ;* standard 8 bytes DES. ;* ;*************************************************************************** .include "c:\outils\micro\avr\appnotes\8515def.inc" ;***** CONSTANTES DEFINITIONS ********************************************** .EQU ENCODE=0 .EQU DECODE=1 ;***** VARIABLES DEFINITIONS *********************************************** ; r0 is reserved for lpm instruction .def byte1 =r1;byte[1:8] .def byte2 =r2;data to be processed .def byte3 =r3; .def byte4 =r4; .def byte5 =r5; .def byte6 =r6; .def byte7 =r7; .def byte8 =r8; .def key1 =r9;Key[1:8] .def key2 =r10;secret key .def key3 =r11; .def key4 =r12; .def key5 =r13; .def key6 =r14; .def key7 =r15; .def key8 =r16; .def temp1 =r17; local variables .def temp2 =r18; .def temp3 =r19; .def temp4 =r20; .def temp5 =r21; .def temp6 =r22; .def temp7 =r23; .def temp8 =r24; .def temp9 =r25; .def temp10 =r26; .def temp11 =r27; .def mode =r28; encode or decode .def i =r29; loop counter for the 16 loops ;************* MACROS ******************************************************* ;*************************************************************************** ;* ;* MAcro name : BITMOVE ;* ;* This macro load one bit from a certain position in a source byte to a ;* certain position in a destination byte. ;* ;* use: bitmove @0,@1,@2,@3 ;* Parameters: @0 : destination byte ;* @1 : position of the destination bit ;* @2 : source byte ;* @3 : position of the source bit ;*************************************************************************** .MACRO BITMOVE; Move bit from source byte (@2), position (@3) ; to byte (@0), position (@1). bst @2,@3; Store bit position @1 into T flag bld @0,@1; Store T flag content into bit position @3 .ENDMACRO ;*********************** EEPROM DATA *************************************** .ESEG ;*********************** CODE ********************************************** .CSEG rjmp RESET;Reset Handler ;*************************************************************************** ;* ;* FONCTION name : DES ;* ;* This function realise encryption (mode =ENCODE) or a decryption (mode=DECODE) ;* of a 64 bytes with a 56 bit key stored in EEPROM. ;* ;* Use: rcall DES ;* Input: mode, byte[1:8],key[1:8] ;* Output: byte[1:8] ;* Size: 1956 bytes ;* Time: 7923 cycles for encoding + 2(return) ;* 7882 cycles for decoding + 2(return) ;*************************************************************************** DES: ;*************************************************************************** ;* ;* FONCTION name : IP ;* ;* This macro realise the initial permutation. The 64 bits of the temp block ;* are permuted following the Table below. ;* L= byte1,..,byte4 ;* R= byte5,..,byte8 ;* --------------------------- --------------------------- ;* | 7 6 5 4 3 2 1 0 | | 7 6 5 4 3 2 1 0 | ;* ------------------------------------ ------------------------------------ ;* | temp1 | 58 50 42 34 26 18 10 2 | | byte1 | 1 2 3 4 5 6 7 8 | ;* | temp2 | 60 52 44 36 28 20 12 4 | | byte2 | 9 10 11 12 13 14 15 16 | ;* | temp3 | 62 54 46 38 30 22 14 6 | | byte3 | 17 18 19 20 21 22 23 24 | ;* | temp4 | 64 56 48 40 32 24 16 8 | | byte4 | 25 26 27 28 29 30 31 32 | ;* | temp5 | 57 49 41 33 25 17 9 1 | | byte5 | 33 34 35 36 37 38 39 40 | ;* | temp6 | 59 51 43 35 27 19 11 3 | | byte6 | 41 42 43 44 45 46 47 48 | ;* | temp7 | 61 53 45 37 29 21 13 5 | | byte7 | 49 50 51 52 53 54 55 56 | ;* | temp8 | 63 55 47 39 31 23 15 7 | | byte8 | 57 58 59 60 61 62 63 64 | ;* ------------------------------------ ------------------------------------ ;* ;* Use: IP ;* Input: byte[1:8] ;* Output: byte[1:8] ;* Size: 272 bytes ;* Time: 136 cycles ;* ;*************************************************************************** IP: bitmove temp1,7,byte8,6; Rebuild temp1 bitmove temp1,6,byte7,6; bitmove temp1,5,byte6,6; bitmove temp1,4,byte5,6; bitmove temp1,3,byte4,6; bitmove temp1,2,byte3,6; bitmove temp1,1,byte2,6; bitmove temp1,0,byte1,6; bitmove temp2,7,byte8,4; Rebuild temp2 bitmove temp2,6,byte7,4; bitmove temp2,5,byte6,4; bitmove temp2,4,byte5,4; bitmove temp2,3,byte4,4; bitmove temp2,2,byte3,4; bitmove temp2,1,byte2,4; bitmove temp2,0,byte1,4; bitmove temp3,7,byte8,2; Rebuild temp3 bitmove temp3,6,byte7,2; bitmove temp3,5,byte6,2; bitmove temp3,4,byte5,2; bitmove temp3,3,byte4,2; bitmove temp3,2,byte3,2; bitmove temp3,1,byte2,2; bitmove temp3,0,byte1,2; bitmove temp4,7,byte8,0; Rebuild temp4 bitmove temp4,6,byte7,0; bitmove temp4,5,byte6,0; bitmove temp4,4,byte5,0; bitmove temp4,3,byte4,0; bitmove temp4,2,byte3,0; bitmove temp4,1,byte2,0; bitmove temp4,0,byte1,0; bitmove temp5,7,byte8,7; Rebuild temp5 bitmove temp5,6,byte7,7; bitmove temp5,5,byte6,7; bitmove temp5,4,byte5,7; bitmove temp5,3,byte4,7; bitmove temp5,2,byte3,7; bitmove temp5,1,byte2,7; bitmove temp5,0,byte1,7; bitmove temp6,7,byte8,5; Rebuild temp6 bitmove temp6,6,byte7,5; bitmove temp6,5,byte6,5; bitmove temp6,4,byte5,5; bitmove temp6,3,byte4,5; bitmove temp6,2,byte3,5; bitmove temp6,1,byte2,5; bitmove temp6,0,byte1,5; bitmove temp7,7,byte8,3; Rebuild temp7 bitmove temp7,6,byte7,3; bitmove temp7,5,byte6,3; bitmove temp7,4,byte5,3; bitmove temp7,3,byte4,3; bitmove temp7,2,byte3,3; bitmove temp7,1,byte2,3; bitmove temp7,0,byte1,3; bitmove temp8,7,byte8,1; Rebuild temp8 bitmove temp8,6,byte7,1; bitmove temp8,5,byte6,1; bitmove temp8,4,byte5,1; bitmove temp8,3,byte4,1; bitmove temp8,2,byte3,1; bitmove temp8,1,byte2,1; bitmove temp8,0,byte1,1; mov byte1,temp1; mov byte2,temp2 mov byte3,temp3 mov byte4,temp4 mov byte5,temp5 mov byte6,temp6 mov byte7,temp7 mov byte8,temp8 ;*************************************************************************** ;* ;* FONCTION name : PC-1 ;* ;* This function realise the permuted choice 1. The 48 bits of the temp ;* block are permuted following the Table below. ;* ;* --------------------------- --------------------------- ;* | 7 6 5 4 3 2 1 0 | | 7 6 5 4 3 2 1 0 | ;* ------------------------------------ ------------------------------------ ;* | temp1 | 57 49 41 33 25 17 9 1 | | key1 | 1 2 3 4 5 6 7 8 | ;* | temp2 | 58 50 42 34 26 18 10 2 | | key2 | 9 10 11 12 13 14 15 16 | ;* | temp3 | 59 51 43 35 27 19 11 3 | | key3 | 17 18 19 20 21 22 23 24 | ;* | temp4 | 60 52 44 36 63 55 47 39 | | key4 | 25 26 27 28 29 30 31 32 | ;* | temp5 | 31 23 15 7 62 54 46 38 | | key5 | 33 34 35 36 37 38 39 40 | ;* | temp6 | 30 22 14 6 61 53 45 37 | | key6 | 41 42 43 44 45 46 47 48 | ;* | temp7 | 29 21 13 5 28 20 12 4 | | key7 | 49 50 51 52 53 54 55 56 | ;* | | | key8 | 57 58 59 60 61 62 63 64 | ;* ------------------------------------ ------------------------------------ ;* ;* Use: PC_1 ;* Input: key[1:8] ;* Output:key[1:7] ;* Size: 238 bytes ;* Time: 119 cycles ;* ;*************************************************************************** PC_1: bitmove temp1,7,key8,7; Rebuild temp1 bitmove temp1,6,key7,7; bitmove temp1,5,key6,7; bitmove temp1,4,key5,7; bitmove temp1,3,key4,7; bitmove temp1,2,key3,7; bitmove temp1,1,key2,7; bitmove temp1,0,key1,7; bitmove temp2,7,key8,6; Rebuild temp2 bitmove temp2,6,key7,6; bitmove temp2,5,key6,6; bitmove temp2,4,key5,6; bitmove temp2,3,key4,6; bitmove temp2,2,key3,6; bitmove temp2,1,key2,6; bitmove temp2,0,key1,6; bitmove temp3,7,key8,5;Rebuild temp3 bitmove temp3,6,key7,5; bitmove temp3,5,key6,5; bitmove temp3,4,key5,5; bitmove temp3,3,key4,5; bitmove temp3,2,key3,5; bitmove temp3,1,key2,5; bitmove temp3,0,key1,5; bitmove temp4,7,key8,4;Rebuild temp4 bitmove temp4,6,key7,4; bitmove temp4,5,key6,4; bitmove temp4,4,key5,4; bitmove temp4,3,key8,1; bitmove temp4,2,key7,1; bitmove temp4,1,key6,1; bitmove temp4,0,key5,1; bitmove temp5,7,key4,1;Rebuild temp5 bitmove temp5,6,key3,1; bitmove temp5,5,key2,1; bitmove temp5,4,key1,1; bitmove temp5,3,key8,2; bitmove temp5,2,key7,2; bitmove temp5,1,key6,2; bitmove temp5,0,key5,2; bitmove temp6,7,key4,2;Rebuild temp6 bitmove temp6,6,key3,2; bitmove temp6,5,key2,2; bitmove temp6,4,key1,2; bitmove temp6,3,key8,3; bitmove temp6,2,key7,3; bitmove temp6,1,key6,3; bitmove temp6,0,key5,3; bitmove temp7,7,key4,3; Rebuild temp7 bitmove temp7,6,key3,3; bitmove temp7,5,key2,3; bitmove temp7,4,key1,3; bitmove temp7,3,key4,4; bitmove temp7,2,key3,4; bitmove temp7,1,key2,4; bitmove temp7,0,key1,4; mov key1,temp1 ; remove key from temporaly variables mov key2,temp2 mov key3,temp3 mov key4,temp4 mov key5,temp5 mov key6,temp6 mov key7,temp7 ldi i,16; loop 16 times DES_LOOP: ;*************************************************************************** ;* ;* FONCTION name : SHIFT_KEY ;* ;* This function shift left/right the two 28 bit word . The 56 bits are splited in two ;* 28 bits word C and D. Then a left/right shift is done on each word ;* left if it is encoding ;* right if it is decoding ;* ;* | key1 | 1 2 3 4 5 6 7 8 | ;* | key2 | 9 10 11 12 13 14 15 16 | : C ;* | key3 | 17 18 19 20 21 22 23 24 | ;* | key4 | 25 26 27 28 29 30 31 32 | ;* | key5 | 33 34 35 36 37 38 39 40 | ;* | key6 D: | 41 42 43 44 45 46 47 48 | ;* | key7 | 49 50 51 52 53 54 55 56 | ;* | ;* ------------------------------------ ------------------------------------ ;* Use: SHIFT_KEY ;* Input: key[1:7] ;* Output:key[1:7] ;* Size: 100 bytes + 16 bytes for number of shift ;* Time: cycles ;* ;*************************************************************************** SHIFT_KEY: clr temp11 cpi mode,ENCODE brne REVERSE_TAB ;*** in case of encode, address= TAB_SHIFT-i+1+15 ldi ZL, low((2*TAB_SHIFT+1+15)); **** to use lpm instruction ldi ZH, high((2*TAB_SHIFT+1+15)); address should be multiplied by 2 sub ZL,i sbc ZH,temp11; sub with temp11=0 for the carry rjmp GET_NBSHIFT REVERSE_TAB:;*** in case of decode, address= TAB_SHIFT+i cpi i,16; if first loop and decode breq PC_2; then no need for shifting to generate the key clr ZH; else shift mov ZL,i subi ZL,low(-(2*TAB_SHIFT)) sbci ZH,high(-(2*TAB_SHIFT)) GET_NBSHIFT: lpm; get number of shift into r0 LOOP_SHIFT: mov temp9, key4; save midle byte cpi mode,ENCODE; if encoding then C and D are shifted left brne SHIFT_RIGHT; else shifted right SHIFT_LEFT: lsl key4; shift left C rol key3; rol key2; bst key1,7; save bit 1 rol key1; bld key4,4; bit 1 goes into position 28 lsl key7; shift left D rol key6 rol key5 rol temp9 bitmove key7,0,temp9,4; bit 29 goes into position 56 rjmp BUILD_MIDDLE SHIFT_RIGHT: lsr key1; shift right C ror key2 ror key3 ror key4 bitmove key1,7,key4,3; bit 28 goes into position 1 lsr temp9; shift right D ror key5 ror key6 bst key7,0; save bit 56 ror key7 bld temp9,3; bit 56 goes into position 29 BUILD_MIDDLE: andi temp9,$0F; mask last C nibble mov temp10,key4; *** immediate not possible on key4 andi temp10, $F0; mask first D nibble or temp10,temp9; recompose the middle byte mov key4,temp10 dec r0 ; decrement number of shift brne LOOP_SHIFT; if <> 0 then shift again ;*************************************************************************** ;* ;* FONCTION name : PC-2 ;* ;* This function realise the permuted choice 2. The 48 bits of the temp ;* block are permuted following the Table below. ;* --------------------------- --------------------------- ;* | 7 6 5 4 3 2 1 0 | | 7 6 5 4 3 2 1 0 | ;* ------------------------------------ ------------------------------------ ;* | temp1 | 14 17 11 24 1 5 3 28 | | key1 | 1 2 3 4 5 6 7 8 | ;* | temp2 | 15 6 21 10 23 19 12 4 | | key2 | 9 10 11 12 13 14 15 16 | ;* | temp3 | 26 8 16 7 27 20 13 2 | | key3 | 17 18 19 20 21 22 23 24 | ;* | temp4 | 41 52 31 37 47 55 30 40 | | key4 | 25 26 27 28 29 30 31 32 | ;* | temp5 | 51 45 33 48 44 49 39 56 | | key5 | 33 34 35 36 37 38 39 40 | ;* | temp6 | 34 53 46 42 50 36 29 32 | | key6 | 41 42 43 44 45 46 47 48 | ;* | key7 | 49 50 51 52 53 54 55 56 | ;* ------------------------------------ ------------------------------------ ;* ;* Use: PC_2 ;* Input: key[1:7] ;* Output:temp[1:6] ;* Size: 192 bytes ;* Time: 96 cycles ;* ;*************************************************************************** PC_2: bitmove temp1,7,key2,2; Rebuild temp1 bitmove temp1,6,key3,7; bitmove temp1,5,key2,5; bitmove temp1,4,key3,0; bitmove temp1,3,key1,7; bitmove temp1,2,key1,3; bitmove temp1,1,key1,5; bitmove temp1,0,key4,4; bitmove temp2,7,key2,1; Rebuild temp2 bitmove temp2,6,key1,2; bitmove temp2,5,key3,3; bitmove temp2,4,key2,6; bitmove temp2,3,key3,1; bitmove temp2,2,key3,5; bitmove temp2,1,key2,4; bitmove temp2,0,key1,4; bitmove temp3,7,key4,6; Rebuild temp3 bitmove temp3,6,key1,0; bitmove temp3,5,key2,0; bitmove temp3,4,key1,1; bitmove temp3,3,key4,5; bitmove temp3,2,key3,4; bitmove temp3,1,key2,3; bitmove temp3,0,key1,6; bitmove temp4,7,key6,7; Rebuild temp4 bitmove temp4,6,key7,4; bitmove temp4,5,key4,1; bitmove temp4,4,key5,3; bitmove temp4,3,key6,1; bitmove temp4,2,key7,1; bitmove temp4,1,key4,2; bitmove temp4,0,key5,0; bitmove temp5,7,key7,5; Rebuild temp5 bitmove temp5,6,key6,3; bitmove temp5,5,key5,7; bitmove temp5,4,key6,0; bitmove temp5,3,key6,4; bitmove temp5,2,key7,7; bitmove temp5,1,key5,1; bitmove temp5,0,key7,0; bitmove temp6,7,key5,6; Rebuild temp6 bitmove temp6,6,key7,3; bitmove temp6,5,key6,2; bitmove temp6,4,key6,6; bitmove temp6,3,key7,6; bitmove temp6,2,key5,4; bitmove temp6,1,key4,3; bitmove temp6,0,key4,0; ;*************************************************************************** ;* ;* FONCTION name : E_XOR ;* ;* This function realise the expansion and XOR. The 32 bits of the R input ;* block are expanded to 48 bits. ;* tempi=E(R) xor Keyi ;* --------------------------- --------------------------- ;* | 7 6 5 4 3 2 1 0 | | 7 6 5 4 3 2 1 0 | ;* | temp1 | 32 1 2 3 4 5 4 5 | | byte5 | 1 2 3 4 5 6 7 8 | ;* | temp2 | 6 7 8 9 8 9 10 11 | | byte6 | 9 10 11 12 13 14 15 16 | ;* | temp3 | 12 13 12 13 14 15 16 17 | | byte7 | 17 18 19 20 21 22 23 24 | ;* | temp4 | 16 17 18 19 20 21 20 21 | | byte8 | 25 26 27 28 29 30 31 32 | ;* | temp5 | 22 23 24 25 24 25 26 27 | ;* | temp6 | 28 29 28 29 30 31 32 1 | ;* ------------------------------------ ------------------------------------ ;* Use: call E_XOR ;* Input: temp[1:6],byte[5:8] ;* Output:temp[1:6] ;* Size: 204 bytes ;* Time: 102 cycles ;* ;*************************************************************************** E_XOR: bitmove temp7,7,byte8,0; Rebuild temp1 bitmove temp7,6,byte5,7; bitmove temp7,5,byte5,6; bitmove temp7,4,byte5,5; bitmove temp7,3,byte5,4; bitmove temp7,2,byte5,3; bitmove temp7,1,byte5,4; bitmove temp7,0,byte5,3; eor temp1,temp7; bitmove temp7,7,byte5,2; Rebuild temp2 bitmove temp7,6,byte5,1; bitmove temp7,5,byte5,0; bitmove temp7,4,byte6,7; bitmove temp7,3,byte5,0; bitmove temp7,2,byte6,7; bitmove temp7,1,byte6,6; bitmove temp7,0,byte6,5; eor temp2,temp7 bitmove temp7,7,byte6,4; Rebuild temp3 bitmove temp7,6,byte6,3; bitmove temp7,5,byte6,4; bitmove temp7,4,byte6,3; bitmove temp7,3,byte6,2; bitmove temp7,2,byte6,1; bitmove temp7,1,byte6,0; bitmove temp7,0,byte7,7; eor temp3,temp7 bitmove temp7,7,byte6,0; Rebuild temp4 bitmove temp7,6,byte7,7; bitmove temp7,5,byte7,6; bitmove temp7,4,byte7,5; bitmove temp7,3,byte7,4; bitmove temp7,2,byte7,3; bitmove temp7,1,byte7,4; bitmove temp7,0,byte7,3; eor temp4,temp7 bitmove temp7,7,byte7,2; Rebuild temp5 bitmove temp7,6,byte7,1; bitmove temp7,5,byte7,0; bitmove temp7,4,byte8,7; bitmove temp7,3,byte7,0; bitmove temp7,2,byte8,7; bitmove temp7,1,byte8,6; bitmove temp7,0,byte8,5; eor temp5,temp7 bitmove temp7,7,byte8,4; Rebuild temp6 bitmove temp7,6,byte8,3; bitmove temp7,5,byte8,4; bitmove temp7,4,byte8,3; bitmove temp7,3,byte8,2; bitmove temp7,2,byte8,1; bitmove temp7,1,byte8,0; bitmove temp7,0,byte5,7; eor temp6,temp7 ;*************************************************************************** ;* ;* FONCTION name : S_BOX ;* ;* This function take the 48 bits ( E(R) xor Key) and gives an 32 bit output ;* thru 8 tables (TAB_S1,...,TAB_S8). ;* The 48 bits inputs are splited into 8 sets of consecutives 6 bits ;* temp1: | 6 | 2| ;* temp2: | 4 | 4 | ;* temp3: |2 | 6 | ;* temp4: | 6 | 2| ;* temp5: | 4 | 4 | ;* temp6: |2 | 6 | ;* ;* Use: S_BOX ;* Input:temp[1:6] ;* Output:temp[8:11] ;* Size: 244 bytes for code + 256 bytes for the table ;* Time: 138 cycles ;* ;*************************************************************************** S_BOX: clr temp8; the 32 bits will be stored clr temp9; into temp8,..,temp11 clr temp10 clr temp11 ;**** TAB_S1 mov temp7,temp1; b5 b4 b3 b2 b1 b0 x x lsr temp7; 0 b5 b4 b3 b2 b1 b0 x lsr temp7; 0 0 b5 b4 b3 b2 b1 b0 lsr temp7; 0 0 0 b5 b4 b3 b2 b1 mov ZL,temp7 clr ZH subi ZL,low(-2*TAB_S1); sbci ZH,high(-2*TAB_S1) lpm; get 2 nibbles into r0 sbrs temp1,2; choose right nibble depends on b0 swap r0 mov temp7,r0 andi temp7,$F0 or temp8,temp7 ;**** TAB_S2 mov temp7,temp2;b3 b2 b1 b0 x x x x lsr temp1;0 x x x x x x b5 ,c=b4 ror temp7;b4 b3 b2 b1 b0 x x x lsr temp1;0 0 x x x x x x ,c=b5 ror temp7;b5 b4 b3 b2 b1 b0 x x lsr temp7;0 b5 b4 b3 b2 b1 b0 x lsr temp7;0 0 b5 b4 b3 b2 b1 b0 lsr temp7;0 0 0 b5 b4 b3 b2 b1 mov ZL,temp7 clr ZH subi ZL,low(-2*TAB_S2); sbci ZH,high(-2*TAB_S2) lpm; get 2 nibbles into r0 sbrc temp2,4; choose right nibble depends on b0 swap r0 mov temp7,r0 andi temp7,$0F or temp8,temp7 ;**** TAB_S3 mov temp7,temp3;b1 b0 x x x x x x lsl temp7;b0 x x x x x x 0 ,c=b1 rol temp2; x x x b5 b4 b3 b2 b1 andi temp2,0b00011111; 0 0 0 b5 b4 b3 b2 b1 mov ZL,temp2 clr ZH subi ZL,low(-2*TAB_S3); sbci ZH,high(-2*TAB_S3) lpm; get 2 nibbles into r0 sbrs temp3,6; choose right nibble depends on b0 swap r0 mov temp7,r0 andi temp7,$F0 or temp9,temp7 ;**** TAB_S4 mov temp7,temp3;x x b5 b4 b3 b2 b1 b0 lsr temp7;0 x x b5 b4 b3 b2 b1 andi temp7,0b00011111;0 0 0 b5 b4 b3 b2 b1 mov ZL,temp7 clr ZH subi ZL,low(-2*TAB_S4); sbci ZH,high(-2*TAB_S4) lpm; get 2 nibbles into r0 sbrc temp3,0; choose right nibble depends on b0 swap r0 mov temp7,r0 andi temp7,$0F or temp9,temp7 ;**** TAB_S5 mov temp7,temp4; b5 b4 b3 b2 b1 b0 x x lsr temp7; 0 b5 b4 b3 b2 b1 b0 x lsr temp7; 0 0 b5 b4 b3 b2 b1 b0 lsr temp7; 0 0 0 b5 b4 b3 b2 b1 mov ZL,temp7 clr ZH subi ZL,low(-2*TAB_S5); sbci ZH,high(-2*TAB_S5) lpm; get 2 nibbles into r0 sbrs temp4,2; choose right nibble depends on b0 swap r0 mov temp7,r0 andi temp7,$F0 or temp10,temp7 ;**** TAB_S6 mov temp7,temp5;b3 b2 b1 b0 x x x x lsr temp4;0 x x x x x x b5 ,c=b4 ror temp7;b4 b3 b2 b1 b0 x x x lsr temp4;0 0 x x x x x x ,c=b5 ror temp7;b5 b4 b3 b2 b1 b0 x x lsr temp7;0 b5 b4 b3 b2 b1 b0 x lsr temp7;0 0 b5 b4 b3 b2 b1 b0 lsr temp7;0 0 0 b5 b4 b3 b2 b1 mov ZL,temp7 clr ZH subi ZL,low(-2*TAB_S6); sbci ZH,high(-2*TAB_S6) lpm; get 2 nibbles into r0 sbrc temp5,4; choose right nibble depends on b0 swap r0 mov temp7,r0 andi temp7,$0F or temp10,temp7 ;**** TAB_S7 mov temp7,temp6;b1 b0 x x x x x x lsl temp7;b0 x x x x x x 0 ,c=b1 rol temp5; x x x b5 b4 b3 b2 b1 andi temp5,0b00011111; 0 0 0 b5 b4 b3 b2 b1 mov ZL,temp5 clr ZH subi ZL,low(-2*TAB_S7); sbci ZH,high(-2*TAB_S7) lpm; get 2 nibbles into r0 sbrs temp6,6; choose right nibble depends on b0 swap r0 mov temp7,r0 andi temp7,$F0 or temp11,temp7 ;**** TAB_S8 mov temp7,temp6;x x b5 b4 b3 b2 b1 b0 lsr temp7;0 x x b5 b4 b3 b2 b1 andi temp7,0b00011111;0 0 0 b5 b4 b3 b2 b1 mov ZL,temp7 clr ZH subi ZL,low(-2*TAB_S8); sbci ZH,high(-2*TAB_S8) lpm; get 2 nibbles into r0 sbrc temp6,0; choose right nibble depends on b0 swap r0 mov temp7,r0 andi temp7,$0F or temp11,temp7 ;*************************************************************************** ;* ;* FONCTION name : P ;* ;* This function realise a permutation of 32 bit coming from the output of the ;* S_BOX ;* --------------------------- --------------------------- ;* | 7 6 5 4 3 2 1 0 | | 7 6 5 4 3 2 1 0 | ;* | temp1 | 16 7 20 21 29 12 28 17 | | temp8 | 1 2 3 4 5 6 7 8 | ;* | temp2 | 1 15 23 26 5 18 31 10 | | temp9 | 9 10 11 12 13 14 15 16 | ;* | temp3 | 2 8 24 14 32 27 3 9 | | temp10 | 17 18 19 20 21 22 23 24 | ;* | temp4 | 19 13 30 6 22 11 4 25 | | temp11 | 25 26 27 28 29 30 31 32 | ;;* ------------------------------------ ------------------------------------ ;* Use: P ;* Input: temp[8:11] ;* Output:temp[1:4] ;* Size: 152 bytes ;* Time: 76 cycles ;* ;*************************************************************************** P: bitmove temp1,7,temp9,0; Rebuild temp1 bitmove temp1,6,temp8,1; bitmove temp1,5,temp10,4; bitmove temp1,4,temp10,3; bitmove temp1,3,temp11,3; bitmove temp1,2,temp9,4; bitmove temp1,1,temp11,4; bitmove temp1,0,temp10,7; bitmove temp2,7,temp8,7; Rebuild temp2 bitmove temp2,6,temp9,1; bitmove temp2,5,temp10,1; bitmove temp2,4,temp11,6; bitmove temp2,3,temp8,3; bitmove temp2,2,temp10,6; bitmove temp2,1,temp11,1; bitmove temp2,0,temp9,6; bitmove temp3,7,temp8,6; Rebuild temp3 bitmove temp3,6,temp8,0; bitmove temp3,5,temp10,0; bitmove temp3,4,temp9,2; bitmove temp3,3,temp11,0; bitmove temp3,2,temp11,5; bitmove temp3,1,temp8,5; bitmove temp3,0,temp9,7; bitmove temp4,7,temp10,5; Rebuild temp4 bitmove temp4,6,temp9,3; bitmove temp4,5,temp11,2; bitmove temp4,4,temp8,2; bitmove temp4,3,temp10,2; bitmove temp4,2,temp9,5; bitmove temp4,1,temp8,4; bitmove temp4,0,temp11,7; eor temp1,byte1; eor temp2,byte2 eor temp3,byte3 eor temp4,byte4 mov byte1,byte5; L(i+1)=R(i) mov byte2,byte6 mov byte3,byte7 mov byte4,byte8 mov byte5,temp1; R(i+1) = L(i) xor f(R(i),K(i)) mov byte6,temp2 mov byte7,temp3 mov byte8,temp4 dec i; breq END_DES_LOOP; rjmp DES_LOOP; Loop 16 times END_DES_LOOP: mov temp5,byte1; Swap L and R mov temp6,byte2 mov temp7,byte3 mov temp8,byte4 mov temp1,byte5 mov temp2,byte6 mov temp3,byte7 mov temp4,byte8 ;*************************************************************************** ;* ;* FONCTION name : IP_1 ;* ;* This macro realise the inverse initial permutation. The 64 bits of the byte ;* block are permuted following the Table below. ;* --------------------------- --------------------------- ;* | 7 6 5 4 3 2 1 0 | | 7 6 5 4 3 2 1 0 | ;* ------------------------------------ ------------------------------------ ;* | byte1 | 40 8 48 16 56 24 64 32| | temp1 | 1 2 3 4 5 6 7 8 | ;* | byte2 | 39 7 47 15 55 23 63 31| | temp2 | 9 10 11 12 13 14 15 16 | ;* | byte3 | 38 6 46 14 54 22 62 30| | temp3 | 17 18 19 20 21 22 23 24 | ;* | byte4 | 37 5 45 13 53 21 61 29| | temp4 | 25 26 27 28 29 30 31 32 | ;* | byte5 | 36 4 44 12 52 20 60 28| | temp5 | 33 34 35 36 37 38 39 40 | ;* | byte6 | 35 3 43 11 51 19 59 27| | temp6 | 41 42 43 44 45 46 47 48 | ;* | byte7 | 34 2 42 10 50 18 58 26| | temp7 | 49 50 51 52 53 54 55 56 | ;* | byte8 | 33 1 41 9 49 17 57 25| | temp8 | 57 58 59 60 61 62 63 64 | ;* ------------------------------------ ------------------------------------ ;* ;* Use: IP_1 ;* Input: temp[1:8] ;* Output:byte[1:8] ;* Size: 256 bytes ;* Time: 128 cycles ;* ;*************************************************************************** IP_1: bitmove byte1,7,temp5,0; Rebuild byte1 bitmove byte1,6,temp1,0; bitmove byte1,5,temp6,0; bitmove byte1,4,temp2,0; bitmove byte1,3,temp7,0; bitmove byte1,2,temp3,0; bitmove byte1,1,temp8,0; bitmove byte1,0,temp4,0; bitmove byte2,7,temp5,1; Rebuild byte2 bitmove byte2,6,temp1,1; bitmove byte2,5,temp6,1; bitmove byte2,4,temp2,1; bitmove byte2,3,temp7,1; bitmove byte2,2,temp3,1; bitmove byte2,1,temp8,1; bitmove byte2,0,temp4,1; bitmove byte3,7,temp5,2; Rebuild byte3 bitmove byte3,6,temp1,2; bitmove byte3,5,temp6,2; bitmove byte3,4,temp2,2; bitmove byte3,3,temp7,2; bitmove byte3,2,temp3,2; bitmove byte3,1,temp8,2; bitmove byte3,0,temp4,2; bitmove byte4,7,temp5,3; Rebuild byte4 bitmove byte4,6,temp1,3; bitmove byte4,5,temp6,3; bitmove byte4,4,temp2,3; bitmove byte4,3,temp7,3; bitmove byte4,2,temp3,3; bitmove byte4,1,temp8,3; bitmove byte4,0,temp4,3; bitmove byte5,7,temp5,4; Rebuild byte5 bitmove byte5,6,temp1,4; bitmove byte5,5,temp6,4; bitmove byte5,4,temp2,4; bitmove byte5,3,temp7,4; bitmove byte5,2,temp3,4; bitmove byte5,1,temp8,4; bitmove byte5,0,temp4,4; bitmove byte6,7,temp5,5; Rebuild byte6 bitmove byte6,6,temp1,5; bitmove byte6,5,temp6,5; bitmove byte6,4,temp2,5; bitmove byte6,3,temp7,5; bitmove byte6,2,temp3,5; bitmove byte6,1,temp8,5; bitmove byte6,0,temp4,5; bitmove byte7,7,temp5,6; Rebuild byte7 bitmove byte7,6,temp1,6; bitmove byte7,5,temp6,6; bitmove byte7,4,temp2,6; bitmove byte7,3,temp7,6; bitmove byte7,2,temp3,6; bitmove byte7,1,temp8,6; bitmove byte7,0,temp4,6; bitmove byte8,7,temp5,7; Rebuild byte8 bitmove byte8,6,temp1,7; bitmove byte8,5,temp6,7; bitmove byte8,4,temp2,7; bitmove byte8,3,temp7,7; bitmove byte8,2,temp3,7; bitmove byte8,1,temp8,7; bitmove byte8,0,temp4,7; ret; end of DES procedure ;*** Constante table definition ;*** define number of shift to apply during Key shift TAB_SHIFT: .DB 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1 ;****** The Sbox table give 4 bits outputs with a 6 bits input. ;two nibbles are stored in one byte in the Sbox table as NIB1 NIB0. ; if the 6 input bits are b5b4b3b2b1b0, we use b5b4b3b2b1 to address the byte and b0 to select ; the correct nibble: b0=1 -> NIB1, b0=0 -> NIB0. ; the byte is stored as ( NIB1 << 4) | NIB0. TAB_S1: .DB (( 0 << 4) |14),((15 << 4) | 4),(( 7 << 4) |13),(( 4 << 4) | 1) .DB ((14 << 4) | 2),(( 2 << 4) |15),((13 << 4) |11),(( 1 << 4) | 8) .DB ((10 << 4) | 3),(( 6 << 4) |10),((12 << 4) | 6),((11 << 4) |12) .DB (( 9 << 4) | 5),(( 5 << 4) | 9),(( 3 << 4) | 0),(( 8 << 4) | 7) .DB ((15 << 4) | 4),((12 << 4) | 1),(( 8 << 4) |14),(( 2 << 4) | 8) .DB (( 4 << 4) |13),(( 9 << 4) | 6),(( 1 << 4) | 2),(( 7 << 4) |11) .DB (( 5 << 4) |15),((11 << 4) |12),(( 3 << 4) | 9),((14 << 4) | 7) .DB ((10 << 4) | 3),(( 0 << 4) |10),(( 6 << 4) | 5),((13 << 4) | 0) TAB_S2: .DB ( (3 << 4) |15),((13 << 4) | 1),(( 4 << 4) | 8),(( 7 << 4) |14) .DB ((15 << 4) | 6),(( 2 << 4) |11),(( 8 << 4) | 3),((14 << 4) | 4) .DB ((12 << 4) | 9),(( 0 << 4) | 7),(( 1 << 4) | 2),((10 << 4) |13) .DB (( 6 << 4) |12),(( 9 << 4) | 0),((11 << 4) | 5),(( 5 << 4) |10) .DB ((13 << 4) | 0),(( 8 << 4) |14),((10 << 4) | 7),(( 1 << 4) |11) .DB (( 3 << 4) |10),((15 << 4) | 4),(( 4 << 4) |13),(( 2 << 4) | 1) .DB ((11 << 4) | 5),(( 6 << 4) | 8),(( 7 << 4) |12),((12 << 4) | 6) .DB (( 0 << 4) | 9),(( 5 << 4) | 3),((14 << 4) | 2),(( 9 << 4) |15) TAB_S3: .DB ((13 << 4) |10),(( 7 << 4) | 0),(( 0 << 4) | 9),(( 9 << 4) |14) .DB (( 3 << 4) | 6),(( 4 << 4) | 3),(( 6 << 4) |15),((10 << 4) | 5) .DB (( 2 << 4) | 1),(( 8 << 4) |13),(( 5 << 4) |12),((14 << 4) | 7) .DB ((12 << 4) |11),((11 << 4) | 4),((15 << 4) | 2),(( 1 << 4) | 8) .DB (( 1 << 4) |13),((10 << 4) | 6),((13 << 4) | 4),(( 0 << 4) | 9) .DB (( 6 << 4) | 8),(( 9 << 4) |15),(( 8 << 4) | 3),(( 7 << 4) | 0) .DB (( 4 << 4) |11),((15 << 4) | 1),((14 << 4) | 2),(( 3 << 4) |12) .DB ((11 << 4) | 5),(( 5 << 4) |10),(( 2 << 4) |14),((12 << 4) | 7) TAB_S4: .DB ((13 << 4) | 7),(( 8 << 4) |13),((11 << 4) |14),(( 5 << 4) | 3) .DB (( 6 << 4) | 0),((15 << 4) | 6),(( 0 << 4) | 9),(( 3 << 4) |10) .DB (( 4 << 4) | 1),(( 7 << 4) | 2),(( 2 << 4) | 8),((12 << 4) | 5) .DB (( 1 << 4) |11),((10 << 4) |12),((14 << 4) | 4),(( 9 << 4) |15) .DB (( 3 << 4) |10),((15 << 4) | 6),(( 0 << 4) | 9),(( 6 << 4) | 0) .DB ((10 << 4) |12),(( 1 << 4) |11),((13 << 4) | 7),(( 8 << 4) |13) .DB (( 9 << 4) |15),(( 4 << 4) | 1),(( 5 << 4) | 3),((11 << 4) |14) .DB ((12 << 4) | 5),(( 7 << 4) | 2),(( 2 << 4) | 8),((14 << 4) | 4) TAB_S5: .DB ((14 << 4) | 2),((11 << 4) |12),(( 2 << 4) | 4),((12 << 4) | 1) .DB (( 4 << 4) | 7),(( 7 << 4) |10),((13 << 4) |11),(( 1 << 4) | 6) .DB (( 5 << 4) | 8),(( 0 << 4) | 5),((15 << 4) | 3),((10 << 4) |15) .DB (( 3 << 4) |13),(( 9 << 4) | 0),(( 8 << 4) |14),(( 6 << 4) | 9) .DB ((11 << 4) | 4),(( 8 << 4) | 2),((12 << 4) | 1),(( 7 << 4) |11) .DB (( 1 << 4) |10),((14 << 4) |13),(( 2 << 4) | 7),((13 << 4) | 8) .DB (( 6 << 4) |15),((15 << 4) | 9),(( 0 << 4) |12),(( 9 << 4) | 5) .DB ((10 << 4) | 6),(( 4 << 4) | 3),(( 5 << 4) | 0),(( 3 << 4) |14) TAB_S6: .DB ((10 << 4) |12),((15 << 4) | 1),(( 4 << 4) |10),(( 2 << 4) |15) .DB (( 7 << 4) | 9),((12 << 4) | 2),(( 9 << 4) | 6),(( 5 << 4) | 8) .DB (( 6 << 4) | 0),(( 1 << 4) |13),((13 << 4) | 3),((14 << 4) | 4) .DB (( 0 << 4) |14),((11 << 4) | 7),(( 3 << 4) | 5),(( 8 << 4) |11) .DB (( 4 << 4) | 9),(( 3 << 4) |14),(( 2 << 4) |15),((12 << 4) | 5) .DB (( 9 << 4) | 2),(( 5 << 4) | 8),((15 << 4) |12),((10 << 4) | 3) .DB ((11 << 4) | 7),((14 << 4) | 0),(( 1 << 4) | 4),(( 7 << 4) |10) .DB (( 6 << 4) | 1),(( 0 << 4) |13),(( 8 << 4) |11),((13 << 4) | 6) TAB_S7: .DB ((13 << 4) | 4),(( 0 << 4) |11),((11 << 4) | 2),(( 7 << 4) |14) .DB (( 4 << 4) |15),(( 9 << 4) | 0),(( 1 << 4) | 8),((10 << 4) |13) .DB ((14 << 4) | 3),(( 3 << 4) |12),(( 5 << 4) | 9),((12 << 4) | 7) .DB (( 2 << 4) | 5),((15 << 4) |10),(( 8 << 4) | 6),(( 6 << 4) | 1) .DB (( 6 << 4) | 1),((11 << 4) | 4),((13 << 4) |11),(( 8 << 4) |13) .DB (( 1 << 4) |12),(( 4 << 4) | 3),((10 << 4) | 7),(( 7 << 4) |14) .DB (( 9 << 4) |10),(( 5 << 4) |15),(( 0 << 4) | 6),((15 << 4) | 8) .DB ((14 << 4) | 0),(( 2 << 4) | 5),(( 3 << 4) | 9),((12 << 4) | 2) TAB_S8: .DB (( 1 << 4) |13),((15 << 4) | 2),((13 << 4) | 8),(( 8 << 4) | 4) .DB ((10 << 4) | 6),(( 3 << 4) |15),(( 7 << 4) |11),(( 4 << 4) | 1) .DB ((12 << 4) |10),(( 5 << 4) | 9),(( 6 << 4) | 3),((11 << 4) |14) .DB (( 0 << 4) | 5),((14 << 4) | 0),(( 9 << 4) |12),(( 2 << 4) | 7) .DB (( 2 << 4) | 7),(( 1 << 4) |11),((14 << 4) | 4),(( 7 << 4) | 1) .DB (( 4 << 4) | 9),((10 << 4) |12),(( 8 << 4) |14),((13 << 4) | 2) .DB ((15 << 4) | 0),((12 << 4) | 6),(( 9 << 4) |10),(( 0 << 4) |13) .DB (( 3 << 4) |15),(( 5 << 4) | 3),(( 6 << 4) | 5),((11 << 4) | 8) ;******** test programm ********************* RESET: ldi r16,0x0; init stack pointer out SPH,r16 ldi r16,0x60 out SPL,r16 ldi ZL,0xf1; data to be encrypted :f1,1d,59,a5,5a,37,fe,aa. mov byte8,ZL ldi ZL,0x1d mov byte7,ZL ldi ZL,0x59 mov byte6,ZL ldi ZL,0xa5 mov byte5,ZL ldi ZL,0x5a mov byte4,ZL ldi ZL,0x37 mov byte3,ZL ldi ZL,0xfe mov byte2,ZL ldi ZL,0xaa mov byte1,ZL ldi ZL,0x11; secret key value :11,22,33,44,55,66,77,88 mov key8,ZL ldi ZL,0x22 mov key7,ZL ldi ZL,0x33 mov key6,ZL ldi ZL,0x44 mov key5,ZL ldi ZL,0x55 mov key4,ZL ldi ZL,0x66 mov key3,ZL ldi ZL,0x77 mov key2,ZL ldi ZL,0x88 mov key1,ZL ldi mode,ENCODE; encryption mode rcall DES; result is 6b,34,25,73,57,3f,66,15 ; and reused for decription ldi ZL,0x11; reload the same secret key value mov key8,ZL ldi ZL,0x22 mov key7,ZL ldi ZL,0x33 mov key6,ZL ldi ZL,0x44 mov key5,ZL ldi ZL,0x55 mov key4,ZL ldi ZL,0x66 mov key3,ZL ldi ZL,0x77 mov key2,ZL ldi ZL,0x88 mov key1,ZL ldi mode,DECODE; decode mode rcall DES; result should be f1,1d,59,a5,5a,37,fe,aa. rjmp RESET |