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

Go to the source code of this file.

Functions

VOID SYMCRYPT_CALL SymCryptPoly1305ProcessBlocks (_Inout_ PSYMCRYPT_POLY1305_STATE pState, _In_reads_(cbData) PCBYTE pbData, SIZE_T cbData)
 
VOID SYMCRYPT_CALL SymCryptPoly1305 (_In_reads_(SYMCRYPT_POLY1305_KEY_SIZE) PCBYTE pbKey, _In_reads_(cbData) PCBYTE pbData, SIZE_T cbData, _Out_writes_(SYMCRYPT_POLY1305_RESULT_SIZE) PBYTE pbResult)
 
VOID SYMCRYPT_CALL SymCryptPoly1305Init (_Out_ PSYMCRYPT_POLY1305_STATE pState, _In_reads_(SYMCRYPT_POLY1305_KEY_SIZE) PCBYTE pbKey)
 
VOID SYMCRYPT_CALL SymCryptPoly1305Append (_Inout_ PSYMCRYPT_POLY1305_STATE pState, _In_reads_(cbData) PCBYTE pbData, SIZE_T cbData)
 
VOID SYMCRYPT_CALL SymCryptPoly1305Result (_Inout_ PSYMCRYPT_POLY1305_STATE pState, _Out_writes_(SYMCRYPT_POLY1305_RESULT_SIZE) PBYTE pbResult)
 
VOID SYMCRYPT_CALL SymCryptPoly1305Selftest (void)
 

Variables

static const BYTE poly1305Kat [16]
 

Function Documentation

◆ SymCryptPoly1305()

Definition at line 18 of file poly1305.c.

23{
25
29}
static int state
Definition: maze.c:121
VOID SYMCRYPT_CALL SymCryptPoly1305Result(_Inout_ PSYMCRYPT_POLY1305_STATE pState, _Out_writes_(SYMCRYPT_POLY1305_RESULT_SIZE) PBYTE pbResult)
Definition: poly1305.c:109
VOID SYMCRYPT_CALL SymCryptPoly1305Init(_Out_ PSYMCRYPT_POLY1305_STATE pState, _In_reads_(SYMCRYPT_POLY1305_KEY_SIZE) PCBYTE pbKey)
Definition: poly1305.c:33
VOID SYMCRYPT_CALL SymCryptPoly1305Append(_Inout_ PSYMCRYPT_POLY1305_STATE pState, _In_reads_(cbData) PCBYTE pbData, SIZE_T cbData)
Definition: poly1305.c:55
static const BYTE pbResult[]
PCBYTE pbKey
PCBYTE PBYTE SIZE_T cbData
SYMCRYPT_MAGIC_FIELD SYMCRYPT_POLY1305_STATE
PCBYTE pbData

Referenced by SymCryptPoly1305Selftest().

◆ SymCryptPoly1305Append()

VOID SYMCRYPT_CALL SymCryptPoly1305Append ( _Inout_ PSYMCRYPT_POLY1305_STATE  pState,
_In_reads_(cbData) PCBYTE  pbData,
SIZE_T  cbData 
)

Definition at line 55 of file poly1305.c.

59{
60 SIZE_T nBytes;
62
63 bytesInBuffer = pState->bytesInBuffer;
64 if( bytesInBuffer != 0 )
65 {
66 // We have a partial block in the buffer, keep filling the block
67
69 nBytes = 16 - bytesInBuffer;
70 if( nBytes > cbData )
71 {
72 nBytes = cbData;
73 }
74
75 memcpy( &pState->buf[bytesInBuffer], pbData, nBytes );
76 pbData += nBytes;
77 cbData -= nBytes;
78 bytesInBuffer += nBytes;
79
80 if( bytesInBuffer == 16 )
81 {
82 // Buffer is full, process it and empty the buffer
84 bytesInBuffer = 0;
85 }
86 pState->bytesInBuffer = bytesInBuffer;
87 }
88
89 if( cbData >= 16 )
90 {
91 // There are whole blocks to process
93 pbData += cbData;
94 cbData &= 0xf;
95 pbData -= cbData;
96 }
97
98 if( cbData > 0 )
99 {
100 // Copy remaining data to buffer
101 SYMCRYPT_ASSERT( cbData < 16 );
102 memcpy( &pState->buf[0], pbData, cbData );
103 pState->bytesInBuffer = cbData;
104 }
105}
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
VOID SYMCRYPT_CALL SymCryptPoly1305ProcessBlocks(_Inout_ PSYMCRYPT_POLY1305_STATE pState, _In_reads_(cbData) PCBYTE pbData, SIZE_T cbData)
Definition: poly1305.c:323
#define SYMCRYPT_ASSERT(_x)
Definition: symcrypt.h:10807
SIZE_T bytesInBuffer
PSYMCRYPT_COMMON_HASH_STATE pState
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by SymCryptChaCha20Poly1305ComputeTag(), and SymCryptPoly1305().

