RosettaCodeData/Task/MD5/ARM-Assembly/md5.arm

383 lines
12 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* 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"