RC4
Algorithm creator(s)
Ron Rivest / RSA Laboratories
PB author(s)
Scott Slater
Description
RC4 is a variable key-size stream cipher with byte-oriented operations. The algorithm is based on the use of a random permutation.
Note
Susceptible to bit-flipping attacks; RC4 has no error detection and changing 1 byte in the ciphertext doesn't affect any other data except that byte
Source
https://forum.powerbasic.com/forum/user-to-user-discussions/source-code/23907-asm-encryption-base64-routines
See also
n/a
Source Code
Download source code file rc4.bas (Right-click -> "Save as ...")
' ---------------------------------------------------------
' RC4 Encrypt/Decrypt Routine: Returns 1 on Error,
' 0 for Success
'
' nLen = Input String Len. NOTE: Buffer Lengths Must Be
' equal to or greater than this size. We want To be able
' to encrypt Ascii Zero's so we can't look for These for
' the end of the string mark as you normally would with
' this type of data.
'
' NOTE: If you are calling from PB you are better off using
' the wrapper function below to use BASIC Strings.
' ---------------------------------------------------------
Function EnDeCrypt Alias "EnDeCrypt"(InString As Asciiz, Passwd As Asciiz, _
OutString As Asciiz, ByVal nLen As Dword) Export As Long
Local S As Asciiz * 256
Local K As Asciiz * 256
Local rtn As Long
! push ebx ; save ebx
! push esi ; save esi
! push edi ; save edi
! mov esi, InString ; Input String Address
! and esi, esi ; null pointer check
! jz EnDeCryptDone ; exit function
! mov edi, OutString ; Output String Address
! and edi, edi ; null pointer check
! jz EnDeCryptDone ; exit function
! mov edx, Passwd ; Password String Address
! and edx, edx ; null pointer check
! jz EnDeCryptDone ; exit function
! push esi ; save it for temp use
! push edi ; save it for temp use
! push edx ; save original pw address
! xor eax, eax ; zero eax
! lea esi, S ; address of S
! lea edi, K ; address of K
EnDeCryptInitS:
! mov [esi+eax], al ; store char in S
! mov bl, [edx] ; get byte from password
! cmp bl, 0 ; see if its a null terminator
! je EnDeCryptFixPw ; if so adjust it
! mov [edi+eax], bl ; store char in K
! inc edx ; increment pw pointer
! inc eax ; increment ascii pointer
! cmp eax, 256 ; see if we're done
! jl EnDeCryptInitS ; get next character
! jmp EnDeCryptCreateTable ; go to next step
EnDeCryptFixPw:
! pop edx ; get starting address of pw
! push edx ; save it again
! mov bl, [edx] ; get first char again
! mov [edi+eax], bl ; store it in K
! inc edx ; increment pw pointer
! inc eax ; increment ascii pointer
! cmp eax, 256 ; see if we're done
! jl EnDeCryptInitS ; get next character
EnDeCryptCreateTable:
! xor ecx, ecx ; zero ecx
! xor edx, edx ; zero edx
EnDeCryptTableLoop:
! mov al, [esi+ecx] ; get S char into al
! mov ah, [edi+ecx] ; get K char into ah
! add al, ah ; add them together
! mov ah, dl ; dl to ah
! add al, ah ; add them together
! mov edx, eax ; save it to edx
! and edx, 255 ; filter off high bits
! mov bl, [esi+ecx] ; get S char to bl
! mov al, [esi+edx] ; get K char to al
! mov [esi+ecx], al ; swap the values
! mov [esi+edx], bl ; swap the values
! inc ecx ; increment counter
! cmp ecx, 256 ; see if we're done
! jl EnDeCryptTableLoop ; get next character
! pop edx ; restore password address
! pop edi ; restore Output address
! pop esi ; restore Input address
! xor eax, eax ; zero eax
! xor ebx, ebx ; zero ebx
! xor ecx, ecx ; zero ecx
! xor edx, edx ; zero edx
EnDeCryptMainLoop:
! mov eax, 1234 ; normal exit code checked on exit
! cmp edx, nLen ; See if we've reached the end yet
! jge EnDeCryptDone ; if so we're done
! mov al, [esi+edx] ; get char from input
! inc ch ; increment ch
! and ch, 255 ; range 0-255
! push esi ; save esi
! lea esi, S ; address of S
! push eax ; save eax
! push ebx ; save ebx
! xor eax, eax ; zero eax
! mov ah, ch ; get ch
! shr eax, 8 ; move to al
! mov ebx, eax ; copy it to ebx
! mov al, [esi+ebx] ; get byte
! add cl, al ; add them up
! and cl, 255 ; range 0-255
! pop ebx ; restore ebx
! xor eax, eax ; zero eax
! mov al, cl ; cl to al
! mov bl, [esi+eax] ; swap table bytes
! mov al, ch ; ch to al
! mov bh, [esi+eax] ; swap table bytes
! mov [esi+eax], bl ; swap table bytes
! mov al, cl ; cl to al
! mov [esi+eax], bh ; swap table bytes
! pop eax ; restore eax
! add bl, bh ; add the bytes together
! and ebx, 255 ; range 0-255
! mov bh, [esi+ebx] ; get xor Var
! shr ebx, 8 ; move it to bl
! xor al, bl ; xor the value
! mov [edi+edx], al ; store the encrypted char
! pop esi ; restore input address
! inc edx ; increment character counter
! jmp EnDeCryptMainLoop ; get next character
EnDeCryptDone:
! cmp eax, 1234 ; see if our normal exit code
! je EnDeCryptExitLab ; got us here, if so exit
! mov eax, 1 ; if not return error code
! mov rtn, eax ; to caller
EnDeCryptExitLab:
! pop edi ; restore edi
! pop esi ; restore esi
! pop ebx ; restore ebx
Function = rtn
End Function
' ---------------------------------------------------------
' Wrapper Function that Calls EnDeCrypt and handles
' Conversions of Input And output to regular basic
' style strings instead of Asciiz.
'
' Returns: String on Success
' Empty String on Error
' ---------------------------------------------------------
Function CryptStr Alias "CryptStr" (StringIn As String, Pw As String) _
Export As String
Local pBuff As String
Local oBuff As String
pBuff = Pw & Chr$(0) ' pad pw with a chr 0
oBuff = Space$(Len(StringIn)) ' set outbuff len
! push ebx ; save ebx
! mov eax, StringIn ; Get Input Buffer Handle to eax
! mov eax, [eax] ; get address of data
! and eax, eax ; null pointer check
! jz CryptStrDone ; leave the function
! lea ebx, pBuff ; pBuff's handle to ebx
! mov ebx, [ebx] ; pBuff's address to ebx
! lea ecx, oBuff ; oBuff's handle to ecx
! mov ecx, [ecx] ; oBuff's address to ecx
! mov edx, [eax-4] ; StringIn's Length to edx
! push edx ; last parameter for call
! push ecx ; 3rd parameter for call
! push ebx ; 2nd parameter for call
! push eax ; 1st paramter for call
! call EnDeCrypt ; call the master function
! cmp eax, 0 ; make sure there were no errors
! jne CryptStrDone ; if so then exit
Function = oBuff ' set output
CryptStrDone:
! pop ebx ; restore ebx
End Function