12 #ifndef CRYPTOPP_IMPORTS 13 #ifndef CRYPTOPP_GENERATE_X64_MASM 17 #if defined(__clang__) 18 # undef CRYPTOPP_X86_ASM_AVAILABLE 19 # undef CRYPTOPP_X32_ASM_AVAILABLE 20 # undef CRYPTOPP_X64_ASM_AVAILABLE 21 # undef CRYPTOPP_SSE2_ASM_AVAILABLE 26 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x5140) 27 # undef CRYPTOPP_CLMUL_AVAILABLE 30 #if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) 31 # include <emmintrin.h> 39 #if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) 42 #if (CRYPTOPP_LLVM_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000) || defined(CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER) 44 # define USE_MOVD_REG32 1 45 #elif defined(__GNUC__) || defined(_MSC_VER) 47 # define USE_MOVD_REG32_OR_REG64 1 50 # define USE_MOV_REG32_OR_REG64 1 52 #endif // CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 55 #define M128_CAST(x) ((__m128i *)(void *)(x)) 56 #define CONST_M128_CAST(x) ((const __m128i *)(const void *)(x)) 58 #if CRYPTOPP_ARM_NEON_AVAILABLE 59 extern void GCM_Xor16_NEON(
byte *a,
const byte *b,
const byte *c);
62 word16 GCM_Base::s_reductionTable[256];
63 volatile bool GCM_Base::s_reductionTableInitialized =
false;
65 void GCM_Base::GCTR::IncrementCounterBy256()
70 static inline void Xor16(
byte *a,
const byte *b,
const byte *c)
75 ((word64 *)(
void *)a)[0] = ((word64 *)(
void *)b)[0] ^ ((word64 *)(
void *)c)[0];
76 ((word64 *)(
void *)a)[1] = ((word64 *)(
void *)b)[1] ^ ((word64 *)(
void *)c)[1];
79 #if CRYPTOPP_SSE2_INTRIN_AVAILABLE || CRYPTOPP_SSE2_ASM_AVAILABLE 82 extern void GCM_Xor16_SSE2(
byte *a,
const byte *b,
const byte *c);
85 #if CRYPTOPP_CLMUL_AVAILABLE 86 extern void GCM_SetKeyWithoutResync_CLMUL(
const byte *hashKey,
byte *mulTable,
unsigned int tableSize);
87 extern size_t GCM_AuthenticateBlocks_CLMUL(
const byte *data,
size_t len,
const byte *mtable,
byte *hbuffer);
88 const unsigned int s_cltableSizeInBlocks = 8;
89 extern void GCM_ReverseHashBufferIfNeeded_CLMUL(
byte *hashBuffer);
90 #endif // CRYPTOPP_CLMUL_AVAILABLE 92 #if CRYPTOPP_ARM_PMULL_AVAILABLE 93 extern void GCM_SetKeyWithoutResync_PMULL(
const byte *hashKey,
byte *mulTable,
unsigned int tableSize);
94 extern size_t GCM_AuthenticateBlocks_PMULL(
const byte *data,
size_t len,
const byte *mtable,
byte *hbuffer);
95 const unsigned int s_cltableSizeInBlocks = 8;
96 extern void GCM_ReverseHashBufferIfNeeded_PMULL(
byte *hashBuffer);
97 #endif // CRYPTOPP_ARM_PMULL_AVAILABLE 99 void GCM_Base::SetKeyWithoutResync(
const byte *userKey,
size_t keylength,
const NameValuePairs ¶ms)
102 blockCipher.
SetKey(userKey, keylength, params);
108 const unsigned int blockSize = blockCipher.
BlockSize();
110 if (blockCipher.
BlockSize() != REQUIRED_BLOCKSIZE)
113 int tableSize, i, j, k;
115 #if CRYPTOPP_CLMUL_AVAILABLE 120 tableSize = s_cltableSizeInBlocks * blockSize;
124 #elif CRYPTOPP_ARM_PMULL_AVAILABLE 129 tableSize = s_cltableSizeInBlocks * blockSize;
136 tableSize = (tableSize >= 64*1024) ? 64*1024 : 2*1024;
138 tableSize = (GetTablesOption() ==
GCM_64K_Tables) ? 64*1024 : 2*1024;
146 m_buffer.resize(3*blockSize + tableSize);
147 byte *mulTable = MulTable();
148 byte *hashKey = HashKey();
149 memset(hashKey, 0, REQUIRED_BLOCKSIZE);
152 #if CRYPTOPP_CLMUL_AVAILABLE 155 GCM_SetKeyWithoutResync_CLMUL(hashKey, mulTable, tableSize);
158 #elif CRYPTOPP_ARM_PMULL_AVAILABLE 161 GCM_SetKeyWithoutResync_PMULL(hashKey, mulTable, tableSize);
168 Block::Get(hashKey)(V0)(V1);
170 if (tableSize == 64*1024)
172 for (i=0; i<128; i++)
175 Block::Put(NULLPTR, mulTable+(i/8)*256*16+(
size_t(1)<<(11-k)))(V0)(V1);
178 V1 = (V1>>1) | (V0<<63);
179 V0 = (V0>>1) ^ (x ? W64LIT(0xe1) << 56 : 0);
184 memset(mulTable+i*256*16, 0, 16);
185 #if CRYPTOPP_SSE2_INTRIN_AVAILABLE || CRYPTOPP_SSE2_ASM_AVAILABLE 187 for (j=2; j<=0x80; j*=2)
189 GCM_Xor16_SSE2(mulTable+i*256*16+(j+k)*16, mulTable+i*256*16+j*16, mulTable+i*256*16+k*16);
191 #elif CRYPTOPP_ARM_NEON_AVAILABLE 193 for (j=2; j<=0x80; j*=2)
195 GCM_Xor16_NEON(mulTable+i*256*16+(j+k)*16, mulTable+i*256*16+j*16, mulTable+i*256*16+k*16);
198 for (j=2; j<=0x80; j*=2)
200 Xor16(mulTable+i*256*16+(j+k)*16, mulTable+i*256*16+j*16, mulTable+i*256*16+k*16);
205 if (!s_reductionTableInitialized)
207 s_reductionTable[0] = 0;
210 for (
unsigned int ii=2; ii<=0x80; ii*=2)
214 for (
unsigned int jj=1; jj<ii; jj++)
215 s_reductionTable[ii+jj] = s_reductionTable[ii] ^ s_reductionTable[jj];
217 s_reductionTableInitialized =
true;
220 for (i=0; i<128-24; i++)
224 Block::Put(NULLPTR, mulTable+1024+(i/32)*256+(
size_t(1)<<(7-k)))(V0)(V1);
226 Block::Put(NULLPTR, mulTable+(i/32)*256+(
size_t(1)<<(11-k)))(V0)(V1);
229 V1 = (V1>>1) | (V0<<63);
230 V0 = (V0>>1) ^ (x ? W64LIT(0xe1) << 56 : 0);
235 memset(mulTable+i*256, 0, 16);
236 memset(mulTable+1024+i*256, 0, 16);
237 #if CRYPTOPP_SSE2_INTRIN_AVAILABLE || CRYPTOPP_SSE2_ASM_AVAILABLE 239 for (j=2; j<=8; j*=2)
242 GCM_Xor16_SSE2(mulTable+i*256+(j+k)*16, mulTable+i*256+j*16, mulTable+i*256+k*16);
243 GCM_Xor16_SSE2(mulTable+1024+i*256+(j+k)*16, mulTable+1024+i*256+j*16, mulTable+1024+i*256+k*16);
246 #elif CRYPTOPP_ARM_NEON_AVAILABLE 248 for (j=2; j<=8; j*=2)
251 GCM_Xor16_NEON(mulTable+i*256+(j+k)*16, mulTable+i*256+j*16, mulTable+i*256+k*16);
252 GCM_Xor16_NEON(mulTable+1024+i*256+(j+k)*16, mulTable+1024+i*256+j*16, mulTable+1024+i*256+k*16);
256 for (j=2; j<=8; j*=2)
259 Xor16(mulTable+i*256+(j+k)*16, mulTable+i*256+j*16, mulTable+i*256+k*16);
260 Xor16(mulTable+1024+i*256+(j+k)*16, mulTable+1024+i*256+j*16, mulTable+1024+i*256+k*16);
266 inline void GCM_Base::ReverseHashBufferIfNeeded()
268 #if CRYPTOPP_CLMUL_AVAILABLE 271 GCM_ReverseHashBufferIfNeeded_CLMUL(HashBuffer());
273 #elif CRYPTOPP_ARM_PMULL_AVAILABLE 276 GCM_ReverseHashBufferIfNeeded_PMULL(HashBuffer());
281 void GCM_Base::Resync(
const byte *iv,
size_t len)
284 byte *hashBuffer = HashBuffer();
288 memcpy(hashBuffer, iv, len);
289 memset(hashBuffer+len, 0, 3);
290 hashBuffer[len+3] = 1;
294 size_t origLen = len;
295 memset(hashBuffer, 0, HASH_BLOCKSIZE);
297 if (len >= HASH_BLOCKSIZE)
299 len = GCM_Base::AuthenticateBlocks(iv, len);
300 iv += (origLen - len);
305 memcpy(m_buffer, iv, len);
306 memset(m_buffer+len, 0, HASH_BLOCKSIZE-len);
307 GCM_Base::AuthenticateBlocks(m_buffer, HASH_BLOCKSIZE);
311 GCM_Base::AuthenticateBlocks(m_buffer, HASH_BLOCKSIZE);
313 ReverseHashBufferIfNeeded();
316 if (m_state >= State_IVSet)
317 m_ctr.Resynchronize(hashBuffer, REQUIRED_BLOCKSIZE);
319 m_ctr.SetCipherWithIV(cipher, hashBuffer);
321 m_ctr.Seek(HASH_BLOCKSIZE);
323 memset(hashBuffer, 0, HASH_BLOCKSIZE);
329 #if CRYPTOPP_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE) 331 #elif CRYPTOPP_ARM_NEON_AVAILABLE 337 #if CRYPTOPP_MSC_VERSION 338 # pragma warning(disable: 4731) // frame pointer register 'ebp' modified by inline assembly code 341 #endif // #ifndef CRYPTOPP_GENERATE_X64_MASM 343 #ifdef CRYPTOPP_X64_MASM_AVAILABLE 345 void GCM_AuthenticateBlocks_2K(
const byte *data,
size_t blocks, word64 *hashBuffer,
const word16 *reductionTable);
346 void GCM_AuthenticateBlocks_64K(
const byte *data,
size_t blocks, word64 *hashBuffer);
350 #ifndef CRYPTOPP_GENERATE_X64_MASM 352 size_t GCM_Base::AuthenticateBlocks(
const byte *data,
size_t len)
354 #if CRYPTOPP_CLMUL_AVAILABLE 357 return GCM_AuthenticateBlocks_CLMUL(data, len, MulTable(), HashBuffer());
359 #elif CRYPTOPP_ARM_PMULL_AVAILABLE 362 return GCM_AuthenticateBlocks_PMULL(data, len, MulTable(), HashBuffer());
367 word64 *hashBuffer = (word64 *)(
void *)HashBuffer();
370 switch (2*(m_buffer.size()>=64*1024)
371 #
if CRYPTOPP_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE)
380 byte *mulTable = MulTable();
381 word64 x0 = hashBuffer[0], x1 = hashBuffer[1];
385 word64 y0, y1, a0, a1, b0, b1, c0, c1, d0, d1;
386 Block::Get(data)(y0)(y1);
390 data += HASH_BLOCKSIZE;
391 len -= HASH_BLOCKSIZE;
393 #define READ_TABLE_WORD64_COMMON(a, b, c, d) *(word64 *)(void *)(mulTable+(a*1024)+(b*256)+c+d*8) 395 #ifdef CRYPTOPP_LITTLE_ENDIAN 396 #if CRYPTOPP_BOOL_SLOW_WORD64 397 word32 z0 = (word32)x0;
398 word32 z1 = (word32)(x0>>32);
399 word32 z2 = (word32)x1;
400 word32 z3 = (word32)(x1>>32);
401 #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) 403 #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) 405 #define GF_MOST_SIG_8BITS(a) (a##1 >> 7*8) 406 #define GF_SHIFT_8(a) a##1 = (a##1 << 8) ^ (a##0 >> 7*8); a##0 <<= 8; 408 #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) 409 #define GF_MOST_SIG_8BITS(a) (a##1 & 0xff) 410 #define GF_SHIFT_8(a) a##1 = (a##1 >> 8) ^ (a##0 << 7*8); a##0 >>= 8; 413 #define GF_MUL_32BY128(op, a, b, c) \ 414 a0 op READ_TABLE_WORD64(a, b, c, 0, 0) ^ READ_TABLE_WORD64(a, b, c, 1, 0); \ 415 a1 op READ_TABLE_WORD64(a, b, c, 0, 1) ^ READ_TABLE_WORD64(a, b, c, 1, 1); \ 416 b0 op READ_TABLE_WORD64(a, b, c, 2, 0) ^ READ_TABLE_WORD64(a, b, c, 3, 0); \ 417 b1 op READ_TABLE_WORD64(a, b, c, 2, 1) ^ READ_TABLE_WORD64(a, b, c, 3, 1); \ 418 c0 op READ_TABLE_WORD64(a, b, c, 4, 0) ^ READ_TABLE_WORD64(a, b, c, 5, 0); \ 419 c1 op READ_TABLE_WORD64(a, b, c, 4, 1) ^ READ_TABLE_WORD64(a, b, c, 5, 1); \ 420 d0 op READ_TABLE_WORD64(a, b, c, 6, 0) ^ READ_TABLE_WORD64(a, b, c, 7, 0); \ 421 d1 op READ_TABLE_WORD64(a, b, c, 6, 1) ^ READ_TABLE_WORD64(a, b, c, 7, 1); \ 423 GF_MUL_32BY128(=, 0, 0, 0)
424 GF_MUL_32BY128(^=, 0, 1, 1)
425 GF_MUL_32BY128(^=, 1, 0, 2)
426 GF_MUL_32BY128(^=, 1, 1, 3)
428 word32 r = (word32)s_reductionTable[GF_MOST_SIG_8BITS(d)] << 16;
431 r ^= (word32)s_reductionTable[GF_MOST_SIG_8BITS(c)] << 8;
434 r ^= s_reductionTable[GF_MOST_SIG_8BITS(b)];
440 while (len >= HASH_BLOCKSIZE);
442 hashBuffer[0] = x0; hashBuffer[1] = x1;
448 byte *mulTable = MulTable();
449 word64 x0 = hashBuffer[0], x1 = hashBuffer[1];
453 word64 y0, y1, a0, a1;
454 Block::Get(data)(y0)(y1);
458 data += HASH_BLOCKSIZE;
459 len -= HASH_BLOCKSIZE;
461 #undef READ_TABLE_WORD64_COMMON 462 #undef READ_TABLE_WORD64 464 #define READ_TABLE_WORD64_COMMON(a, c, d) *(word64 *)(void *)(mulTable+(a)*256*16+(c)+(d)*8) 466 #ifdef CRYPTOPP_LITTLE_ENDIAN 467 #if CRYPTOPP_BOOL_SLOW_WORD64 468 word32 z0 = (word32)x0;
469 word32 z1 = (word32)(x0>>32);
470 word32 z2 = (word32)x1;
471 word32 z3 = (word32)(x1>>32);
472 #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) 474 #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) 477 #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) 480 #define GF_MUL_8BY128(op, b, c, d) \ 481 a0 op READ_TABLE_WORD64(b, c, d, 0);\ 482 a1 op READ_TABLE_WORD64(b, c, d, 1);\ 484 GF_MUL_8BY128(=, 0, 0, 0)
485 GF_MUL_8BY128(^=, 0, 0, 1)
486 GF_MUL_8BY128(^=, 0, 0, 2)
487 GF_MUL_8BY128(^=, 0, 0, 3)
488 GF_MUL_8BY128(^=, 0, 1, 0)
489 GF_MUL_8BY128(^=, 0, 1, 1)
490 GF_MUL_8BY128(^=, 0, 1, 2)
491 GF_MUL_8BY128(^=, 0, 1, 3)
492 GF_MUL_8BY128(^=, 1, 2, 0)
493 GF_MUL_8BY128(^=, 1, 2, 1)
494 GF_MUL_8BY128(^=, 1, 2, 2)
495 GF_MUL_8BY128(^=, 1, 2, 3)
496 GF_MUL_8BY128(^=, 1, 3, 0)
497 GF_MUL_8BY128(^=, 1, 3, 1)
498 GF_MUL_8BY128(^=, 1, 3, 2)
499 GF_MUL_8BY128(^=, 1, 3, 3)
503 while (len >= HASH_BLOCKSIZE);
505 hashBuffer[0] = x0; hashBuffer[1] = x1;
508 #endif // #ifndef CRYPTOPP_GENERATE_X64_MASM 510 #ifdef CRYPTOPP_X64_MASM_AVAILABLE 512 GCM_AuthenticateBlocks_2K(data, len/16, hashBuffer, s_reductionTable);
515 GCM_AuthenticateBlocks_64K(data, len/16, hashBuffer);
519 #if CRYPTOPP_SSE2_ASM_AVAILABLE 526 #elif defined(CRYPTOPP_GENERATE_X64_MASM)
528 GCM_AuthenticateBlocks_2K PROC FRAME
536 AS2( mov WORD_REG(cx), data )
537 AS2( mov WORD_REG(dx), len )
538 AS2( mov WORD_REG(si), hashBuffer )
539 AS2( shr WORD_REG(dx), 4 )
542 #
if CRYPTOPP_BOOL_X32
551 AS2( mov AS_REG_7, WORD_REG(di))
552 #elif CRYPTOPP_BOOL_X86
553 AS2( lea AS_REG_7, s_reductionTable)
556 AS2( movdqa xmm0, [WORD_REG(si)] )
558 #define MUL_TABLE_0 WORD_REG(si) + 32
559 #define MUL_TABLE_1 WORD_REG(si) + 32 + 1024
560 #define RED_TABLE AS_REG_7
563 AS2( movdqu xmm4, [WORD_REG(cx)] )
564 AS2( pxor xmm0, xmm4 )
566 AS2( movd ebx, xmm0 )
567 AS2( mov eax, AS_HEX(f0f0f0f0) )
570 AS2( and ebx, AS_HEX(f0f0f0f0) )
572 AS2( movdqa xmm5, XMMWORD_PTR [MUL_TABLE_1 + WORD_REG(di)] )
574 AS2( movdqa xmm4, XMMWORD_PTR [MUL_TABLE_1 + WORD_REG(di)] )
577 AS2( movdqa xmm3, XMMWORD_PTR [MUL_TABLE_1 + WORD_REG(di)] )
579 AS2( movdqa xmm2, XMMWORD_PTR [MUL_TABLE_1 + WORD_REG(di)] )
581 #define SSE2_MUL_32BITS(i) \
582 AS2( psrldq xmm0, 4 )\
583 AS2( movd eax, xmm0 )\
584 AS2( and eax, AS_HEX(f0f0f0f0) )\
585 AS2( movzx edi, bh )\
586 AS2( pxor xmm5, XMMWORD_PTR [MUL_TABLE_0 + (i-1)*256 + WORD_REG(di)] )\
587 AS2( movzx edi, bl )\
588 AS2( pxor xmm4, XMMWORD_PTR [MUL_TABLE_0 + (i-1)*256 + WORD_REG(di)] )\
590 AS2( movzx edi, bh )\
591 AS2( pxor xmm3, XMMWORD_PTR [MUL_TABLE_0 + (i-1)*256 + WORD_REG(di)] )\
592 AS2( movzx edi, bl )\
593 AS2( pxor xmm2, XMMWORD_PTR [MUL_TABLE_0 + (i-1)*256 + WORD_REG(di)] )\
594 AS2( movd ebx, xmm0 )\
596 AS2( and ebx, AS_HEX(f0f0f0f0) )\
597 AS2( movzx edi, ah )\
598 AS2( pxor xmm5, XMMWORD_PTR [MUL_TABLE_1 + i*256 + WORD_REG(di)] )\
599 AS2( movzx edi, al )\
600 AS2( pxor xmm4, XMMWORD_PTR [MUL_TABLE_1 + i*256 + WORD_REG(di)] )\
602 AS2( movzx edi, ah )\
603 AS2( pxor xmm3, XMMWORD_PTR [MUL_TABLE_1 + i*256 + WORD_REG(di)] )\
604 AS2( movzx edi, al )\
605 AS2( pxor xmm2, XMMWORD_PTR [MUL_TABLE_1 + i*256 + WORD_REG(di)] )\
612 AS2( pxor xmm5, XMMWORD_PTR [MUL_TABLE_0 + 3*256 + WORD_REG(di)] )
614 AS2( pxor xmm4, XMMWORD_PTR [MUL_TABLE_0 + 3*256 + WORD_REG(di)] )
617 AS2( pxor xmm3, XMMWORD_PTR [MUL_TABLE_0 + 3*256 + WORD_REG(di)] )
619 AS2( pxor xmm2, XMMWORD_PTR [MUL_TABLE_0 + 3*256 + WORD_REG(di)] )
621 AS2( movdqa xmm0, xmm3 )
622 AS2( pslldq xmm3, 1 )
623 AS2( pxor xmm2, xmm3 )
624 AS2( movdqa xmm1, xmm2 )
625 AS2( pslldq xmm2, 1 )
626 AS2( pxor xmm5, xmm2 )
628 AS2( psrldq xmm0, 15 )
630 AS2( movd edi, xmm0 )
631 #elif USE_MOV_REG32_OR_REG64
632 AS2( mov WORD_REG(di), xmm0 )
634 AS2( movd WORD_REG(di), xmm0 )
636 AS2( movzx eax, WORD PTR [RED_TABLE + WORD_REG(di)*2] )
639 AS2( movdqa xmm0, xmm5 )
640 AS2( pslldq xmm5, 1 )
641 AS2( pxor xmm4, xmm5 )
643 AS2( psrldq xmm1, 15 )
645 AS2( movd edi, xmm1 )
646 #elif USE_MOV_REG32_OR_REG64
647 AS2( mov WORD_REG(di), xmm1 )
649 AS2( movd WORD_REG(di), xmm1 )
651 AS2( xor ax, WORD PTR [RED_TABLE + WORD_REG(di)*2] )
654 AS2( psrldq xmm0, 15 )
656 AS2( movd edi, xmm0 )
657 #elif USE_MOV_REG32_OR_REG64
658 AS2( mov WORD_REG(di), xmm0 )
660 AS2( movd WORD_REG(di), xmm0 )
662 AS2( xor ax, WORD PTR [RED_TABLE + WORD_REG(di)*2] )
664 AS2( movd xmm0, eax )
665 AS2( pxor xmm0, xmm4 )
667 AS2( add WORD_REG(cx), 16 )
668 AS2( sub WORD_REG(dx), 1 )
672 AS2( movdqa [WORD_REG(si)], xmm0 )
674 #
if CRYPTOPP_BOOL_X32
685 :
"c" (data),
"d" (len/16),
"S" (hashBuffer),
"D" (s_reductionTable)
686 :
"memory",
"cc",
"%eax" 687 #
if CRYPTOPP_BOOL_X64
691 #elif defined(CRYPTOPP_GENERATE_X64_MASM) 696 GCM_AuthenticateBlocks_2K ENDP
707 #elif defined(CRYPTOPP_GENERATE_X64_MASM)
709 GCM_AuthenticateBlocks_64K PROC FRAME
715 AS2( mov WORD_REG(cx), data )
716 AS2( mov WORD_REG(dx), len )
717 AS2( mov WORD_REG(si), hashBuffer )
718 AS2( shr WORD_REG(dx), 4 )
721 AS2( movdqa xmm0, [WORD_REG(si)] )
724 #define MUL_TABLE(i,j) WORD_REG(si) + 32 + (i*4+j)*256*16
727 AS2( movdqu xmm1, [WORD_REG(cx)] )
728 AS2( pxor xmm1, xmm0 )
729 AS2( pxor xmm0, xmm0 )
731 #undef SSE2_MUL_32BITS
732 #define SSE2_MUL_32BITS(i) \
733 AS2( movd eax, xmm1 )\
734 AS2( psrldq xmm1, 4 )\
735 AS2( movzx edi, al )\
736 AS2( add WORD_REG(di), WORD_REG(di) )\
737 AS2( pxor xmm0, [MUL_TABLE(i,0) + WORD_REG(di)*8] )\
738 AS2( movzx edi, ah )\
739 AS2( add WORD_REG(di), WORD_REG(di) )\
740 AS2( pxor xmm0, [MUL_TABLE(i,1) + WORD_REG(di)*8] )\
742 AS2( movzx edi, al )\
743 AS2( add WORD_REG(di), WORD_REG(di) )\
744 AS2( pxor xmm0, [MUL_TABLE(i,2) + WORD_REG(di)*8] )\
745 AS2( movzx edi, ah )\
746 AS2( add WORD_REG(di), WORD_REG(di) )\
747 AS2( pxor xmm0, [MUL_TABLE(i,3) + WORD_REG(di)*8] )\
754 AS2( add WORD_REG(cx), 16 )
755 AS2( sub WORD_REG(dx), 1 )
759 AS2( movdqa [WORD_REG(si)], xmm0 )
764 :
"c" (data),
"d" (len/16),
"S" (hashBuffer)
765 :
"memory",
"cc",
"%edi",
"%eax" 767 #elif defined(CRYPTOPP_GENERATE_X64_MASM) 771 GCM_AuthenticateBlocks_64K ENDP
777 #ifndef CRYPTOPP_GENERATE_X64_MASM 783 void GCM_Base::AuthenticateLastHeaderBlock()
785 if (m_bufferedDataLength > 0)
787 memset(m_buffer+m_bufferedDataLength, 0, HASH_BLOCKSIZE-m_bufferedDataLength);
788 m_bufferedDataLength = 0;
789 GCM_Base::AuthenticateBlocks(m_buffer, HASH_BLOCKSIZE);
793 void GCM_Base::AuthenticateLastConfidentialBlock()
795 GCM_Base::AuthenticateLastHeaderBlock();
797 GCM_Base::AuthenticateBlocks(m_buffer, HASH_BLOCKSIZE);
800 void GCM_Base::AuthenticateLastFooterBlock(
byte *mac,
size_t macSize)
803 ReverseHashBufferIfNeeded();
804 m_ctr.ProcessData(mac, HashBuffer(), macSize);
809 #endif // #ifndef CRYPTOPP_GENERATE_X64_MASM 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.
unsigned int OptimalDataAlignment() const
Provides input and output data alignment for optimal performance.
void IncrementCounterByOne(byte *inout, unsigned int size)
Performs an addition with carry on a block of bytes.
Library configuration file.
Access a block of memory.
byte order is little-endian
Interface for one direction (encryption or decryption) of a block cipher.
Use a table with 64K entries.
bool IsAlignedOn(const void *ptr, unsigned int alignment)
Determines whether ptr is aligned to a minimum value.
const char * TableSize()
int, in bytes
bool HasCLMUL()
Determines Carryless Multiply availability.
T ConditionalByteReverse(ByteOrder order, T value)
Reverses bytes in a value depending upon endianness.
std::string AlgorithmName() const
Provides the name of this algorithm.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
const char * BlockSize()
int, in bytes
Functions for CPU features and intrinsics.
bool HasSSE2()
Determines SSE2 availability.
GCM block cipher mode of operation.
Access a block of memory.
Crypto++ library namespace.
bool GetIntValue(const char *name, int &value) const
Get a named value with type int.
byte ByteReverse(byte value)
Reverses bytes in a 8-bit value.
bool HasPMULL()
Determine if an ARM processor provides Polynomial Multiplication.
bool HasNEON()
Determine if an ARM processor has Advanced SIMD available.
Interface for retrieving values given their names.