8 #if CRYPTOPP_MSC_VERSION 9 # pragma warning(disable: 4189) 12 #ifndef CRYPTOPP_IMPORTS 13 #ifndef CRYPTOPP_GENERATE_X64_MASM 20 word16
GCM_Base::s_reductionTable[256];
21 volatile
bool GCM_Base::s_reductionTableInitialized = false;
23 void GCM_Base::GCTR::IncrementCounterBy256()
30 void gcm_gf_mult(
const unsigned char *a,
const unsigned char *b,
unsigned char *c)
32 word64 Z0=0, Z1=0, V0, V1;
35 Block::Get(a)(V0)(V1);
37 for (
int i=0; i<16; i++)
39 for (
int j=0x80; j!=0; j>>=1)
45 V1 = (V1>>1) | (V0<<63);
46 V0 = (V0>>1) ^ (x ? W64LIT(0xe1) << 56 : 0);
52 __m128i _mm_clmulepi64_si128(
const __m128i &a,
const __m128i &b,
int i)
62 for (
int i=0; i<16; i++)
63 ((byte *)&output)[i] = c.
GetByte(i);
68 #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE || CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 69 inline static void SSE2_Xor16(byte *a,
const byte *b,
const byte *c)
71 #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 72 *(__m128i *)a = _mm_xor_si128(*(__m128i *)b, *(__m128i *)c);
74 asm (
"movdqa %1, %%xmm0; pxor %2, %%xmm0; movdqa %%xmm0, %0;" :
"=m" (a[0]) :
"m"(b[0]),
"m"(c[0]));
79 inline static void Xor16(byte *a,
const byte *b,
const byte *c)
81 ((word64 *)a)[0] = ((word64 *)b)[0] ^ ((word64 *)c)[0];
82 ((word64 *)a)[1] = ((word64 *)b)[1] ^ ((word64 *)c)[1];
85 #if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE 86 static CRYPTOPP_ALIGN_DATA(16) const word64 s_clmulConstants64[] = {
87 W64LIT(0xe100000000000000), W64LIT(0xc200000000000000),
88 W64LIT(0x08090a0b0c0d0e0f), W64LIT(0x0001020304050607),
89 W64LIT(0x0001020304050607), W64LIT(0x08090a0b0c0d0e0f)};
90 static const __m128i *s_clmulConstants = (
const __m128i *)s_clmulConstants64;
91 static const unsigned int s_clmulTableSizeInBlocks = 8;
93 inline __m128i CLMUL_Reduce(__m128i c0, __m128i c1, __m128i c2,
const __m128i &r)
107 #if 0 // MSVC 2010 workaround: see http://connect.microsoft.com/VisualStudio/feedback/details/575301 108 c2 = _mm_xor_si128(c2, _mm_move_epi64(c0));
110 c1 = _mm_xor_si128(c1, _mm_slli_si128(c0, 8));
112 c1 = _mm_xor_si128(c1, _mm_clmulepi64_si128(c0, r, 0x10));
113 c0 = _mm_srli_si128(c0, 8);
114 c0 = _mm_xor_si128(c0, c1);
115 c0 = _mm_slli_epi64(c0, 1);
116 c0 = _mm_clmulepi64_si128(c0, r, 0);
117 c2 = _mm_xor_si128(c2, c0);
118 c2 = _mm_xor_si128(c2, _mm_srli_si128(c1, 8));
119 c1 = _mm_unpacklo_epi64(c1, c2);
120 c1 = _mm_srli_epi64(c1, 63);
121 c2 = _mm_slli_epi64(c2, 1);
122 return _mm_xor_si128(c2, c1);
125 inline __m128i CLMUL_GF_Mul(
const __m128i &x,
const __m128i &h,
const __m128i &r)
127 __m128i c0 = _mm_clmulepi64_si128(x,h,0);
128 __m128i c1 = _mm_xor_si128(_mm_clmulepi64_si128(x,h,1), _mm_clmulepi64_si128(x,h,0x10));
129 __m128i c2 = _mm_clmulepi64_si128(x,h,0x11);
131 return CLMUL_Reduce(c0, c1, c2, r);
135 void GCM_Base::SetKeyWithoutResync(
const byte *userKey,
size_t keylength,
const NameValuePairs ¶ms)
138 blockCipher.
SetKey(userKey, keylength, params);
140 if (blockCipher.
BlockSize() != REQUIRED_BLOCKSIZE)
143 int tableSize, i, j, k;
145 #if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE 150 tableSize = s_clmulTableSizeInBlocks * REQUIRED_BLOCKSIZE;
156 tableSize = (tableSize >= 64*1024) ? 64*1024 : 2*1024;
158 tableSize = (GetTablesOption() == GCM_64K_Tables) ? 64*1024 : 2*1024;
160 #if defined(_MSC_VER) && (_MSC_VER >= 1300 && _MSC_VER < 1400) 166 m_buffer.resize(3*REQUIRED_BLOCKSIZE + tableSize);
167 byte *table = MulTable();
168 byte *hashKey = HashKey();
169 memset(hashKey, 0, REQUIRED_BLOCKSIZE);
172 #if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE 175 const __m128i r = s_clmulConstants[0];
176 __m128i h0 = _mm_shuffle_epi8(_mm_load_si128((__m128i *)hashKey), s_clmulConstants[1]);
179 for (i=0; i<tableSize; i+=32)
181 __m128i h1 = CLMUL_GF_Mul(h, h0, r);
182 _mm_storel_epi64((__m128i *)(table+i), h);
183 _mm_storeu_si128((__m128i *)(table+i+16), h1);
184 _mm_storeu_si128((__m128i *)(table+i+8), h);
185 _mm_storel_epi64((__m128i *)(table+i+8), h1);
186 h = CLMUL_GF_Mul(h1, h0, r);
195 Block::Get(hashKey)(V0)(V1);
197 if (tableSize == 64*1024)
199 for (i=0; i<128; i++)
202 Block::Put(NULL, table+(i/8)*256*16+(
size_t(1)<<(11-k)))(V0)(V1);
205 V1 = (V1>>1) | (V0<<63);
206 V0 = (V0>>1) ^ (x ? W64LIT(0xe1) << 56 : 0);
211 memset(table+i*256*16, 0, 16);
212 #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE || CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 214 for (j=2; j<=0x80; j*=2)
216 SSE2_Xor16(table+i*256*16+(j+k)*16, table+i*256*16+j*16, table+i*256*16+k*16);
219 for (j=2; j<=0x80; j*=2)
221 Xor16(table+i*256*16+(j+k)*16, table+i*256*16+j*16, table+i*256*16+k*16);
226 if (!s_reductionTableInitialized)
228 s_reductionTable[0] = 0;
231 for (
unsigned int ii=2; ii<=0x80; ii*=2)
235 for (
unsigned int jj=1; jj<ii; jj++)
236 s_reductionTable[ii+jj] = s_reductionTable[ii] ^ s_reductionTable[jj];
238 s_reductionTableInitialized =
true;
241 for (i=0; i<128-24; i++)
245 Block::Put(NULL, table+1024+(i/32)*256+(
size_t(1)<<(7-k)))(V0)(V1);
247 Block::Put(NULL, table+(i/32)*256+(
size_t(1)<<(11-k)))(V0)(V1);
250 V1 = (V1>>1) | (V0<<63);
251 V0 = (V0>>1) ^ (x ? W64LIT(0xe1) << 56 : 0);
256 memset(table+i*256, 0, 16);
257 memset(table+1024+i*256, 0, 16);
258 #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE || CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 260 for (j=2; j<=8; j*=2)
263 SSE2_Xor16(table+i*256+(j+k)*16, table+i*256+j*16, table+i*256+k*16);
264 SSE2_Xor16(table+1024+i*256+(j+k)*16, table+1024+i*256+j*16, table+1024+i*256+k*16);
268 for (j=2; j<=8; j*=2)
271 Xor16(table+i*256+(j+k)*16, table+i*256+j*16, table+i*256+k*16);
272 Xor16(table+1024+i*256+(j+k)*16, table+1024+i*256+j*16, table+1024+i*256+k*16);
278 inline void GCM_Base::ReverseHashBufferIfNeeded()
280 #if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE 283 __m128i &x = *(__m128i *)HashBuffer();
284 x = _mm_shuffle_epi8(x, s_clmulConstants[1]);
289 void GCM_Base::Resync(
const byte *iv,
size_t len)
292 byte *hashBuffer = HashBuffer();
296 memcpy(hashBuffer, iv, len);
297 memset(hashBuffer+len, 0, 3);
298 hashBuffer[len+3] = 1;
302 size_t origLen = len;
303 memset(hashBuffer, 0, HASH_BLOCKSIZE);
305 if (len >= HASH_BLOCKSIZE)
307 len = GCM_Base::AuthenticateBlocks(iv, len);
308 iv += (origLen - len);
313 memcpy(m_buffer, iv, len);
314 memset(m_buffer+len, 0, HASH_BLOCKSIZE-len);
315 GCM_Base::AuthenticateBlocks(m_buffer, HASH_BLOCKSIZE);
319 GCM_Base::AuthenticateBlocks(m_buffer, HASH_BLOCKSIZE);
321 ReverseHashBufferIfNeeded();
324 if (m_state >= State_IVSet)
325 m_ctr.Resynchronize(hashBuffer, REQUIRED_BLOCKSIZE);
327 m_ctr.SetCipherWithIV(cipher, hashBuffer);
329 m_ctr.Seek(HASH_BLOCKSIZE);
331 memset(hashBuffer, 0, HASH_BLOCKSIZE);
337 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE) 343 #if CRYPTOPP_MSC_VERSION 344 # pragma warning(disable: 4731) // frame pointer register 'ebp' modified by inline assembly code 347 #endif // #ifndef CRYPTOPP_GENERATE_X64_MASM 349 #ifdef CRYPTOPP_X64_MASM_AVAILABLE 351 void GCM_AuthenticateBlocks_2K(
const byte *data,
size_t blocks, word64 *hashBuffer,
const word16 *reductionTable);
352 void GCM_AuthenticateBlocks_64K(
const byte *data,
size_t blocks, word64 *hashBuffer);
356 #ifndef CRYPTOPP_GENERATE_X64_MASM 358 size_t GCM_Base::AuthenticateBlocks(
const byte *data,
size_t len)
360 #if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE 363 const __m128i *table = (
const __m128i *)MulTable();
364 __m128i x = _mm_load_si128((__m128i *)HashBuffer());
365 const __m128i r = s_clmulConstants[0], bswapMask = s_clmulConstants[1], bswapMask2 = s_clmulConstants[2];
369 size_t s =
UnsignedMin(len/16, s_clmulTableSizeInBlocks), i=0;
370 __m128i d, d2 = _mm_shuffle_epi8(_mm_loadu_si128((
const __m128i *)(data+(s-1)*16)), bswapMask2);;
371 __m128i c0 = _mm_setzero_si128();
372 __m128i c1 = _mm_setzero_si128();
373 __m128i c2 = _mm_setzero_si128();
377 __m128i h0 = _mm_load_si128(table+i);
378 __m128i h1 = _mm_load_si128(table+i+1);
379 __m128i h01 = _mm_xor_si128(h0, h1);
383 d = _mm_shuffle_epi8(_mm_loadu_si128((
const __m128i *)data), bswapMask);
384 d = _mm_xor_si128(d, x);
385 c0 = _mm_xor_si128(c0, _mm_clmulepi64_si128(d, h0, 0));
386 c2 = _mm_xor_si128(c2, _mm_clmulepi64_si128(d, h1, 1));
387 d = _mm_xor_si128(d, _mm_shuffle_epi32(d, _MM_SHUFFLE(1, 0, 3, 2)));
388 c1 = _mm_xor_si128(c1, _mm_clmulepi64_si128(d, h01, 0));
392 d = _mm_shuffle_epi8(_mm_loadu_si128((
const __m128i *)(data+(s-i)*16-8)), bswapMask2);
393 c0 = _mm_xor_si128(c0, _mm_clmulepi64_si128(d2, h0, 1));
394 c2 = _mm_xor_si128(c2, _mm_clmulepi64_si128(d, h1, 1));
395 d2 = _mm_xor_si128(d2, d);
396 c1 = _mm_xor_si128(c1, _mm_clmulepi64_si128(d2, h01, 1));
400 d = _mm_shuffle_epi8(_mm_loadu_si128((
const __m128i *)data), bswapMask);
401 d = _mm_xor_si128(d, x);
402 c0 = _mm_xor_si128(c0, _mm_clmulepi64_si128(d, h0, 0x10));
403 c2 = _mm_xor_si128(c2, _mm_clmulepi64_si128(d, h1, 0x11));
404 d = _mm_xor_si128(d, _mm_shuffle_epi32(d, _MM_SHUFFLE(1, 0, 3, 2)));
405 c1 = _mm_xor_si128(c1, _mm_clmulepi64_si128(d, h01, 0x10));
409 d2 = _mm_shuffle_epi8(_mm_loadu_si128((
const __m128i *)(data+(s-i)*16-8)), bswapMask);
410 c0 = _mm_xor_si128(c0, _mm_clmulepi64_si128(d, h0, 0x10));
411 c2 = _mm_xor_si128(c2, _mm_clmulepi64_si128(d2, h1, 0x10));
412 d = _mm_xor_si128(d, d2);
413 c1 = _mm_xor_si128(c1, _mm_clmulepi64_si128(d, h01, 0x10));
418 c1 = _mm_xor_si128(_mm_xor_si128(c1, c0), c2);
419 x = CLMUL_Reduce(c0, c1, c2, r);
422 _mm_store_si128((__m128i *)HashBuffer(), x);
428 word64 *hashBuffer = (word64 *)HashBuffer();
430 switch (2*(m_buffer.size()>=64*1024)
431 #
if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE)
438 byte *table = MulTable();
439 word64 x0 = hashBuffer[0], x1 = hashBuffer[1];
443 word64 y0, y1, a0, a1, b0, b1, c0, c1, d0, d1;
444 Block::Get(data)(y0)(y1);
448 data += HASH_BLOCKSIZE;
449 len -= HASH_BLOCKSIZE;
451 #define READ_TABLE_WORD64_COMMON(a, b, c, d) *(word64 *)(table+(a*1024)+(b*256)+c+d*8) 453 #ifdef IS_LITTLE_ENDIAN 454 #if CRYPTOPP_BOOL_SLOW_WORD64 455 word32 z0 = (word32)x0;
456 word32 z1 = (word32)(x0>>32);
457 word32 z2 = (word32)x1;
458 word32 z3 = (word32)(x1>>32);
459 #define READ_TABLE_WORD64(a, b, c, d, e) READ_TABLE_WORD64_COMMON((d%2), c, (d?(z##c>>((d?d-1:0)*4))&0xf0:(z##c&0xf)<<4), e) 461 #define READ_TABLE_WORD64(a, b, c, d, e) READ_TABLE_WORD64_COMMON((d%2), c, ((d+8*b)?(x##a>>(((d+8*b)?(d+8*b)-1:1)*4))&0xf0:(x##a&0xf)<<4), e) 463 #define GF_MOST_SIG_8BITS(a) (a##1 >> 7*8) 464 #define GF_SHIFT_8(a) a##1 = (a##1 << 8) ^ (a##0 >> 7*8); a##0 <<= 8; 466 #define READ_TABLE_WORD64(a, b, c, d, e) READ_TABLE_WORD64_COMMON((1-d%2), c, ((15-d-8*b)?(x##a>>(((15-d-8*b)?(15-d-8*b)-1:0)*4))&0xf0:(x##a&0xf)<<4), e) 467 #define GF_MOST_SIG_8BITS(a) (a##1 & 0xff) 468 #define GF_SHIFT_8(a) a##1 = (a##1 >> 8) ^ (a##0 << 7*8); a##0 >>= 8; 471 #define GF_MUL_32BY128(op, a, b, c) \ 472 a0 op READ_TABLE_WORD64(a, b, c, 0, 0) ^ READ_TABLE_WORD64(a, b, c, 1, 0);\ 473 a1 op READ_TABLE_WORD64(a, b, c, 0, 1) ^ READ_TABLE_WORD64(a, b, c, 1, 1);\ 474 b0 op READ_TABLE_WORD64(a, b, c, 2, 0) ^ READ_TABLE_WORD64(a, b, c, 3, 0);\ 475 b1 op READ_TABLE_WORD64(a, b, c, 2, 1) ^ READ_TABLE_WORD64(a, b, c, 3, 1);\ 476 c0 op READ_TABLE_WORD64(a, b, c, 4, 0) ^ READ_TABLE_WORD64(a, b, c, 5, 0);\ 477 c1 op READ_TABLE_WORD64(a, b, c, 4, 1) ^ READ_TABLE_WORD64(a, b, c, 5, 1);\ 478 d0 op READ_TABLE_WORD64(a, b, c, 6, 0) ^ READ_TABLE_WORD64(a, b, c, 7, 0);\ 479 d1 op READ_TABLE_WORD64(a, b, c, 6, 1) ^ READ_TABLE_WORD64(a, b, c, 7, 1);\ 481 GF_MUL_32BY128(=, 0, 0, 0)
482 GF_MUL_32BY128(^=, 0, 1, 1)
483 GF_MUL_32BY128(^=, 1, 0, 2)
484 GF_MUL_32BY128(^=, 1, 1, 3)
486 word32 r = (word32)s_reductionTable[GF_MOST_SIG_8BITS(d)] << 16;
489 r ^= (word32)s_reductionTable[GF_MOST_SIG_8BITS(c)] << 8;
492 r ^= s_reductionTable[GF_MOST_SIG_8BITS(b)];
495 a0 ^= ConditionalByteReverse<word64>(LITTLE_ENDIAN_ORDER, r);
498 while (len >= HASH_BLOCKSIZE);
500 hashBuffer[0] = x0; hashBuffer[1] = x1;
506 byte *table = MulTable();
507 word64 x0 = hashBuffer[0], x1 = hashBuffer[1];
511 word64 y0, y1, a0, a1;
512 Block::Get(data)(y0)(y1);
516 data += HASH_BLOCKSIZE;
517 len -= HASH_BLOCKSIZE;
519 #undef READ_TABLE_WORD64_COMMON 520 #undef READ_TABLE_WORD64 522 #define READ_TABLE_WORD64_COMMON(a, c, d) *(word64 *)(table+(a)*256*16+(c)+(d)*8) 524 #ifdef IS_LITTLE_ENDIAN 525 #if CRYPTOPP_BOOL_SLOW_WORD64 526 word32 z0 = (word32)x0;
527 word32 z1 = (word32)(x0>>32);
528 word32 z2 = (word32)x1;
529 word32 z3 = (word32)(x1>>32);
530 #define READ_TABLE_WORD64(b, c, d, e) READ_TABLE_WORD64_COMMON(c*4+d, (d?(z##c>>((d?d:1)*8-4))&0xff0:(z##c&0xff)<<4), e) 532 #define READ_TABLE_WORD64(b, c, d, e) READ_TABLE_WORD64_COMMON(c*4+d, ((d+4*(c%2))?(x##b>>(((d+4*(c%2))?(d+4*(c%2)):1)*8-4))&0xff0:(x##b&0xff)<<4), e) 535 #define READ_TABLE_WORD64(b, c, d, e) READ_TABLE_WORD64_COMMON(c*4+d, ((7-d-4*(c%2))?(x##b>>(((7-d-4*(c%2))?(7-d-4*(c%2)):1)*8-4))&0xff0:(x##b&0xff)<<4), e) 538 #define GF_MUL_8BY128(op, b, c, d) \ 539 a0 op READ_TABLE_WORD64(b, c, d, 0);\ 540 a1 op READ_TABLE_WORD64(b, c, d, 1);\ 542 GF_MUL_8BY128(=, 0, 0, 0)
543 GF_MUL_8BY128(^=, 0, 0, 1)
544 GF_MUL_8BY128(^=, 0, 0, 2)
545 GF_MUL_8BY128(^=, 0, 0, 3)
546 GF_MUL_8BY128(^=, 0, 1, 0)
547 GF_MUL_8BY128(^=, 0, 1, 1)
548 GF_MUL_8BY128(^=, 0, 1, 2)
549 GF_MUL_8BY128(^=, 0, 1, 3)
550 GF_MUL_8BY128(^=, 1, 2, 0)
551 GF_MUL_8BY128(^=, 1, 2, 1)
552 GF_MUL_8BY128(^=, 1, 2, 2)
553 GF_MUL_8BY128(^=, 1, 2, 3)
554 GF_MUL_8BY128(^=, 1, 3, 0)
555 GF_MUL_8BY128(^=, 1, 3, 1)
556 GF_MUL_8BY128(^=, 1, 3, 2)
557 GF_MUL_8BY128(^=, 1, 3, 3)
561 while (len >= HASH_BLOCKSIZE);
563 hashBuffer[0] = x0; hashBuffer[1] = x1;
566 #endif // #ifndef CRYPTOPP_GENERATE_X64_MASM 568 #ifdef CRYPTOPP_X64_MASM_AVAILABLE 570 GCM_AuthenticateBlocks_2K(data, len/16, hashBuffer, s_reductionTable);
573 GCM_AuthenticateBlocks_64K(data, len/16, hashBuffer);
577 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 584 #elif defined(CRYPTOPP_GENERATE_X64_MASM)
586 GCM_AuthenticateBlocks_2K PROC FRAME
594 AS2( mov WORD_REG(cx), data )
595 AS2( mov WORD_REG(dx), len )
596 AS2( mov WORD_REG(si), hashBuffer )
597 AS2( shr WORD_REG(dx), 4 )
600 #
if CRYPTOPP_BOOL_X32
609 AS2( mov AS_REG_7, WORD_REG(di))
610 #elif CRYPTOPP_BOOL_X86
611 AS2( lea AS_REG_7, s_reductionTable)
614 AS2( movdqa xmm0, [WORD_REG(si)] )
616 #define MUL_TABLE_0 WORD_REG(si) + 32
617 #define MUL_TABLE_1 WORD_REG(si) + 32 + 1024
618 #define RED_TABLE AS_REG_7
621 AS2( movdqu xmm4, [WORD_REG(cx)] )
622 AS2( pxor xmm0, xmm4 )
624 AS2( movd ebx, xmm0 )
625 AS2( mov eax, AS_HEX(f0f0f0f0) )
628 AS2( and ebx, AS_HEX(f0f0f0f0) )
630 AS2( movdqa xmm5, XMMWORD_PTR [MUL_TABLE_1 + WORD_REG(di)] )
632 AS2( movdqa xmm4, XMMWORD_PTR [MUL_TABLE_1 + WORD_REG(di)] )
635 AS2( movdqa xmm3, XMMWORD_PTR [MUL_TABLE_1 + WORD_REG(di)] )
637 AS2( movdqa xmm2, XMMWORD_PTR [MUL_TABLE_1 + WORD_REG(di)] )
639 #define SSE2_MUL_32BITS(i) \
640 AS2( psrldq xmm0, 4 )\
641 AS2( movd eax, xmm0 )\
642 AS2( and eax, AS_HEX(f0f0f0f0) )\
643 AS2( movzx edi, bh )\
644 AS2( pxor xmm5, XMMWORD_PTR [MUL_TABLE_0 + (i-1)*256 + WORD_REG(di)] )\
645 AS2( movzx edi, bl )\
646 AS2( pxor xmm4, XMMWORD_PTR [MUL_TABLE_0 + (i-1)*256 + WORD_REG(di)] )\
648 AS2( movzx edi, bh )\
649 AS2( pxor xmm3, XMMWORD_PTR [MUL_TABLE_0 + (i-1)*256 + WORD_REG(di)] )\
650 AS2( movzx edi, bl )\
651 AS2( pxor xmm2, XMMWORD_PTR [MUL_TABLE_0 + (i-1)*256 + WORD_REG(di)] )\
652 AS2( movd ebx, xmm0 )\
654 AS2( and ebx, AS_HEX(f0f0f0f0) )\
655 AS2( movzx edi, ah )\
656 AS2( pxor xmm5, XMMWORD_PTR [MUL_TABLE_1 + i*256 + WORD_REG(di)] )\
657 AS2( movzx edi, al )\
658 AS2( pxor xmm4, XMMWORD_PTR [MUL_TABLE_1 + i*256 + WORD_REG(di)] )\
660 AS2( movzx edi, ah )\
661 AS2( pxor xmm3, XMMWORD_PTR [MUL_TABLE_1 + i*256 + WORD_REG(di)] )\
662 AS2( movzx edi, al )\
663 AS2( pxor xmm2, XMMWORD_PTR [MUL_TABLE_1 + i*256 + WORD_REG(di)] )\
670 AS2( pxor xmm5, XMMWORD_PTR [MUL_TABLE_0 + 3*256 + WORD_REG(di)] )
672 AS2( pxor xmm4, XMMWORD_PTR [MUL_TABLE_0 + 3*256 + WORD_REG(di)] )
675 AS2( pxor xmm3, XMMWORD_PTR [MUL_TABLE_0 + 3*256 + WORD_REG(di)] )
677 AS2( pxor xmm2, XMMWORD_PTR [MUL_TABLE_0 + 3*256 + WORD_REG(di)] )
679 AS2( movdqa xmm0, xmm3 )
680 AS2( pslldq xmm3, 1 )
681 AS2( pxor xmm2, xmm3 )
682 AS2( movdqa xmm1, xmm2 )
683 AS2( pslldq xmm2, 1 )
684 AS2( pxor xmm5, xmm2 )
686 AS2( psrldq xmm0, 15 )
687 #
if (CRYPTOPP_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000)
688 AS2( movd edi, xmm0 )
689 #elif defined(CRYPTOPP_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)
690 AS2( mov WORD_REG(di), xmm0 )
692 AS2( movd WORD_REG(di), xmm0 )
694 AS2( movzx eax, WORD PTR [RED_TABLE + WORD_REG(di)*2] )
697 AS2( movdqa xmm0, xmm5 )
698 AS2( pslldq xmm5, 1 )
699 AS2( pxor xmm4, xmm5 )
701 AS2( psrldq xmm1, 15 )
702 #
if (CRYPTOPP_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000)
703 AS2( movd edi, xmm1 )
704 #elif defined(CRYPTOPP_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)
705 AS2( mov WORD_REG(di), xmm1 )
707 AS2( movd WORD_REG(di), xmm1 )
709 AS2( xor ax, WORD PTR [RED_TABLE + WORD_REG(di)*2] )
712 AS2( psrldq xmm0, 15 )
713 #
if (CRYPTOPP_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000)
714 AS2( movd edi, xmm0 )
715 #elif defined(CRYPTOPP_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)
716 AS2( mov WORD_REG(di), xmm0 )
718 AS2( movd WORD_REG(di), xmm0 )
720 AS2( xor ax, WORD PTR [RED_TABLE + WORD_REG(di)*2] )
722 AS2( movd xmm0, eax )
723 AS2( pxor xmm0, xmm4 )
725 AS2( add WORD_REG(cx), 16 )
726 AS2( sub WORD_REG(dx), 1 )
728 AS2( movdqa [WORD_REG(si)], xmm0 )
730 #
if CRYPTOPP_BOOL_X32
741 :
"c" (data),
"d" (len/16),
"S" (hashBuffer),
"D" (s_reductionTable)
742 :
"memory",
"cc",
"%eax" 743 #
if CRYPTOPP_BOOL_X64
747 #elif defined(CRYPTOPP_GENERATE_X64_MASM) 752 GCM_AuthenticateBlocks_2K ENDP
763 #elif defined(CRYPTOPP_GENERATE_X64_MASM)
765 GCM_AuthenticateBlocks_64K PROC FRAME
771 AS2( mov WORD_REG(cx), data )
772 AS2( mov WORD_REG(dx), len )
773 AS2( mov WORD_REG(si), hashBuffer )
774 AS2( shr WORD_REG(dx), 4 )
777 AS2( movdqa xmm0, [WORD_REG(si)] )
780 #define MUL_TABLE(i,j) WORD_REG(si) + 32 + (i*4+j)*256*16
783 AS2( movdqu xmm1, [WORD_REG(cx)] )
784 AS2( pxor xmm1, xmm0 )
785 AS2( pxor xmm0, xmm0 )
787 #undef SSE2_MUL_32BITS
788 #define SSE2_MUL_32BITS(i) \
789 AS2( movd eax, xmm1 )\
790 AS2( psrldq xmm1, 4 )\
791 AS2( movzx edi, al )\
792 AS2( add WORD_REG(di), WORD_REG(di) )\
793 AS2( pxor xmm0, [MUL_TABLE(i,0) + WORD_REG(di)*8] )\
794 AS2( movzx edi, ah )\
795 AS2( add WORD_REG(di), WORD_REG(di) )\
796 AS2( pxor xmm0, [MUL_TABLE(i,1) + WORD_REG(di)*8] )\
798 AS2( movzx edi, al )\
799 AS2( add WORD_REG(di), WORD_REG(di) )\
800 AS2( pxor xmm0, [MUL_TABLE(i,2) + WORD_REG(di)*8] )\
801 AS2( movzx edi, ah )\
802 AS2( add WORD_REG(di), WORD_REG(di) )\
803 AS2( pxor xmm0, [MUL_TABLE(i,3) + WORD_REG(di)*8] )\
810 AS2( add WORD_REG(cx), 16 )
811 AS2( sub WORD_REG(dx), 1 )
813 AS2( movdqa [WORD_REG(si)], xmm0 )
818 :
"c" (data),
"d" (len/16),
"S" (hashBuffer)
819 :
"memory",
"cc",
"%edi",
"%eax" 821 #elif defined(CRYPTOPP_GENERATE_X64_MASM) 825 GCM_AuthenticateBlocks_64K ENDP
831 #ifndef CRYPTOPP_GENERATE_X64_MASM 837 void GCM_Base::AuthenticateLastHeaderBlock()
839 if (m_bufferedDataLength > 0)
841 memset(m_buffer+m_bufferedDataLength, 0, HASH_BLOCKSIZE-m_bufferedDataLength);
842 m_bufferedDataLength = 0;
843 GCM_Base::AuthenticateBlocks(m_buffer, HASH_BLOCKSIZE);
847 void GCM_Base::AuthenticateLastConfidentialBlock()
849 GCM_Base::AuthenticateLastHeaderBlock();
851 GCM_Base::AuthenticateBlocks(m_buffer, HASH_BLOCKSIZE);
854 void GCM_Base::AuthenticateLastFooterBlock(byte *mac,
size_t macSize)
857 ReverseHashBufferIfNeeded();
858 m_ctr.ProcessData(mac, HashBuffer(), macSize);
863 #endif // #ifndef CRYPTOPP_GENERATE_X64_MASM CCM block cipher mode of operation.
An invalid argument was detected.
virtual void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms=g_nullNameValuePairs)
Sets or reset the key of this object.
void IncrementCounterByOne(byte *inout, unsigned int size)
Performs an addition with carry on a block of bytes.
Library configuration file.
byte GetByte(size_t n) const
return the n-th byte
bool GetIntValue(const char *name, int &value) const
Get a named value with type int.
Polynomial with Coefficients in GF(2)
Interface for one direction (encryption or decryption) of a block cipher.
const char * TableSize()
int, in bytes
unsigned int OptimalDataAlignment() const
Provides input and output data alignment for optimal performance.
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be neagtive and incorrectly promoted.
const char * BlockSize()
int, in bytes
Classes, functions, intrinsics and features for X86, X32 nd X64 assembly.
std::string AlgorithmName() const
Provides the name of this algorithm.
GCM block cipher mode of operation.
Crypto++ library namespace.
byte ByteReverse(byte value)
Reverses bytes in a 8-bit value.
Interface for retrieving values given their names.