/* ARM assembly Raspberry PI */ /* program sha256.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, 32 // result length /*******************************************/ /* 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 var_e: // e .struct var_e + 4 var_f: // f .struct var_f + 4 var_g: // g .struct var_g + 4 var_h: // h .struct var_h + 4 /*********************************/ /* Initialized data */ /*********************************/ .data szMessRosetta: .asciz "Rosetta code" szMessTest1: .asciz "abc" szMessSup64: .ascii "ABCDEFGHIJKLMNOPQRSTUVWXYZ" .ascii "abcdefghijklmnopqrstuvwxyz" .asciz "1234567890AZERTYUIOP" szMessTest2: .asciz "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" szMessFinPgm: .asciz "Program End ok.\n" szMessResult: .asciz "Rosetta code => " szCarriageReturn: .asciz "\n" /* array constantes Hi */ tbConstHi: .int 0x6A09E667 @ H0 .int 0xBB67AE85 @ H1 .int 0x3C6EF372 @ H2 .int 0xA54FF53A @ H3 .int 0x510E527F @ H4 .int 0x9B05688C @ H5 .int 0x1F83D9AB @ H6 .int 0x5BE0CD19 @ H7 /* array 64 constantes Kt */ tbConstKt: .int 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5 .int 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174 .int 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da .int 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967 .int 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85 .int 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070 .int 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3 .int 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 /*********************************/ /* UnInitialized data */ /*********************************/ .bss .align 4 iNbBlocs: .skip 4 sZoneConv: .skip 24 sZoneTrav: .skip 1000 .align 8 tbH: .skip 4 * 8 @ 8 variables H tbabcdefgh: .skip 4 * 8 tbW: .skip 4 * 64 @ 64 words W /*********************************/ /* code section */ /*********************************/ .text .global main main: @ entry of program ldr r0,iAdrszMessRosetta //ldr r0,iAdrszMessTest1 //ldr r0,iAdrszMessTest2 //ldr r0,iAdrszMessSup64 bl computeSHA256 @ call routine SHA1 ldr r0,iAdrszMessResult bl affichageMess @ display message ldr r0, iAdrtbH bl displaySHA1 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 iAdrszMessRosetta: .int szMessRosetta iAdrszMessTest1: .int szMessTest1 iAdrszMessTest2: .int szMessTest2 iAdrsZoneTrav: .int sZoneTrav iAdrsZoneConv: .int sZoneConv iAdrszMessFinPgm: .int szMessFinPgm iAdrszMessSup64: .int szMessSup64 /******************************************************************/ /* compute SHA1 */ /******************************************************************/ /* r0 contains the address of the message */ computeSHA256: push {r1-r12,lr} @ save registres ldr r1,iAdrsZoneTrav mov r2,#0 @ counter length debCopy: @ copy string in work area ldrb r3,[r0,r2] strb r3,[r1,r2] cmp r3,#0 addne r2,r2,#1 bne debCopy 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 addZeroes: lsr r5,r2,#6 lsl r5,r5,#6 sub r5,r2,r5 cmp r5,#56 beq storeLength @ 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 addZeroes storeLength: add r2,#4 @ add four bytes rev r6,r6 @ inversion bits initials message length str r6,[r1,r2] @ and store at end ldr r7,iAdrtbConstHi @ constantes H address ldr r4,iAdrtbH @ start area H mov r5,#0 loopConst: @ 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,#8 blt loopConst @ split into block of 64 bytes add r2,#4 @ TODO : à revoir lsr r4,r2,#6 @ blocks number ldr r0,iAdriNbBlocs str r4,[r0] @ save block maxi mov r7,#0 @ n° de block et r1 contient l adresse zone de travail loopBlock: @ begin loop of each block of 64 bytes mov r0,r7 bl inversion @ inversion each word because little indian ldr r3,iAdrtbW @ working area W address mov r6,#0 @ indice t /* r2 address begin each block */ ldr r1,iAdrsZoneTrav add r2,r1,r7,lsl #6 @ compute block begin indice * 4 * 16 //vidregtit avantloop //mov r0,r2 //vidmemtit verifBloc r0 10 loopPrep: @ loop for expand 80 words cmp r6,#15 @ bgt expand1 ldr r0,[r2,r6,lsl #2] @ load byte message str r0,[r3,r6,lsl #2] @ store in first 16 block b expandEnd expand1: sub r8,r6,#2 ldr r9,[r3,r8,lsl #2] ror r10,r9,#17 @ fonction e1 (256) ror r11,r9,#19 eor r10,r10,r11 lsr r11,r9,#10 eor r10,r10,r11 sub r8,r6,#7 ldr r9,[r3,r8,lsl #2] add r9,r9,r10 @ + w - 7 sub r8,r6,#15 ldr r10,[r3,r8,lsl #2] ror r11,r10,#7 @ fonction e0 (256) ror r12,r10,#18 eor r11,r12 lsr r12,r10,#3 eor r10,r11,r12 add r9,r9,r10 sub r8,r6,#16 ldr r11,[r3,r8,lsl #2] add r9,r9,r11 str r9,[r3,r6,lsl #2] expandEnd: add r6,r6,#1 cmp r6,#64 @ 64 words ? blt loopPrep @ and loop /* COMPUTING THE MESSAGE DIGEST */ /* r1 area H constantes address */ /* r3 working area W address */ /* r5 address constantes K */ /* r6 counter t */ /* r7 block counter */ /* r8 addresse variables a b c d e f g h */ //ldr r0,iAdrtbW //vidmemtit verifW80 r0 20 @ init variable a b c d e f g h ldr r0,iAdrtbH ldr r8,iAdrtbabcdefgh mov r1,#0 loopInita: ldr r9,[r0,r1,lsl #2] str r9,[r8,r1,lsl #2] add r1,r1,#1 cmp r1,#8 blt loopInita ldr r1,iAdrtbConstHi ldr r5,iAdrtbConstKt mov r6,#0 loop64T: @ begin loop 64 t ldr r9,[r8,#var_h] ldr r10,[r8,#var_e] @ calcul T1 ror r11,r10,#6 @ fonction sigma 1 ror r12,r10,#11 eor r11,r12 ror r12,r10,#25 eor r11,r12 add r9,r9,r11 @ h + sigma1 (e) ldr r0,[r8,#var_f] @ fonction ch x and y xor (non x and z) ldr r4,[r8,#var_g] and r11,r10,r0 mvn r12,r10 and r12,r12,r4 eor r11,r12 add r9,r9,r11 @ h + sigma1 (e) + ch (e,f,g) ldr r0,[r5,r6,lsl #2] @ load constantes k0 add r9,r9,r0 ldr r0,[r3,r6,lsl #2] @ Wt add r9,r9,r0 @ calcul T2 ldr r10,[r8,#var_a] @ fonction sigma 0 ror r11,r10,#2 ror r12,r10,#13 eor r11,r11,r12 ror r12,r10,#22 eor r11,r11,r12 ldr r2,[r8,#var_b] ldr r4,[r8,#var_c] @ fonction maj x and y xor x and z xor y and z and r12,r10,r2 and r0,r10,r4 eor r12,r12,r0 and r0,r2,r4 eor r12,r12,r0 @ add r12,r12,r11 @ T2 @ compute variables ldr r4,[r8,#var_g] str r4,[r8,#var_h] ldr r4,[r8,#var_f] str r4,[r8,#var_g] ldr r4,[r8,#var_e] str r4,[r8,#var_f] ldr r4,[r8,#var_d] add r4,r4,r9 @ add T1 str r4,[r8,#var_e] ldr r4,[r8,#var_c] str r4,[r8,#var_d] ldr r4,[r8,#var_b] str r4,[r8,#var_c] ldr r4,[r8,#var_a] str r4,[r8,#var_b] add r4,r9,r12 @ add T1 T2 str r4,[r8,#var_a] mov r0,r8 add r6,r6,#1 @ increment t cmp r6,#64 blt loop64T @ End block ldr r0,iAdrtbH @ start area H mov r10,#0 loopStoreH: ldr r9,[r8,r10,lsl #2] ldr r3,[r0,r10,lsl #2] add r3,r9 str r3,[r0,r10,lsl #2] @ store variables in H0 add r10,r10,#1 cmp r10,#8 blt loopStoreH @ other bloc add r7,#1 @ increment block ldr r0,iAdriNbBlocs ldr r4,[r0] @ restaur maxi block cmp r7,r4 @ maxi ? blt loopBlock @ loop other block mov r0,#0 @ routine OK 100: pop {r1-r12,lr} @ restaur registers bx lr @ return iAdrtbConstHi: .int tbConstHi iAdrtbConstKt: .int tbConstKt iAdrtbH: .int tbH iAdrtbW: .int tbW iAdrtbabcdefgh: .int tbabcdefgh iAdriNbBlocs: .int iNbBlocs /******************************************************************/ /* inversion des mots de 32 bits d un bloc */ /******************************************************************/ /* r0 contains N° block */ inversion: push {r1-r3,lr} @ save registers ldr r1,iAdrsZoneTrav add r1,r0,lsl #6 @ debut du bloc mov r2,#0 1: @ start loop ldr r3,[r1,r2,lsl #2] rev r3,r3 str r3,[r1,r2,lsl #2] add r2,r2,#1 cmp r2,#16 blt 1b 100: pop {r1-r3,lr} @ restaur registres bx lr @return /******************************************************************/ /* display hash SHA1 */ /******************************************************************/ /* r0 contains the address of hash */ displaySHA1: push {r1-r3,lr} @ save registres mov r3,r0 mov r2,#0 1: ldr r0,[r3,r2,lsl #2] @ load 4 bytes //rev r0,r0 @ reverse 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"