Full Version : 8 Byte DES Data Encryption (AVR ASM)
avr >>COMMUNICATIONS & WEB PROJECTS >>8 Byte DES Data Encryption (AVR ASM)


AVR_Admin- 05-09-2006
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


Link: http://vfx.freeweb.hu/avr/index.html


Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.