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

Go to the source code of this file.

Macros

#define OFFSET_MASK   (((UINT64)1 << 38) - 1)
 
#define CHACHA_QUARTERROUND(a, b, c, d)
 

Functions

VOID SYMCRYPT_CALL SymCryptChaCha20CryptBlocks (_Inout_ PSYMCRYPT_CHACHA20_STATE pState, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, SIZE_T cbData)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptChaCha20Init (_Out_ PSYMCRYPT_CHACHA20_STATE pState, _In_reads_(cbKey) PCBYTE pbKey, _In_ SIZE_T cbKey, _In_reads_(cbNonce) PCBYTE pbNonce, SIZE_T cbNonce, UINT64 offset)
 
VOID SYMCRYPT_CALL SymCryptChaCha20SetOffset (_Inout_ PSYMCRYPT_CHACHA20_STATE pState, UINT64 offset)
 
VOID SYMCRYPT_CALL SymCryptChaCha20Crypt (_Inout_ PSYMCRYPT_CHACHA20_STATE pState, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, SIZE_T cbData)
 
VOID SYMCRYPT_CALL SymCryptChaCha20Selftest (void)
 

Variables

static const BYTE chacha20KatAnswer [3] = { 0xb5, 0xe0, 0x54 }
 

Macro Definition Documentation

◆ CHACHA_QUARTERROUND

#define CHACHA_QUARTERROUND (   a,
  b,
  c,
  d 
)
Value:
{ \
a += b; d ^= a; d = ROL32( d, 16 ); \
c += d; b ^= c; b = ROL32( b, 12 ); \
a += b; d ^= a; d = ROL32( d, 8 ); \
c += d; b ^= c; b = ROL32( b, 7 ); \
}
const GLubyte * c
Definition: glext.h:8905
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
#define d
Definition: ke_i.h:81
#define a
Definition: ke_i.h:78
#define c
Definition: ke_i.h:80
#define b
Definition: ke_i.h:79

Definition at line 147 of file chacha20.c.

◆ OFFSET_MASK

#define OFFSET_MASK   (((UINT64)1 << 38) - 1)

Definition at line 22 of file chacha20.c.

Function Documentation

◆ SymCryptChaCha20Crypt()

VOID SYMCRYPT_CALL SymCryptChaCha20Crypt ( _Inout_ PSYMCRYPT_CHACHA20_STATE  pState,
_In_reads_(cbData) PCBYTE  pbSrc,
_Out_writes_(cbData) PBYTE  pbDst,
SIZE_T  cbData 
)

Definition at line 69 of file chacha20.c.

