383 lines
12 KiB
Plaintext
383 lines
12 KiB
Plaintext
/* 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"
|