summaryrefslogtreecommitdiff
path: root/other/burneye/src/stub/cipher-glfsr.asm
blob: 7b4871f2be6a76b0dd27113dc73c7e5504e4fd69 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
; minimalistic size-optimized cipher 'glfsr'
;
; using one single 32 bit galois linear feedback shifting register with a
; fixed tap sequence. can be broken easily but its better than the
; standard xor cipher and it looks neat, takes only ~25 bytes of code ;)

%ifdef IN_STUB
	GLOBAL	glent

glen:	dd	0x00000000
gkey:	dd	0x00000000
gnent:	dd	0x00000000

	db	'TEEE burneye - TESO ELF Encryption Engine'

glent:;	int3
	push	dword [gnent]
	pushf
	pusha
	mov	ecx, [glen]
	jmp	hunk
hret:	pop	esi
	mov	edi, esi
	mov	ebx, [gkey]

	or	ebx, ebx	; zero key = skip, used for SEAL mode
	jz	hcont
%else
	GLOBAL	glfsr_crypt	; glfsr_crypt (uchar *dst, uchar *src, int len, int key)

glfsr_crypt:
	push	ebp
	mov	ebp, esp
	pusha
	mov	edi, dword [ebp + 8]
	mov	esi, dword [ebp + 12]
	mov	ecx, dword [ebp + 16]
	mov	ebx, dword [ebp + 20]
%endif

; esi = source
; edi = dest (can overlap/be the same) with source
; ecx = number of bytes
; ebx = 32 bit key

	xor	edx, edx
glls:	mov	eax, 8
gll0:	shrd	edx, ebx, 1		; edx = >>output, ebx = |lfsr|
	shr	ebx, 1			; cf = lfsr[0]
	jnc	gll1			; == 1 ?
	xor	ebx, 0xc0000057		; binary tap sequence
gll1:	dec	eax
	jnz	gll0
	shr	edx, 32 - 8		; take highest 8 bits
	lodsb
	xor	al, dl
	stosb
	dec	ecx
	jnz	glls

%ifdef IN_STUB
hcont:	popa
	popf
	ret

hunk:	call	hret
%else
%ifdef CONSERVE_SPACE
	popa
	pop	ebp
	ret	16
%else
	popa
	pop	ebp			; only restore, no stack space
	ret
%endif
%endif