flat assembler
Message board for the users of flat assembler.
Index
> Macroinstructions > RC4 Encryption  Need It 
Author 

vid 13 Nov 2007, 14:44
Quote: How can I use RC4 Encryption in FASM without a 3rd party .dll file?  use third party .LIB file  use third party .OBJ file  include third party sources of RC4 encryption  (worst) write your own implementation of encryption 

13 Nov 2007, 14:44 

f0dder 13 Nov 2007, 14:49
Unless you're bound by legacy stuff, choose a more secure algorithm.


13 Nov 2007, 14:49 

JMGK 14 Nov 2007, 00:09
hi,
rc4 is pretty easy to code... From Bruce Schneider´s Applied Cryptography: Quote:
regards, jmgk 

14 Nov 2007, 00:09 

ziral2088 14 Jun 2010, 19:50
Does anyone do it already? Couse I need it too, maybe someone already done it


14 Jun 2010, 19:50 

cod3b453 15 Jun 2010, 08:27
I seem to have lost the RC4 implementation but I do have a macro for it at compile time. Unfortunately I wrote this a long time ago  it will trash 512 bytes at the point where you use RC4Encode.
example.asm Code: include 'rc4.ash' A: db 'some data',0 some_code: mov esi,eax mov ebx,[esi] ret B: RC4Encode A,B,'the rc4 key' rc4.ash Code: macro RC4Encode __rc4start,__rc4end,__rc4key { __rc4location = 0 __rc4len = 0 __rc4keylen = 0 __rc4kboxchar = 0 __rc4sboxchar = 0 __rc4mix = 0 __rc4swap1 = 0 __rc4swap2 = 0 __rc4counter = 0 __rc4xor = 0 __rc4data = 0 __rc4location = $ __rc4len = (__rc4end  __rc4start) virtual at 0 db __rc4key __rc4keylen = $ end virtual repeat 0x100 virtual at 0 db __rc4key load __rc4kboxchar byte from ((%  1) mod __rc4keylen) end virtual db __rc4kboxchar end repeat repeat 0x100 db (%  1) end repeat repeat 0x100 load __rc4kboxchar byte from (__rc4location + (%  1)) load __rc4sboxchar byte from (__rc4location + (%  1) + 0x100) __rc4mix = ((__rc4mix + __rc4kboxchar + __rc4sboxchar) mod 256) load __rc4swap1 byte from (__rc4location + __rc4mix + 0x100) load __rc4swap2 byte from (__rc4location + (%  1) + 0x100) store byte __rc4swap2 at (__rc4location + __rc4mix + 0x100) store byte __rc4swap1 at (__rc4location + (%  1) + 0x100) end repeat __rc4mix = 0 repeat __rc4len __rc4counter = (% mod 256) load __rc4swap1 byte from (__rc4location + __rc4counter + 0x100) __rc4mix = ((__rc4mix + __rc4swap1) mod 256) load __rc4swap2 byte from (__rc4location + __rc4mix + 0x100) store byte __rc4swap2 at (__rc4location + __rc4counter + 0x100) store byte __rc4swap1 at (__rc4location + __rc4mix + 0x100) load __rc4xor byte from (__rc4location + ((__rc4swap1 + __rc4swap2) mod 256) + 0x100) load __rc4data byte from (__rc4start + (%  1)) __rc4enc = (__rc4data xor __rc4xor) store byte __rc4enc at (__rc4start + (%  1)) end repeat repeat 0x200 store byte 0x00 at (__rc4location + (%  1)) end repeat } 

15 Jun 2010, 08:27 