74{
75 UINT32 blockOffset;
76 SIZE_T nBytes;
77
78 blockOffset = pState->offset & 0x3f;
79
80 // If the offset is in the middle of the block, we first crypt until the end
81 // of the block
82 if( blockOffset != 0 )
83 {
84 if( !pState->keystreamBufferValid )
85 {
86 // Generate a block of key stream
87 SymCryptWipe( &pState->keystream[0], 64 );
89 &pState->keystream[0],
90 &pState->keystream[0],
91 64 );
92 pState->offset -= 64; // Don't update the offset yet
93 }
94
95 nBytes = 64 - blockOffset; // # bytes in buffer starting at offset
96 if( cbData < nBytes )
97 {
98 // We don't use the generated block to the end. The buffer will be valid
99 // at the end as the offset won't advance beyond the block.
100 nBytes = cbData;
101 pState->keystreamBufferValid = TRUE;
102 } else {
103 // We'll use the rest of the generated block. After that the key stream
104 // buffer won't be valid as the offset will advance beyond it.
105 pState->keystreamBufferValid = FALSE;
106 }
107
108 SymCryptXorBytes( pbSrc, &pState->keystream[ blockOffset ], pbDst, nBytes );
109 pbSrc += nBytes;
110 pbDst += nBytes;
111 cbData -= nBytes;
112 pState->offset += nBytes;
113 }
114
115 // Here: pbSrc, pbDst, cbData, and pState->offset all in sync
116 // and either cbData == 0 or offset is at a block boundary
117
118 if( cbData >= 64 )
119 {
120 nBytes = cbData & ~0x3f;
122 pbSrc += nBytes;
123 pbDst += nBytes;
124 cbData -= nBytes;
125 }
126
127 if( cbData > 0 )
128 {
129 // Generate a block of key stream
130 SymCryptWipe( &pState->keystream[0], 64 );
132 &pState->keystream[0],
133 &pState->keystream[0],
134 64 );
135 pState->offset -= 64; // Don't update the offset yet
136 pState->keystreamBufferValid = TRUE;
137
138 SymCryptXorBytes( pbSrc, &pState->keystream[0], pbDst, cbData );
139 pState->offset += cbData;
140 // The following updates are correct but not needed
141 // pbSrc += cbData;
142 // pbDst += cbData;
143 // cbData -= cbData;
144 }
145}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
VOID SYMCRYPT_CALL SymCryptChaCha20CryptBlocks(_Inout_ PSYMCRYPT_CHACHA20_STATE pState, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, SIZE_T cbData)
Definition: chacha20.c:156
VOID SYMCRYPT_CALL SymCryptWipe(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
Definition: libmain.c:137
VOID SYMCRYPT_CALL SymCryptXorBytes(_In_reads_(cbBytes) PCBYTE pbSrc1, _In_reads_(cbBytes) PCBYTE pbSrc2, _Out_writes_(cbBytes) PBYTE pbResult, SIZE_T cbBytes)
Definition: libmain.c:236
PCBYTE pbSrc
PCBYTE PBYTE SIZE_T cbData
PCBYTE PBYTE pbDst
PSYMCRYPT_COMMON_HASH_STATE pState
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t UINT32
Definition: typedefs.h:59

Referenced by SymCryptChaCha20Poly1305Decrypt(), SymCryptChaCha20Poly1305Encrypt(), and SymCryptChaCha20Selftest().

◆ SymCryptChaCha20CryptBlocks()

VOID SYMCRYPT_CALL SymCryptChaCha20CryptBlocks ( _Inout_ PSYMCRYPT_CHACHA20_STATE  pState,
_In_reads_(cbData) PCBYTE  pbSrc,
_Out_writes_(cbData) PBYTE  pbDst,
SIZE_T  cbData 
)

Definition at line 156 of file chacha20.c.

161{
163 UINT32 s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15;
164 int i;
165
166 counter = (UINT32)(pState->offset >> 6);
167
168 while( cbData >= 64 )
169 {
170 // Initialize the state
171 s0 = 0x61707865;
172 s1 = 0x3320646e;
173 s2 = 0x79622d32;
174 s3 = 0x6b206574;
175 s4 = pState->key[0];
176 s5 = pState->key[1];
177 s6 = pState->key[2];
178 s7 = pState->key[3];
179 s8 = pState->key[4];
180 s9 = pState->key[5];
181 s10 = pState->key[6];
182 s11 = pState->key[7];
183 s12 = counter;
184 s13 = pState->nonce[0];
185 s14 = pState->nonce[1];
186 s15 = pState->nonce[2];
187
188 for( i=0; i<10; i++ )
189 {
190 CHACHA_QUARTERROUND( s0 , s4 , s8 , s12 );
191 CHACHA_QUARTERROUND( s1 , s5 , s9 , s13 );
192 CHACHA_QUARTERROUND( s2 , s6 , s10, s14 );
193 CHACHA_QUARTERROUND( s3 , s7 , s11, s15 );
194
195 CHACHA_QUARTERROUND( s0 , s5 , s10, s15 );
196 CHACHA_QUARTERROUND( s1 , s6 , s11, s12 );
197 CHACHA_QUARTERROUND( s2 , s7 , s8 , s13 );
198 CHACHA_QUARTERROUND( s3 , s4 , s9 , s14 );
199 }
200
201 s0 += 0x61707865;
202 s1 += 0x3320646e;
203 s2 += 0x79622d32;
204 s3 += 0x6b206574;
205 s4 += pState->key[0];
206 s5 += pState->key[1];
207 s6 += pState->key[2];
208 s7 += pState->key[3];
209 s8 += pState->key[4];
210 s9 += pState->key[5];
211 s10 += pState->key[6];
212 s11 += pState->key[7];
213 s12 += counter;
214 s13 += pState->nonce[0];
215 s14 += pState->nonce[1];
216 s15 += pState->nonce[2];
217
234
235 counter ++;
236 // If counter overflows then the caller has encrypted more than 256GB of data with a single stream, which is
237 // called out as being insecure. It is the caller's responsibility to avoid this!
238 pbSrc += 64;
239 pbDst += 64;
240 cbData -= 64;
241 pState->offset += 64;
242 }
243}
signed char s8
Definition: linux.h:51
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
struct S1 s1
#define CHACHA_QUARTERROUND(a, b, c, d)
Definition: chacha20.c:147
PCWSTR s2
Definition: shell32_main.h:38
#define SYMCRYPT_LOAD_LSBFIRST32(p)
Definition: symcrypt.h:299
#define SYMCRYPT_STORE_LSBFIRST32(p, v)
Definition: symcrypt.h:307

Referenced by SymCryptChaCha20Crypt().

◆ SymCryptChaCha20Init()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptChaCha20Init ( _Out_ PSYMCRYPT_CHACHA20_STATE  pState,
_In_reads_(cbKey) PCBYTE  pbKey,
_In_ SIZE_T  cbKey,
_In_reads_(cbNonce) PCBYTE  pbNonce,
SIZE_T  cbNonce,
UINT64  offset 
)

Definition at line 26 of file chacha20.c.

33{
34 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
35
36 if (cbKey != 32)
37 {
38 scError = SYMCRYPT_WRONG_KEY_SIZE;
39 goto cleanup;
40 }
41
42 if (cbNonce != 12)
43 {
44 scError = SYMCRYPT_WRONG_NONCE_SIZE;
45 goto cleanup;
46 }
47
49 SymCryptLsbFirstToUint32( pbNonce, &pState->nonce[0], 3 );
50
52
54 return scError;
55}
static void cleanup(void)
Definition: main.c:1335
GLintptr offset
Definition: glext.h:5920
FORCEINLINE VOID SYMCRYPT_CALL SymCryptLsbFirstToUint32(_In_reads_(4 *cuResult) PCBYTE pbData, _Out_writes_(cuResult) PUINT32 puResult, SIZE_T cuResult)
Definition: sc_lib.h:487
VOID SYMCRYPT_CALL SymCryptChaCha20SetOffset(_Inout_ PSYMCRYPT_CHACHA20_STATE pState, UINT64 offset)
Definition: chacha20.c:59
SYMCRYPT_ERROR
Definition: symcrypt.h:227
PCBYTE pbKey
PCBYTE SIZE_T cbKey
SIZE_T cbNonce

Referenced by SymCryptChaCha20Poly1305Decrypt(), SymCryptChaCha20Poly1305Encrypt(), and SymCryptChaCha20Selftest().

◆ SymCryptChaCha20Selftest()

VOID SYMCRYPT_CALL SymCryptChaCha20Selftest ( void  )

Definition at line 249 of file chacha20.c.

250{
251 BYTE buf[3];
253
257 0 );
258
260
261 SymCryptInjectError( buf, sizeof( buf ) );
262
263 if( memcmp( buf, chacha20KatAnswer, sizeof( buf )) != 0 )
264 {
265 SymCryptFatal( 'Cha2' );
266 }
267}
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
const BYTE SymCryptTestMsg16[16]
Definition: selftest.c:15
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
static const BYTE chacha20KatAnswer[3]
Definition: chacha20.c:245
VOID SYMCRYPT_CALL SymCryptChaCha20Crypt(_Inout_ PSYMCRYPT_CHACHA20_STATE pState, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, SIZE_T cbData)
Definition: chacha20.c:69
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptChaCha20Init(_Out_ PSYMCRYPT_CHACHA20_STATE pState, _In_reads_(cbKey) PCBYTE pbKey, _In_ SIZE_T cbKey, _In_reads_(cbNonce) PCBYTE pbNonce, SIZE_T cbNonce, UINT64 offset)
Definition: chacha20.c:26
_Analysis_noreturn_ VOID SYMCRYPT_CALL SymCryptFatal(UINT32 fatalCode)
SYMCRYPT_CHACHA20_STATE
unsigned char BYTE
Definition: xxhash.c:193

◆ SymCryptChaCha20SetOffset()

VOID SYMCRYPT_CALL SymCryptChaCha20SetOffset ( _Inout_ PSYMCRYPT_CHACHA20_STATE  pState,
UINT64  offset 
)

Definition at line 59 of file chacha20.c.

62{
63 pState->offset = offset;
64 pState->keystreamBufferValid = FALSE;
65}

Referenced by SymCryptChaCha20Init(), SymCryptChaCha20Poly1305Decrypt(), and SymCryptChaCha20Poly1305Encrypt().

Variable Documentation

◆ chacha20KatAnswer

const BYTE chacha20KatAnswer[3] = { 0xb5, 0xe0, 0x54 }
static

Definition at line 245 of file chacha20.c.

Referenced by SymCryptChaCha20Selftest().