376 lines
12 KiB
Text
376 lines
12 KiB
Text
/* 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"
|