ziral2088 15 Jun 2010, 17:38
Thanks!
Here is your converted code. No trash at all So fasm now can crypt in RC4. Speed is very low, but it works. Code: macro CryptRC4 __key , __start , __size { __rc4len = 0 __rc4keylen = 0 __rc4kboxchar = 0 __rc4sboxchar = 0 __rc4mix = 0 __rc4swap1 = 0 __rc4swap2 = 0 __rc4counter = 0 __rc4xor = 0 __rc4data = 0 virtual at 0 db __key __rc4keylen = $ end virtual rept 0x100 counter \{ virtual at 0 db __key load __rc4kboxchar byte from ((counter  1) mod __rc4keylen) end virtual __rc4kboxchar.\#counter = __rc4kboxchar \} rept 0x100 counter \{ __rc4sboxchar.\#counter = counter  1 \} rept 0x100 counter \{ __rc4mix = ((__rc4mix + __rc4kboxchar.\#counter + __rc4sboxchar.\#counter) mod 256) rept 0x100 counter2 \\{ if __rc4mix = ( counter2  1 ) __rc4swap1 = __rc4sboxchar.\\#counter2 end if \\} __rc4swap2 = __rc4sboxchar.\#counter rept 0x100 counter2 \\{ if __rc4mix = ( counter2  1 ) __rc4sboxchar.\\#counter2 = __rc4swap2 end if \\} __rc4sboxchar.\#counter = __rc4swap1 \} __rc4mix = 0 repeat __size __rc4counter = (% mod 256) rept 0x100 counter2 \{ if __rc4counter = (counter2  1) __rc4swap1 = __rc4sboxchar.\#counter2 end if \} __rc4mix = ((__rc4mix + __rc4swap1) mod 256) rept 0x100 counter2 \{ if __rc4mix = ( counter2  1 ) __rc4swap2 = __rc4sboxchar.\#counter2 end if \} rept 0x100 counter2 \{ if __rc4counter = ( counter2  1 ) __rc4sboxchar.\#counter2 = __rc4swap2 end if \} rept 0x100 counter2 \{ if __rc4mix = ( counter2  1 ) __rc4sboxchar.\#counter2 = __rc4swap1 end if \} rept 0x100 counter2 \{ if ((__rc4swap1 + __rc4swap2) mod 256) = ( counter2  1 ) __rc4xor = __rc4sboxchar.\#counter2 end if \} load __rc4data byte from (__start + (%  1)) __rc4enc = (__rc4data xor __rc4xor) store byte __rc4enc at (__start + (%  1)) end repeat } 

15 Jun 2010, 17:38 

cod3b453 18 Jun 2010, 08:36
Well, I prefer that it doesn't trash stuff, so in my eyes that is much better, thanks


18 Jun 2010, 08:36 

baldr 18 Jun 2010, 23:30
There is a trick that allows data to be copied between addressing spaces. It uses numerical constants.
Code: macro copy name*, size*, address* { rept size/8 i:0 \{ rept 1 j:i*8 \\{ load name\\#j qword from address+j \\} \} rept 1((size) mod 8  1) shr 63 \{; something left local fragment rept 1 i:(size) and 8 \\{; calculate suffix name\\#i = 0; initialize accumulator rept (size) mod 8 j:0 \\\{ load fragment byte from address+i+j name\\#i = name\\#i or fragment shl (8*j) \\\} \\} \} } macro paste name*, size*, address { rept (size)/8 i:0 \{ rept 1 j:i*8 \\{ match any, address \\\{ store qword name\\#j at address+j \\\} match , address \\\{ dq name\\#j \\\} \\} \} rept 1 i:(size) and 8 \{; calculate suffix rept (size) mod 8 j:0 \\{; something left match any, address \\\{ store byte name\\#i shr (8*j) and 0xFF at address+i+j \\\} match , address \\\{ db name\\#i shr (8*j) and 0xFF \\\} \\} \} } Code: virtual a db 6 dup 'a' copy A, 5, a; A is a name for copy of 5 bytes starting from label a end virtual virtual b db 10 dup 'b' paste A, 3, b+1; use our copy A to patch 3 bytes at b+1 copy B, 10, b; B is another copy end virtual times 256 db '.' paste A, 3, 16 paste B, 7, 32 paste A, 5; without address argument macro simply pastes specified number of bytes here paste B, 10 Code: macro RC4 _key, start, len { copy plaintext, len, start virtual key db _key key.len = $key s: times 256 db %1 i equ (%1) j = 0 repeat 256 load s_i from s+i load k_i from key+i mod key.len j = (j+s_i+k_i) mod 256 load s_j from s+j store s_i at s+j store s_j at s+i end repeat i equ (% mod 256) j = 0 b: paste plaintext, len repeat len load s_i from s+i j = (j+s_i) mod 256 load s_j from s+j store s_i at s+j store s_j at s+i load k from s+(s_i+s_j) mod 256 load p from b+%1 store p xor k at b+%1 end repeat copy ciphertext, len, b end virtual paste ciphertext, len, start } 

18 Jun 2010, 23:30 

cod3b453 19 Jun 2010, 08:08
Very nice, thanks baldr
I wondered yesterday if constants were the answer, seems to work nicely. 

19 Jun 2010, 08:08 

baldr 19 Jun 2010, 13:57
cod3b453,
I'm thinking about mod that can define arbitrary length binary constants like Code: virtual repeat 256 remainder = %1 repeat 8 if remainder and 1 remainder = remainder shr 1 xor 0xEDB88320 else remainder = remainder shr 1 end if end repeat dd remainder end repeat load crc_tab[$$$] from $$ end virtual ; some code/data block crc = 0 repeat $$$ load b from %1 load dword remainder from crc_tab[4*(b xor crc and 0xFF)] crc = crc shr 8 xor remainder end repeat dd crc; now the extended code/data block has zero remainder 

19 Jun 2010, 13:57 

< Last Thread  Next Thread > 
Forum Rules:

Copyright © 19992020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.
Website powered by rwasa.