;++ ; Copyright (c) 1996, 1997 Microsoft Corporation ; ; Copyright (C) 1987 RSA Data Security, Inc. Created 1987. ; This is an unpublished work protected as such under copyright law. ; This work contains proprietary, confidential, and trade secret information ; of RSA Data Security, Inc. Use, disclosure, or reproduction without the ; express written authorization of RSA Data Security, Inc., is prohibited. ; ; ; Abstract: ; ; This code is derived from Scott Field's optimized implementation of the ; RC4 algorithm. Following changes were made. ; 1. rc4_key and rc4 functionality have been merged ; 2. Does not preserve any registers--does not use stack ; 3. Does not take any parameters--everything is hardcoded ; 4. Does not update the indicies in the key structure at end ; 5. Separate input/output buffers ; ; Environment: ; ; 32-bit Protected Mode ; ;-- ; ; RC4 key expansion functionality (rc4_key) ; mov eax, 03020100H ; initial fill value mov ecx, 64 ; loop iteration count mov esi, ROMDEC_KEYSTRUCT mov edx, esi ; ; for (a=0x03020100,i=0;ii = 0; mov BYTE PTR [esi+257], cl ; Key->j = 0; xor ebx, ebx ; while (i < RC4_TABLESIZE) { permute_loop: ; ti = p[i]; ; tk = K[k]; ; j += tk; ; j += ti; ; j &= (RC4_TABLESIZE - 1); ; tj = p[j]; ; k++; ; p[i] = tj; ; i++; ; p[j] = ti; xor edx, edx ; avoid p6 partial stall xor eax, eax ; avoid p6 partial stall mov dl, BYTE PTR [esi+edi] mov al, BYTE PTR [ecx+ebp] add bl, al ; add ebx, eax inc ecx add bl, dl ; add ebx, edx inc edi ; if (k == m) ; and ebx, 0FFh ; and not needed due to 8 bit add mov al, BYTE PTR [esi+ebx] mov BYTE PTR [esi+edi-1], al cmp ecx, ROMDEC_KEYSIZE mov BYTE PTR [esi+ebx], dl jne skip_zero_k xor ecx, ecx skip_zero_k: cmp edi, 256 jb permute_loop ; ; RC4 encryption functionality (rc4) ; xor ecx, ecx xor edx, edx xor edi, edi xor eax, eax mov esi, ROMDEC_KEYSTRUCT ; p = Key->S mov ebp, ROMDEC_BUFFERSIZE ; byte count mov cl, BYTE PTR [esi+256] ; i = Key->i mov dl, BYTE PTR [esi+257] ; j = Key->j rc4_loop: inc cl ; i ++ ; i &= (RC4_TABLESIZE-1) mov al, BYTE PTR [ecx+esi] ; t = p[i] add dl, al ; j += t ; j &= (RC4_TABLESIZE-1) mov bl, BYTE PTR [edx+esi] ; pickup p[j] mov BYTE PTR [ecx+esi], bl ; p[i] = p[j] mov BYTE PTR [edx+esi], al ; p[j] = t (potential bank conflict) ; ; *outputbuffer++ = *inputbuffer++ ^ p[( p[i] + t) & (RC4_TABLESIZE-1) ]; ; add al, bl ; (t += p[i]) & RC4_TABLESIZE-1 mov bl, BYTE PTR ROMDEC_INPUTBUFFER[edi] ; get byte from input buffer mov al, BYTE PTR [eax+esi] ; pickup p[t] xor bl, al mov BYTE PTR ROMDEC_OUTPUTBUFFER[edi], bl ; write byte to output buffer inc edi ; bufferindex++ dec ebp ; loop until no input left to process jnz rc4_loop rc4_done: