ReactOS 0.4.17-dev-1005-g171e1de
rc4.c File Reference
#include "precomp.h"
Include dependency graph for rc4.c:

Go to the source code of this file.

Functions

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRc4Init (_Out_ PSYMCRYPT_RC4_STATE pState, _In_reads_(cbKey) PCBYTE pbKey, _In_ SIZE_T cbKey)
 
VOID SYMCRYPT_CALL SymCryptRc4Crypt (_Inout_ PSYMCRYPT_RC4_STATE pState, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, _In_ SIZE_T cbData)
 
VOID SYMCRYPT_CALL SymCryptRc4Selftest (void)
 

Variables

static const BYTE rc4KatAnswer [3] = { 0x71, 0x46, 0x92 }
 

Function Documentation

◆ SymCryptRc4Crypt()

VOID SYMCRYPT_CALL SymCryptRc4Crypt ( _Inout_ PSYMCRYPT_RC4_STATE  pState,
_In_reads_(cbData) PCBYTE  pbSrc,
_Out_writes_(cbData) PBYTE  pbDst,
_In_ SIZE_T  cbData 
)

Definition at line 82 of file rc4.c.

87{
88 SIZE_T i;
89 SIZE_T j;
92 PCBYTE pbSrcEnd = pbSrc + cbData;
93
95
96 i = pState->i;
97 j = pState->j;
98
99 //
100 // I tried to unroll this loop 4x and use a single 32-bit operation to XOR the key
101 // stream with the data. This actually makes the code slower by 1 c/B on a Core 2.
102 // I suspect that that is because the instruction decoders are the bottleneck, and
103 // a small loop can be run out of the uop queue which bypasses the instruction decoders.
104 // A larger loop has to be decoded every time, and that slows things down.
105 // The theoretical gain of unrolling the loop is less than 1 c/B,
106 // and as Core 2 and derived CPUs are the most commonly used CPUs by our customers,
107 // it is not worthwhile to persue this further.
108 //
109 // - Niels Ferguson (niels) 2010-10-11
110 //
111
112 while( pbSrc < pbSrcEnd )
113 {
114 //
115 // Our i value is already incremented
116 //
117 Ti = pState->S[i];
118 j = (j + Ti ) & 0xff;
119 Tj = pState->S[j];
120 pState->S[i] = Tj;
121 pState->S[j] = Ti;
122 *pbDst = (BYTE) (*pbSrc ^ pState->S[(Ti + Tj) & 0xff]);
123
124 i = (i + 1) & 0xff;
125
126 pbSrc++;
127 pbDst++;
128 }
129
130 pState->i = (BYTE) i;
131 pState->j = (BYTE) j;
132}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
PCBYTE pbSrc
BYTE SYMCRYPT_RC4_S_TYPE
PCBYTE PBYTE SIZE_T cbData
PCBYTE PBYTE pbDst
PSYMCRYPT_COMMON_HASH_STATE pState
const BYTE * PCBYTE
#define SYMCRYPT_CHECK_MAGIC(p)
ULONG_PTR SIZE_T
Definition: typedefs.h:80
unsigned char BYTE
Definition: xxhash.c:193

Referenced by encrypt_stream_impl(), and SymCryptRc4Selftest().

◆ SymCryptRc4Init()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRc4Init ( _Out_ PSYMCRYPT_RC4_STATE  pState,
_In_reads_(cbKey) PCBYTE  pbKey,
_In_ SIZE_T  cbKey 
)

Definition at line 15 of file rc4.c.

19{
20 SIZE_T i;
21 SIZE_T j;
22 BYTE keyBuf[256];
23 SIZE_T keyIdx;
24
26
27 if( cbKey > 256 || cbKey == 0 )
28 {
29 return SYMCRYPT_WRONG_KEY_SIZE;
30 }
31
32 //
33 // Make a copy of the key to obey the read-once rule.
34 // This is a case where it looks safe to break the read-once
35 // rule, but it isn't. RC4 with very long keys (e.g. 256 bytes)
36 // is actually very vulnerable against related-key attacks.
37 // One obvious precaution is to limit the length of the RC4 key,
38 // which one of the layers above us might do.
39 // Allowing the key bytes to change as we read them negates
40 // this countermeasure.
41 //
42 memcpy( keyBuf, pbKey, cbKey );
43
44 for( i=0; i<256; i++ )
45 {
47 }
48
49 j = 0;
50 keyIdx = 0;
51 for( i=0; i<256; i++ )
52 {
53
54 T = pState->S[i];
55 j = (j + T + keyBuf[keyIdx]) & 0xff;
56 pState->S[i] = pState->S[j];
57 pState->S[j] = T;
58 keyIdx++;
59 if( keyIdx == cbKey )
60 {
61 keyIdx = 0;
62 }
63 }
64
65 //
66 // We store the i value already incremented for the next byte.
67 // This seems to allow better instruction sequencing interleaving in the actual en/decrypt loop
68 //
69 pState->i = 1;
70 pState->j = 0;
71
73
74 SymCryptWipe( keyBuf, cbKey );
75
76 return SYMCRYPT_NO_ERROR;
77}
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define T(num)
Definition: thunks.c:311
VOID SYMCRYPT_CALL SymCryptWipe(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
Definition: libmain.c:137
PCBYTE pbKey
PCBYTE SIZE_T cbKey
#define SYMCRYPT_SET_MAGIC(p)

Referenced by setup_key_impl(), and SymCryptRc4Selftest().

◆ SymCryptRc4Selftest()

VOID SYMCRYPT_CALL SymCryptRc4Selftest ( void  )

Definition at line 140 of file rc4.c.

141{
142 BYTE buf[3];
144
146
148
149 SymCryptInjectError( buf, sizeof( buf ) );
150
151 if( memcmp( buf, rc4KatAnswer, sizeof( buf )) != 0 )
152 {
153 SymCryptFatal( 'rc4 ' );
154 }
155
156}
VOID SYMCRYPT_CALL SymCryptRc4Crypt(_Inout_ PSYMCRYPT_RC4_STATE pState, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, _In_ SIZE_T cbData)
Definition: rc4.c:82
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRc4Init(_Out_ PSYMCRYPT_RC4_STATE pState, _In_reads_(cbKey) PCBYTE pbKey, _In_ SIZE_T cbKey)
Definition: rc4.c:15
static const BYTE rc4KatAnswer[3]
Definition: rc4.c:135
static int state
Definition: maze.c:121
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
VOID SYMCRYPT_CALL SymCryptInjectError(PBYTE pbData, SIZE_T cbData)
const BYTE SymCryptTestKey32[32]
Definition: selftest.c:10
const BYTE SymCryptTestMsg3[3]
Definition: selftest.c:8
_Analysis_noreturn_ VOID SYMCRYPT_CALL SymCryptFatal(UINT32 fatalCode)
SYMCRYPT_MAGIC_FIELD SYMCRYPT_RC4_STATE

Variable Documentation

◆ rc4KatAnswer

const BYTE rc4KatAnswer[3] = { 0x71, 0x46, 0x92 }
static

Definition at line 135 of file rc4.c.

Referenced by SymCryptRc4Selftest().