/* ARM assembly Raspberry PI */ /* program MD5.s */ /* REMARK 1 : this program use routines in a include file see task Include a file language arm assembly for the routine affichageMess conversion10 see at end of this program the instruction include */ /* for constantes see task include a file in arm assembly */ /************************************/ /* Constantes */ /************************************/ .include "../constantes.inc" .equ LGHASH, 16 // result length .equ ZWORKSIZE, 1000 // work area size /*******************************************/ /* Structures */ /********************************************/ /* example structure variables */ .struct 0 var_a: // a .struct var_a + 4 var_b: // b .struct var_b + 4 var_c: // c .struct var_c + 4 var_d: // d .struct var_d + 4 /*********************************/ /* Initialized data */ /*********************************/ .data szMessTest1: .asciz "abc" szMessTest4: .asciz "12345678901234567890123456789012345678901234567890123456789012345678901234567890" szMessTest2: .asciz "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" szMessTest3: .asciz "abcdefghijklmnopqrstuvwxyz" szMessFinPgm: .asciz "Program End ok.\n" szMessResult: .asciz "Result for " szMessResult1: .asciz " => " szMessSizeError: .asciz "\033[31mWork area too small !! \033[0m \n" szCarriageReturn: .asciz "\n" .align 4 /* array constantes K */ tbConstK: .int 0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee .int 0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501 .int 0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be .int 0x6b901122,0xfd987193,0xa679438e,0x49b40821 .int 0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa .int 0xd62f105d,0x2441453,0xd8a1e681,0xe7d3fbc8 .int 0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed .int 0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a .int 0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c .int 0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70 .int 0x289b7ec6,0xeaa127fa,0xd4ef3085,0x4881d05 .int 0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665 .int 0xf4292244,0x432aff97,0xab9423a7,0xfc93a039 .int 0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1 .int 0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1 .int 0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391 /* array rotation coef R */ tbRotaR: .int 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22 .int 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20 .int 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23 .int 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 tbConstH: .int 0x67452301 // H0 .int 0xEFCDAB89 // H1 .int 0x98BADCFE // H2 .int 0x10325476 // H3 /*********************************/ /* UnInitialized data */ /*********************************/ .bss .align 4 sZoneConv: .skip 24 tbH: .skip 4 * 4 @ 4 variables H tbabcd: .skip 4 * 4 @ 4 variables a b c d sZoneTrav: .skip 1000 /*********************************/ /* code section */ /*********************************/ .text .global main main: @ entry of program ldr r0,iAdrszMessTest1 bl computeExemple ldr r0,iAdrszMessTest2 bl computeExemple ldr r0,iAdrszMessTest3 bl computeExemple ldr r0,iAdrszMessTest4 bl computeExemple ldr r0,iAdrszMessFinPgm bl affichageMess @ display message 100: @ standard end of the program mov r0, #0 @ return code mov r7, #EXIT @ request to exit program svc #0 @ perform the system call iAdrszCarriageReturn: .int szCarriageReturn iAdrszMessResult: .int szMessResult iAdrszMessResult1: .int szMessResult1 iAdrszMessTest1: .int szMessTest1 iAdrszMessTest2: .int szMessTest2 iAdrszMessTest3: .int szMessTest3 iAdrszMessTest4: .int szMessTest4 iAdrsZoneTrav: .int sZoneTrav iAdrsZoneConv: .int sZoneConv iAdrszMessFinPgm: .int szMessFinPgm iAdrszMessSizeError: .int szMessSizeError /***********************************************/ /* compute exemple */ /***********************************************/ /* r0 contains the address of the message */ computeExemple: push {r1,lr} @ save registres mov r1,r0 bl computeMD5 @ call routine MD5 ldr r0,iAdrszMessResult bl affichageMess mov r0,r1 bl affichageMess ldr r0,iAdrszMessResult1 bl affichageMess ldr r0, iAdrtbH bl displayMD5 100: pop {r1,pc} @ restaur registers /******************************************************************/ /* compute MD5 */ /******************************************************************/ /* r0 contains the address of the message */ computeMD5: push {r1-r12,lr} @ save registres ldr r1,iAdrsZoneTrav mov r2,#0 @ counter length 1: @ copy string in work area cmp r2,#ZWORKSIZE @ maxi ? bge 99f @ error ldrb r3,[r0,r2] strb r3,[r1,r2] cmp r3,#0 addne r2,r2,#1 bne 1b lsl r6,r2,#3 @ initial message length in bits mov r3,#0b10000000 @ add bit 1 at end of string strb r3,[r1,r2] add r2,r2,#1 @ length in bytes lsl r4,r2,#3 @ length in bits mov r3,#0 2: lsr r5,r2,#6 lsl r5,r5,#6 sub r5,r2,r5 cmp r5,#56 beq 3f @ yes -> end add strb r3,[r1,r2] @ add zero at message end add r2,#1 @ increment lenght bytes add r4,#8 @ increment length in bits b 2b 3: str r6,[r1,r2] @ and store length at end add r5,r2,#4 str r3,[r1,r5] @ store zero in hight bits for 64 bits ldr r7,iAdrtbConstH @ constantes H address ldr r4,iAdrtbH @ start area H mov r5,#0 4: @ init array H with start constantes ldr r6,[r7,r5,lsl #2] @ load constante str r6,[r4,r5,lsl #2] @ and store add r5,r5,#1 cmp r5,#4 blt 4b @ split into block of 64 bytes add r2,#4 @ TODO : à revoir lsr r4,r2,#6 @ blocks number ldr r0,iAdrtbH @ variables H ldr r1,iAdrsZoneTrav ldr r5,iAdrtbConstK ldr r3,iAdrtbRotaR ldr r8,iAdrtbabcd mov r7,#0 @ n° de block et r1 contient l adresse zone de travail 5: @ begin loop of each block of 64 bytes add r2,r1,r7,lsl #6 @ compute block begin indice * 4 * 16 mov r6,#0 @ indice t /* COMPUTING THE MESSAGE DIGEST */ /* r0 variables H address */ /* r1 work area */ /* r2 block work area begin address */ /* r3 address constantes rotate */ /* r4 block number */ /* r5 constance K address */ /* r6 counter t */ /* r7 block counter */ /* r8 addresse variables a b c d */ @ init variable a b c d with variables H mov r10,#0 6: @ loop init ldr r9,[r0,r10,lsl #2] @ variables H str r9,[r8,r10,lsl #2] @ variables a b c d add r10,r10,#1 cmp r10,#4 blt 6b 7: @ loop begin cmp r6,#15 bgt 8f @ cas 1 f := (b et c) ou ((non b) et d) @ g := i ldr r9,[r8,#var_b] ldr r10,[r8,#var_c] and r12,r10,r9 mvn r9,r9 ldr r10,[r8,#var_d] and r11,r9,r10 orr r12,r12,r11 @ f mov r9,r6 @ g b 11f 8: cmp r6,#31 bgt 9f @ f := (d et b) ou ((non d) et c) @ g := (5×i + 1) mod 16 ldr r9,[r8,#var_b] ldr r10,[r8,#var_d] and r12,r10,r9 mvn r10,r10 ldr r9,[r8,#var_c] and r11,r9,r10 orr r12,r12,r11 @ f mov r9,#5 mul r9,r6,r9 add r9,r9,#1 lsr r10,r9,#4 lsl r10,r10,#4 sub r9,r9,r10 @ g b 11f 9: cmp r6,#47 bgt 10f @ f := b xor c xor d @ g := (3×i + 5) mod 16 ldr r9,[r8,#var_b] ldr r10,[r8,#var_c] eor r12,r10,r9 ldr r10,[r8,#var_d] eor r12,r12,r10 @ f mov r9,#3 mul r9,r6,r9 add r9,r9,#5 lsr r10,r9,#4 lsl r10,r10,#4 sub r9,r9,r10 @ g b 11f 10: @ f := c xor (b ou (non d)) @ g := (7×i) mod 16 ldr r10,[r8,#var_d] mvn r12,r10 ldr r10,[r8,#var_b] orr r12,r12,r10 ldr r10,[r8,#var_c] eor r12,r12,r10 @ f mov r9,#7 mul r9,r6,r9 lsr r10,r9,#4 lsl r10,r10,#4 sub r9,r9,r10 @ g 11: ldr r10,[r8,#var_d] mov r11,r10 @ save old d ldr r10,[r8,#var_c] str r10,[r8,#var_d] @ new d = c ldr r10,[r8,#var_b] str r10,[r8,#var_c] @ new c = b ldr r10,[r8,#var_a] add r12,r12,r10 @ a + f ldr r10,[r2,r9,lsl #2] add r12,r12,r10 @ + valeur bloc g ldr r10,[r5,r6,lsl #2] add r12,r12,r10 @ + valeur constante K de i ldr r10,[r3,r6,lsl #2] @ rotate left value rsb r10,r10,#32 @ compute right rotate ror r12,r12,r10 ldr r10,[r8,#var_b] add r12,r12,r10 str r12,[r8,#var_b] @ new b str r11,[r8,#var_a] @ new a = old d add r6,r6,#1 cmp r6,#63 ble 7b @ maj area H ldr r10,[r0] @ H0 ldr r11,[r8,#var_a] add r10,r10,r11 @ + a str r10,[r0] ldr r10,[r0,#4] @ H1 ldr r11,[r8,#var_b] add r10,r10,r11 @ + b str r10,[r0,#4] ldr r10,[r0,#8] @ H2 ldr r11,[r8,#var_c] add r10,r10,r11 @ + c str r10,[r0,#8] ldr r10,[r0,#12] @ H3 ldr r11,[r8,#var_d] add r10,r10,r11 @ + d str r10,[r0,#12] @ loop other block add r7,r7,#1 @ increment block cmp r7,r4 @ maxi ? ble 5b mov r9,#0 @ reverse bytes loop 12: ldr r10,[r0,r9,lsl #2] rev r10,r10 @ reverse bytes str r10,[r0,r9,lsl #2] add r9,r9,#1 cmp r9,#LGHASH / 4 blt 12b mov r0,#0 @ routine OK b 100f 99: @ size error ldr r0,iAdrszMessSizeError bl affichageMess mov r0,#-1 @ error routine 100: pop {r1-r12,pc} @ restaur registers iAdrtbConstH: .int tbConstH iAdrtbConstK: .int tbConstK iAdrtbRotaR: .int tbRotaR iAdrtbH: .int tbH iAdrtbabcd: .int tbabcd /*************************************************/ /* display hash MD5 */ /*************************************************/ /* r0 contains the address of hash */ displayMD5: push {r1-r3,lr} @ save registres mov r3,r0 mov r2,#0 1: ldr r0,[r3,r2,lsl #2] @ load 4 bytes ldr r1,iAdrsZoneConv bl conversion16 @ conversion hexa ldr r0,iAdrsZoneConv bl affichageMess add r2,r2,#1 cmp r2,#LGHASH / 4 blt 1b @ and loop ldr r0,iAdrszCarriageReturn bl affichageMess @ display message 100: pop {r1-r3,lr} @ restaur registers bx lr @ return /***************************************************/ /* ROUTINES INCLUDE */ /***************************************************/ .include "../affichage.inc"