/* ARM assembly AARCH64 Raspberry PI 3B */ /* program MD5_64.s */ /*******************************************/ /* Constantes file */ /*******************************************/ /* for this file see task include a file in language AArch64 assembly*/ .include "../includeConstantesARM64.inc" .equ MD5_DIGEST_LENGTH, 16 .equ ZWORKSIZE, 1000 /*********************************/ /* Initialized data */ /*********************************/ .data szMessRosetta: .asciz "Rosetta Code" szMessTest1: .asciz "" szMessTest2: .asciz "abc" szMessTest3: .asciz "abcdefghijklmnopqrstuvwxyz" szMessTest4: .asciz "12345678901234567890123456789012345678901234567890123456789012345678901234567890" szMessTest5: .asciz "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" 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" /* 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 //iNbBlocs: .skip 8 sZoneConv: .skip 24 sZoneResult: .skip 24 tbH: .skip 4 * 4 // 4 variables H sZoneTrav: .skip ZWORKSIZE /*********************************/ /* code section */ /*********************************/ .text .global main main: // entry of program ldr x0,qAdrszMessTest1 bl computeExemple ldr x0,qAdrszMessTest2 bl computeExemple ldr x0,qAdrszMessTest3 bl computeExemple ldr x0,qAdrszMessTest4 bl computeExemple ldr x0,qAdrszMessTest5 bl computeExemple ldr x0,qAdrszMessFinPgm bl affichageMess // display message 100: // standard end of the program mov x0,0 // return code mov x8,EXIT // request to exit program svc 0 // perform the system call qAdrszCarriageReturn: .quad szCarriageReturn qAdrszMessResult: .quad szMessResult qAdrszMessResult1: .quad szMessResult1 qAdrszMessRosetta: .quad szMessRosetta qAdrszMessTest1: .quad szMessTest1 qAdrszMessTest2: .quad szMessTest2 qAdrszMessTest3: .quad szMessTest3 qAdrszMessTest4: .quad szMessTest4 qAdrszMessTest5: .quad szMessTest5 qAdrsZoneTrav: .quad sZoneTrav qAdrsZoneConv: .quad sZoneConv qAdrszMessFinPgm: .quad szMessFinPgm /***********************************************/ /* compute exemple */ /***********************************************/ /* x0 contains the address of the message */ computeExemple: stp x18,lr,[sp,-16]! // save registers mov x18,x0 bl computeMD5 // call routine MD5 ldr x0,qAdrszMessResult bl affichageMess mov x0,x18 bl affichageMess ldr x0,qAdrszMessResult1 bl affichageMess ldr x0, qAdrsZoneResult bl displayMD5 100: ldp x18,lr,[sp],16 // restaur 2 registers ret // return to address lr x30 /******************************************************************/ /* compute MD5 */ /******************************************************************/ /* x0 contains the address of the message */ computeMD5: stp x1,lr,[sp,-16]! // save registers ldr x1,qAdrsZoneTrav mov x2,#0 // counter length 1: // copy string in work area cmp x2,ZWORKSIZE bge 99f ldrb w3,[x0,x2] strb w3,[x1,x2] cmp x3,#0 add x4,x2,1 csel x2,x4,x2,ne bne 1b // add bit et compute length lsl x6,x2,#3 // initial message length in bits mov x3,#0b10000000 // add bit 1 at end of string strb w3,[x1,x2] add x2,x2,#1 // length in bytes lsl x4,x2,#3 // length in bits mov x3,#0 2: lsr x5,x2,#6 // padding block 512 bytes lsl x5,x5,#6 sub x5,x2,x5 cmp x5,#56 beq 3f // yes -> end add strb w3,[x1,x2] // add zero at message end add x2,x2,#1 // increment length bytes add x4,x4,#8 // increment length in bits b 2b 3: str x6,[x1,x2] // and store at end ldr x7,qAdrtbConstH // constantes H address ldr x4,qAdrtbH // start area H mov x5,#0 4: // init array H with start constantes ldr w6,[x7,x5,lsl #2] // load constante str w6,[x4,x5,lsl #2] // and store add x5,x5,#1 cmp x5,#4 // constantes number blt 4b // split into block of 64 bytes add x2,x2,#4 // TODO : à revoir lsr x4,x2,#6 // blocks number mov x7,#0 // no de block et x1 contient l'adresse zone de travail ldr x3,qAdrtbConstK // K constantes address ldr x5,qAdrtbRotaR // R rotation address 5: // begin loop of each block of 64 bytes // init variable a b c d with H0 H1 H2 H3 ldr x0,qAdrtbH ldr w8,[x0] // a ldr w9,[x0,#4] // b ldr w10,[x0,#8] // c ldr w11,[x0,#12] // d mov x6,#0 // indice t /* x2 address begin each block */ ldr x1,qAdrsZoneTrav add x2,x1,x7,lsl #6 // compute block begin indice * 4 * 16 6: // begin loop one cmp x6,15 bgt 7f // cas 1 f := (b et c) ou ((non b) et d) // g := i and w12,w9,w10 mvn w13,w9 and w13,w13,w11 orr w12,w12,w13 // f mov x14,x6 // g b 10f 7: cmp x6,31 bgt 8f // f := (d et b) ou ((non d) et c) // g := (5×i + 1) mod 16 and w12,w11,w9 mvn w13,w11 and w13,w13,w10 orr w12,w12,w13 // f mov x13,5 mul x13,x6,x13 add x13,x13,1 lsr x15,x13,4 lsl x15,x15,4 sub x14,x13,x15 b 10f 8: cmp x6,47 bgt 9f // f := b xor c xor d // g := (3×i + 5) mod 16 eor w12,w9,w10 eor w12,w12,w11 mov x13,3 mul x13,x6,x13 add x13,x13,5 lsr x15,x13,4 lsl x15,x15,4 sub x14,x13,x15 b 10f 9: // f := c xor (b ou (non d)) // g := (7×i) mod 16 mvn w13,w11 orr w13,w13,w9 eor w12,w13,w10 // f mov x13,7 mul x13,x6,x13 lsr x15,x13,4 lsl x15,x15,4 sub x14,x13,x15 // g 10: mov w15,w11 mov w11,w10 // d = c mov w10,w9 // c = b add w16,w8,w12 // a + f ldr w17,[x2,x14,lsl #2] add w16,w16,w17 // + valeur bloc g ldr w13,[x3,x6,lsl #2] add w16,w16,w13 // + valeur constante K de i ldr w17,[x5,x6,lsl #2] // rotate left value mov w13,32 sub w17,w13,w17 ror w13,w16,w17 add w9,w9,w13 // new b mov w8, w15 // new a add x6,x6,1 cmp x6,63 ble 6b ldr x0,qAdrtbH ldr w1,[x0] // H0 add w1,w1,w8 // + a str w1,[x0] ldr w1,[x0,#4] // H1 add w1,w1,w9 // + b str w1,[x0,#4] ldr w1,[x0,#8] // H2 add w1,w1,w10 // + c str w1,[x0,#8] ldr w1,[x0,#12] // H3 add w1,w1,w11 // + d str w1,[x0,#12] // other bloc add x7,x7,1 // increment block cmp x7,x4 // maxi ? ble 5b // compute final result ldr x0,qAdrtbH // start area H ldr x2,qAdrsZoneResult ldr w1,[x0] str w1,[x2] ldr w1,[x0,#4] str w1,[x2,#4] ldr w1,[x0,#8] str w1,[x2,#8] ldr w1,[x0,#12] str w1,[x2,#12] mov x0,#0 // routine OK b 100f 99: // size error ldr x0,qAdrszMessSizeError bl affichageMess mov x0,-1 100: ldp x1,lr,[sp],16 // restaur 2 registers ret // return to address lr x30 qAdrtbConstH: .quad tbConstH qAdrtbConstK: .quad tbConstK qAdrtbRotaR: .quad tbRotaR qAdrtbH: .quad tbH qAdrsZoneResult: .quad sZoneResult qAdrszMessSizeError: .quad szMessSizeError /******************************************************************/ /* display hash MD5 */ /******************************************************************/ /* x0 contains the address of hash */ displayMD5: stp x1,lr,[sp,-16]! // save registers stp x2,x3,[sp,-16]! // save registers mov x3,x0 mov x2,#0 1: ldr w0,[x3,x2,lsl #2] // load 4 bytes rev w0,w0 // reverse bytes ldr x1,qAdrsZoneConv bl conversion16_4W // conversion hexa ldr x0,qAdrsZoneConv bl affichageMess add x2,x2,#1 cmp x2,#MD5_DIGEST_LENGTH / 4 blt 1b // and loop ldr x0,qAdrszCarriageReturn bl affichageMess // display message 100: ldp x2,x3,[sp],16 // restaur 2 registers ldp x1,lr,[sp],16 // restaur 2 registers ret // return to address lr x30 /******************************************************************/ /* conversion hexadecimal register 32 bits */ /******************************************************************/ /* x0 contains value and x1 address zone receptrice */ conversion16_4W: stp x0,lr,[sp,-48]! // save registres stp x1,x2,[sp,32] // save registres stp x3,x4,[sp,16] // save registres mov x2,#28 // start bit position mov x4,#0xF0000000 // mask mov x3,x0 // save entry value 1: // start loop and x0,x3,x4 // value register and mask lsr x0,x0,x2 // right shift cmp x0,#10 // >= 10 ? bge 2f // yes add x0,x0,#48 // no is digit b 3f 2: add x0,x0,#55 // else is a letter A-F 3: strb w0,[x1],#1 // load result and + 1 in address lsr x4,x4,#4 // shift mask 4 bits left subs x2,x2,#4 // decrement counter 4 bits <= zero ? bge 1b // no -> loop 100: // fin standard de la fonction ldp x3,x4,[sp,16] // restaur des 2 registres ldp x1,x2,[sp,32] // restaur des 2 registres ldp x0,lr,[sp],48 // restaur des 2 registres ret /********************************************************/ /* File Include fonctions */ /********************************************************/ /* for this file see task include a file in language AArch64 assembly */ .include "../includeARM64.inc"