◆ SymCryptPoly1305Init()

Definition at line 33 of file poly1305.c.

36{
37 pState->r[0] = SYMCRYPT_LOAD_LSBFIRST32( pbKey + 0 ) & 0x0fffffff;
38 pState->r[1] = SYMCRYPT_LOAD_LSBFIRST32( pbKey + 4 ) & 0x0ffffffc;
39 pState->r[2] = SYMCRYPT_LOAD_LSBFIRST32( pbKey + 8 ) & 0x0ffffffc;
40 pState->r[3] = SYMCRYPT_LOAD_LSBFIRST32( pbKey + 12 ) & 0x0ffffffc;
41
46
47 // Set accumulator to zero
48 SymCryptWipeKnownSize( &pState->a[0], sizeof( pState->a ) );
49
50 pState->bytesInBuffer = 0;
51}
FORCEINLINE VOID SYMCRYPT_CALL SymCryptWipeKnownSize(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
#define SYMCRYPT_LOAD_LSBFIRST32(p)
Definition: symcrypt.h:299

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

◆ SymCryptPoly1305ProcessBlocks()

VOID SYMCRYPT_CALL SymCryptPoly1305ProcessBlocks ( _Inout_ PSYMCRYPT_POLY1305_STATE  pState,
_In_reads_(cbData) PCBYTE  pbData,
SIZE_T  cbData 
)

Definition at line 323 of file poly1305.c.

329{
330 UINT32 a0, a1, a2, a3, a4;
331 UINT32 r0, r1, r2, r3;
332 UINT64 t64;
333 UINT32 T3;
334 UINT32 V0, V1, V2;
335 UINT32 cy;
336 UINT32 U;
337 UINT32 t32;
338
339 r0 = pState->r[0];
340 r1 = pState->r[1];
341 r2 = pState->r[2];
342 r3 = pState->r[3];
343
344 a0 = pState->a[0];
345 a1 = pState->a[1];
346 a2 = pState->a[2];
347 a3 = pState->a[3];
348 a4 = pState->a[4];
349
350 // Here we have a4 < 6, but we sometimes decrement a4 to compensate for the
351 // 2^128 this function always adds. So we test a4 + 1 < 7
352 SYMCRYPT_ASSERT( a4 + 1 < 7 );
353
354 while( cbData >= 16 )
355 {
356 // Acc += data[0..15] + 2^128
357 t64 = (UINT64) a0 + SYMCRYPT_LOAD_LSBFIRST32( pbData + 0 );
358 a0 = (UINT32) t64;
359 t64 >>= 32;
360
361 t64 += (UINT64) a1 + SYMCRYPT_LOAD_LSBFIRST32( pbData + 4 );
362 a1 = (UINT32) t64;
363 t64 >>= 32;
364
365 t64 += (UINT64) a2 + SYMCRYPT_LOAD_LSBFIRST32( pbData + 8 );
366 a2 = (UINT32) t64;
367 t64 >>= 32;
368
369 t64 += (UINT64) a3 + SYMCRYPT_LOAD_LSBFIRST32( pbData + 12 );
370 a3 = (UINT32) t64;
371 t64 >>= 32;
372
373 a4 = (UINT32) t64 + a4 + 1; // +1 is the padding '1' which we always apply
374 SYMCRYPT_ASSERT( a4 < 8 );
375
376 pbData += 16;
377 cbData -=16;
378
379 // Compute S3
380 t64 = SYMCRYPT_MUL32x32TO64( a3, r0 )
381 + SYMCRYPT_MUL32x32TO64( a2, r1 )
382 + SYMCRYPT_MUL32x32TO64( a1, r2 )
383 + SYMCRYPT_MUL32x32TO64( a0, r3 );
384
385 SYMCRYPT_ASSERT( t64 < (1ULL << 62) );
386
387 T3 = (UINT32) t64;
388 t64 >>= 32;
389
390 // Compute T = S4 + floor(S3/2^32). We have the floor part in t64 already
391 // now add S4 to it
392 t64 += a4*r0 // this fits in 32 bits as r0 < 2^28 and a4 < 8
393 + SYMCRYPT_MUL32x32TO64( a3, r1 )
394 + SYMCRYPT_MUL32x32TO64( a2, r2 )
395 + SYMCRYPT_MUL32x32TO64( a1, r3 );
396
397 U = (UINT32) t64 & 3;
398 t64 &= ~3; // t64 = T4 here
399
400 // Compute S0 + T4 + T4/4, and V0
401 t64 += (t64 >> 2) + SYMCRYPT_MUL32x32TO64( a0, r0 );
402 V0 = (UINT32)t64;
403 cy = (UINT32)(t64 >> 32); // the carry from S0 to S1
404
405 // Compute S5
406 t64 = a4 * r1 + SYMCRYPT_MUL32x32TO64( a3, r2 ) + SYMCRYPT_MUL32x32TO64( a2, r3 );
407 t64 += t64 >> 2; // = S5 + S5/4
408
409 t64 += SYMCRYPT_MUL32x32TO64( a1, r0 ) + SYMCRYPT_MUL32x32TO64( a0, r1 );
410 // t64 = S1 + S5 + S5/4
411
412 t64 += cy;
413 V1 = (UINT32) t64;
414 cy = (UINT32)(t64 >> 32); // the carry from S1 to S2
415
416 // Compute S6
417 t64 = a4 * r2 + SYMCRYPT_MUL32x32TO64( a3, r3 );
418 t64 += t64 >> 2; // S6 + S6/4
419
420 // now add S2
421 t64 += SYMCRYPT_MUL32x32TO64( a2, r0 ) + SYMCRYPT_MUL32x32TO64( a1, r1 ) + SYMCRYPT_MUL32x32TO64( a0, r2 );
422 t64 += cy;
423 V2 = (UINT32) t64;
424 cy = (UINT32)(t64 >> 32);
425
426 // Finally T3 + S7 + S7/4
427 t32 = a4 * r3; // =S7, a 32-bit value
428 t32 += t32/4;
429 t64 = (UINT64) T3 + t32;
430 t64 += cy;
431
432 a0 = V0;
433 a1 = V1;
434 a2 = V2;
435 a3 = (UINT32) t64;
436 a4 = U + (UINT32)(t64 >> 32);
437
438 SYMCRYPT_ASSERT( a4 < 6 );
439 }
440
441 pState->a[0] = a0;
442 pState->a[1] = a1;
443 pState->a[2] = a2;
444 pState->a[3] = a3;
445 pState->a[4] = a4;
446}
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
#define U(x)
Definition: wordpad.c:45
static struct proto V0[]
Definition: mkg3states.c:60
static const struct update_accum a1
Definition: msg.c:534
static const struct update_accum a2
Definition: msg.c:542
static const struct update_accum a3
Definition: msg.c:556
static const struct update_accum a4
Definition: msg.c:2188
static DNS_RECORDW r3
Definition: record.c:39
static DNS_RECORDW r1
Definition: record.c:37
static DNS_RECORDW r2
Definition: record.c:38
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:586
SAMPR_REVISION_INFO_V1 V1
Definition: sam.idl:134
uint32_t UINT32
Definition: typedefs.h:59

Referenced by SymCryptPoly1305Append(), and SymCryptPoly1305Result().

◆ SymCryptPoly1305Result()

Definition at line 109 of file poly1305.c.

112{
114 UINT64 t;
115 UINT32 a4, a3, a2, a1, a0;
116 UINT32 maskOld, maskNew;
117
118 bytesInBuffer = pState->bytesInBuffer;
119 if( bytesInBuffer > 0 )
120 {
121 // Add trailing '1' byte and pad with zeroes
122 // Wipe function deals with 0-length wipes properly
123 pState->buf[bytesInBuffer++] = 1;
125
126 // Now we have to process the block, but the block function adds a trailing
127 // 1 byte to each 16-byte block. We compensate for that by decrementing
128 // the highest word of the accumulator first; the 1 byte added by the block
129 // processing function has the effect of incrementing the highest accumulator
130 // word so those two operations cancel each other out.
131 pState->a[4] -= 1;
133 }
134
135 // We have to fully reduce the accumulator first
136 // We have a[4]<6 at this point
137 a0 = pState->a[0];
138 a1 = pState->a[1];
139 a2 = pState->a[2];
140 a3 = pState->a[3];
141 a4 = pState->a[4];
142
143 SYMCRYPT_ASSERT( a4 < 6 );
144 // Because a4 < 6, we have to subtract either 0*P or 1*P
145 // we subtract P and them mux-choose between the new and old value
146 // Subtracting P is the same as subtracting 2^130 and adding 5
147 t = 5;
148
149 t += a0;
150 a0 = (UINT32) t;
151 t >>= 32;
152
153 t += a1;
154 a1 = (UINT32) t;
155 t >>= 32;
156
157 t += a2;
158 a2 = (UINT32) t;
159 t >>= 32;
160
161 t += a3;
162 a3 = (UINT32) t;
163 t >>= 32;
164
165 t += a4;
166 t -= 4;
167 a4 = (UINT32) t;
168 t >>= 32;
169
170 // If this subtraction produced a carry, then t = 0xffffffff, otherwise it is 0
171 maskOld = (UINT32) t; // ffffffff if the old value is correct, 0 otherwise
172 maskNew = ~maskOld; // ffffffff if the new value is correct, 0 otherwise
173
174 a0 = (maskNew & a0) | (maskOld & pState->a[0]);
175 a1 = (maskNew & a1) | (maskOld & pState->a[1]);
176 a2 = (maskNew & a2) | (maskOld & pState->a[2]);
177 a3 = (maskNew & a3) | (maskOld & pState->a[3]);
178 // a4 = (maskNew & a4) | (maskOld & pState->a[4]); // We don't need a4...
179
180 // Now we add S and return the data
181 t = a0;
182 t += pState->s[0];
184 t >>= 32;
185
186 t += a1;
187 t += pState->s[1];
189 t >>= 32;
190
191 t += a2;
192 t += pState->s[2];
194 t >>= 32;
195
196 t += a3;
197 t += pState->s[3];
199
200 SymCryptWipeKnownSize( (PBYTE) pState, sizeof( *pState ) );
201}
GLdouble GLdouble t
Definition: gl.h:2047
BYTE * PBYTE
Definition: pedump.c:66
VOID SYMCRYPT_CALL SymCryptWipe(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
Definition: libmain.c:137
#define SYMCRYPT_STORE_LSBFIRST32(p, v)
Definition: symcrypt.h:307

Referenced by SymCryptChaCha20Poly1305ComputeTag(), and SymCryptPoly1305().

◆ SymCryptPoly1305Selftest()

VOID SYMCRYPT_CALL SymCryptPoly1305Selftest ( void  )

Definition at line 456 of file poly1305.c.

457{
458 BYTE res[16];
459
461
462 SymCryptInjectError( res, sizeof( res ) );
463
464 if( memcmp( res, poly1305Kat, sizeof( res ) ) != 0 )
465 {
466 SymCryptFatal( 'p135');
467 }
468}
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
GLuint res
Definition: glext.h:9613
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
static const BYTE poly1305Kat[16]
Definition: poly1305.c:449
VOID SYMCRYPT_CALL SymCryptPoly1305(_In_reads_(SYMCRYPT_POLY1305_KEY_SIZE) PCBYTE pbKey, _In_reads_(cbData) PCBYTE pbData, SIZE_T cbData, _Out_writes_(SYMCRYPT_POLY1305_RESULT_SIZE) PBYTE pbResult)
Definition: poly1305.c:18
_Analysis_noreturn_ VOID SYMCRYPT_CALL SymCryptFatal(UINT32 fatalCode)
unsigned char BYTE
Definition: xxhash.c:193

Variable Documentation

◆ poly1305Kat

const BYTE poly1305Kat[16]
static
Initial value:
= {
0xef, 0x9e, 0x73, 0x2a, 0x7f, 0x2d, 0xf1, 0x85, 0xa7, 0x11, 0x80, 0xae, 0x58, 0x3a, 0x0f, 0x93,
}

Definition at line 449 of file poly1305.c.

Referenced by SymCryptPoly1305Selftest().