A
abc.w schrieb:
Wenn du es nicht machst, dann macht's auch keiner.
So, ich hab's gemacht und hier is mein Quellcode, habe ein wenig getestet, scheint so zu funktionieren und ich hoffe, habe keine Fehler eingebaut. Viel Spass damit.
.global rc4init
# Constants for accessing function parameters on stack:
# int rc4init(const char key[], size_t L, char sbox[])
.equ key, 4
.equ L, 8
.equ sbox, 12
# Constants for accessing local stack frame
.equ saved_ebx, -4
.equ jcnt, -8
.equ icnt, -12
.equ kcnt, -16
.equ tmp, -20
.equ saved_esi, -28
.section .text
rc4init:
xorl %eax, %eax
cmpl %eax, key(%esp) # Check for NULL pointer key[]
je key_is_null
cmpl $5, L(%esp) # Check for valid range of L
jl L_range_wrong
cmpl $256, L(%esp)
jg L_range_wrong
cmpl %eax, sbox(%esp) # Check for NULL pointer sbox[]
je sbox_is_null
movl %ebx, saved_ebx(%esp) # Save registers
movl %esi, saved_esi(%esp)
movl sbox(%esp), %ebx # Load address of sbox[0]
movl key(%esp), %esi # Load address of key[0]
movl $63, %ecx # Loop counter
movl $0xFFFEFDFC, %eax # Contains initial value for sbox[]
movl $0x04040404, %edx # Decrement value
0: # Loop for initializing sbox[]
movl %eax, (%ebx, %ecx, 4) # Save new values in sbox[]
subl %edx, %eax # Compute next values
decl %ecx
jnz 0b
movl %eax, (%ebx) # Save rest values in sbox[]
movl %ecx, jcnt(%esp) # Reset the counters i, j and k (use the
movl %ecx, icnt(%esp) # loop counter, because it is zero here)
movl %ecx, kcnt(%esp)
1:
movzbl (%esi, %ecx), %eax # Load key[k]
incl %ecx # Compute k = ((k + 1) mod L)
cmpl %ecx, L(%esp)
jl 2f
xorl %ecx, %ecx
2:
movl %ecx, kcnt(%esp)
movl icnt(%esp), %ecx
movzbl (%ebx, %ecx), %ecx # Load sbox[i]
addl %eax, %ecx # Compute (sbox[i] + key[k])
addl jcnt(%esp), %ecx # Compute j = ((j + sbox[i] + key[k mod L]) mod 256)
andl $0x000000FF, %ecx
movl %ecx, jcnt(%esp)
movl icnt(%esp), %eax
movzbl (%ebx, %eax), %edx # Load sbox[i] and save it in tmp
movl %edx, tmp(%esp)
movzbl (%ebx, %ecx), %edx # Load sbox[j] and overwrite sbox[i] with it
movb %dl, (%ebx, %eax)
movl tmp(%esp), %edx # Load saved sbox[i] and overwrite sbox[j] with it
movb %dl, (%ebx, %ecx)
incl %eax
movl kcnt(%esp), %ecx # Load k counter here, it will be used at top of the loop
movl %eax, icnt(%esp)
cmpl $256, %eax
jb 1b
movl saved_ebx(%esp), %ebx # Restore registers
movl saved_esi(%esp), %esi
xorl %eax, %eax # Return no errors
ret
key_is_null:
movl $-1, %eax # Return error code
ret
L_range_wrong:
movl $-2, %eax # Return error code
ret
sbox_is_null:
movl $-3, %eax # Return error code
ret
.global rc4run
# Constants for accessing function parameters on stack:
# int rc4run(const char buf_in[], size_t len, char buf_out[], char sbox[])
.equ buf_in, 4
.equ len, 8
.equ buf_out, 12
.equ sbox, 16
# Constants for accessing local stack frame
.equ saved_ebx, -4
.equ saved_esi, -8
.equ saved_edi, -12
.equ jcnt, -16
.equ icnt, -20
.equ ncnt, -24
.equ tmp, -28
.section .text
rc4run:
xorl %eax, %eax
cmpl %eax, buf_in(%esp) # Check for NULL pointer buf_in[]
je buf_in_is_null
cmpl %eax, buf_out(%esp) # Check for NULL pointer buf_out[]
je buf_out_is_null
cmpl %eax, sbox(%esp) # Check for NULL pointer sbox[]
je sbox_is_null
cmpl %eax, len(%esp) # Check for valid range of len
je len_range_is_wrong
movl %ebx, saved_ebx(%esp) # Save registers
movl %esi, saved_esi(%esp)
movl %edi, saved_edi(%esp)
movl sbox(%esp), %ebx # Load address of sbox[0]
movl buf_in(%esp), %esi # Load address of buf_in[0]
movl buf_out(%esp), %edi # Load address of buf_out[0]
movl %eax, icnt(%esp) # Reset the counters i, j and n
movl %eax, jcnt(%esp)
movl %eax, ncnt(%esp)
0:
movl icnt(%esp), %eax # Compute i = ((i + 1) mod 256)
incl %eax
andl $0x000000FF, %eax
movl %eax, icnt(%esp)
movzbl (%ebx, %eax), %edx # Load sbox[i] and save it in tmp
movl %edx, tmp(%esp)
addl jcnt(%esp), %edx # Compute j = ((j + sbox[i]) mod 256)
andl $0x000000FF, %edx
movl %edx, jcnt(%esp)
movzbl (%ebx, %edx), %ecx # Load sbox[j] and overwrite sbox[i] with it
movb %cl, (%ebx, %eax)
movl %ecx, %eax
movl tmp(%esp), %ecx # Load saved value sbox[i] and overwrite sbox[j] with it
movb %cl, (%ebx, %edx)
addl %ecx, %eax # Compute index = ((sbox[i] + sbox[j]) mod 256)
andl $0x000000FF, %eax
movzbl (%ebx, %eax), %ecx # Load sbox[index], this is a new random number
movl ncnt(%esp), %eax # Load buf_in[n]
movzbl (%esi, %eax), %edx
xorl %ecx, %edx # Encrypt
movb %dl, (%edi, %eax) # Save new encrypted value in buf_out[n]
incl %eax # Compute n = (n + 1) and check, end of buf_in[] reached or not
movl %eax, ncnt(%esp)
cmpl len(%esp), %eax
jb 0b
movl saved_ebx(%esp), %ebx # Restore registers
movl saved_esi(%esp), %esi
movl saved_edi(%esp), %edi
xorl %eax, %eax # Return no errors
ret
buf_in_is_null:
movl $-1, %eax # Return error code
ret
buf_out_is_null:
movl $-2, %eax # Return error code
ret
sbox_is_null:
movl $-3, %eax # Return error code
ret
len_range_is_wrong:
movl $-4, %eax # Return error code
ret
Die beiden Funktionen sehen so aus:
int rc4init(const char key[], size_t L, char sbox[]);
int rc4run(const char buf_in[], size_t len, char buf_out[], char sbox[]);