8 #if CRYPTOPP_MSC_VERSION 9 # pragma warning(disable: 4189) 12 #ifndef CRYPTOPP_IMPORTS 13 #ifndef CRYPTOPP_GENERATE_X64_MASM 16 #if (defined(CRYPTOPP_LLVM_CLANG_VERSION) && (CRYPTOPP_LLVM_CLANG_VERSION < 30400)) 17 # undef CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 22 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x513) 23 # undef CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE 32 #if (CRYPTOPP_LLVM_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000) || defined(CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER) 34 # define USE_MOVD_REG32 1 35 #elif (defined(CRYPTOPP_LLVM_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)) && defined(CRYPTOPP_X64_ASM_AVAILABLE) 37 # define USE_MOVD_REG32_OR_REG64 1 38 #elif defined(__GNUC__) || defined(_MSC_VER) 40 # define USE_MOVD_REG32_OR_REG64 1 43 # define USE_MOV_REG32_OR_REG64 1 56 void gcm_gf_mult(
const unsigned char *
a,
const unsigned char *
b,
unsigned char *
c)
63 for (
int i=0; i<16; i++)
65 for (
int j=0x80; j!=0; j>>=1)
71 V1 = (V1>>1) | (
V0<<63);
78 __m128i _mm_clmulepi64_si128(
const __m128i &a,
const __m128i &b,
int i)
88 for (
int i=0; i<16; i++)
94 #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE || CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 95 inline static void SSE2_Xor16(
byte *a,
const byte *b,
const byte *c)
100 *(__m128i *)(
void *)a = _mm_xor_si128(*(__m128i *)(
void *)b, *(__m128i *)(
void *)c);
101 # elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 105 *(__m128i *)(
void *)a = _mm_xor_si128(*(__m128i *)(
void *)b, *(__m128i *)(
void *)c);
107 asm (
"movdqa %1, %%xmm0; pxor %2, %%xmm0; movdqa %%xmm0, %0;" :
"=m" (a[0]) :
"m"(b[0]),
"m"(c[0]));
112 #if CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE 113 inline static void NEON_Xor16(
byte *a,
const byte *b,
const byte *c)
118 *(uint64x2_t*)a = veorq_u64(*(uint64x2_t*)
b, *(uint64x2_t*)c);
122 inline static void Xor16(
byte *a,
const byte *b,
const byte *c)
131 #if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE 133 static const word64 s_clmulConstants64[] = {
136 W64LIT(0x0001020304050607),
W64LIT(0x08090a0b0c0d0e0f)};
138 static const __m128i *s_clmulConstants = (
const __m128i *)(
const void *)s_clmulConstants64;
139 static const unsigned int s_clmulTableSizeInBlocks = 8;
141 inline __m128i CLMUL_Reduce(__m128i c0, __m128i c1, __m128i c2,
const __m128i &r)
155 #if 0 // MSVC 2010 workaround: see http://connect.microsoft.com/VisualStudio/feedback/details/575301 156 c2 = _mm_xor_si128(c2, _mm_move_epi64(c0));
158 c1 = _mm_xor_si128(c1, _mm_slli_si128(c0, 8));
160 c1 = _mm_xor_si128(c1, _mm_clmulepi64_si128(c0, r, 0x10));
161 c0 = _mm_srli_si128(c0, 8);
162 c0 = _mm_xor_si128(c0, c1);
163 c0 = _mm_slli_epi64(c0, 1);
164 c0 = _mm_clmulepi64_si128(c0, r, 0);
165 c2 = _mm_xor_si128(c2, c0);
166 c2 = _mm_xor_si128(c2, _mm_srli_si128(c1, 8));
167 c1 = _mm_unpacklo_epi64(c1, c2);
168 c1 = _mm_srli_epi64(c1, 63);
169 c2 = _mm_slli_epi64(c2, 1);
170 return _mm_xor_si128(c2, c1);
173 inline __m128i CLMUL_GF_Mul(
const __m128i &
x,
const __m128i &
h,
const __m128i &r)
175 const __m128i c0 = _mm_clmulepi64_si128(x,h,0);
176 const __m128i c1 = _mm_xor_si128(_mm_clmulepi64_si128(x,h,1), _mm_clmulepi64_si128(x,h,0x10));
177 const __m128i c2 = _mm_clmulepi64_si128(x,h,0x11);
179 return CLMUL_Reduce(c0, c1, c2, r);
183 #if CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE 186 static const word64 s_clmulConstants64[] = {
192 static const uint64x2_t *s_clmulConstants = (
const uint64x2_t *)s_clmulConstants64;
193 static const unsigned int s_clmulTableSizeInBlocks = 8;
195 inline uint64x2_t PMULL_Reduce(uint64x2_t c0, uint64x2_t c1, uint64x2_t c2,
const uint64x2_t &r)
199 c1 = veorq_u64(c1, (uint64x2_t)vextq_u8(vdupq_n_u8(0), (uint8x16_t)c0, 8));
200 c1 = veorq_u64(c1, (uint64x2_t)vmull_p64(vgetq_lane_u64(c0, 0), vgetq_lane_u64(r, 1)));
201 c0 = (uint64x2_t)vextq_u8((uint8x16_t)c0, vdupq_n_u8(0), 8);
202 c0 = veorq_u64(c0, c1);
203 c0 = vshlq_n_u64(c0, 1);
204 c0 = (uint64x2_t)vmull_p64(vgetq_lane_u64(c0, 0), vgetq_lane_u64(r, 0));
205 c2 = veorq_u64(c2, c0);
206 c2 = veorq_u64(c2, (uint64x2_t)vextq_u8((uint8x16_t)c1, vdupq_n_u8(0), 8));
207 c1 = vcombine_u64(vget_low_u64(c1), vget_low_u64(c2));
208 c1 = vshrq_n_u64(c1, 63);
209 c2 = vshlq_n_u64(c2, 1);
211 return veorq_u64(c2, c1);
214 inline uint64x2_t PMULL_GF_Mul(
const uint64x2_t &x,
const uint64x2_t &h,
const uint64x2_t &r)
216 const uint64x2_t c0 = (uint64x2_t)vmull_p64(vgetq_lane_u64(x, 0), vgetq_lane_u64(h, 0));
217 const uint64x2_t c1 = veorq_u64((uint64x2_t)vmull_p64(vgetq_lane_u64(x, 1), vgetq_lane_u64(h,0)),
218 (uint64x2_t)vmull_p64(vgetq_lane_u64(x, 0), vgetq_lane_u64(h, 1)));
219 const uint64x2_t c2 = (uint64x2_t)vmull_high_p64((poly64x2_t)
x, (poly64x2_t)h);
221 return PMULL_Reduce(c0, c1, c2, r);
228 blockCipher.
SetKey(userKey, keylength, params);
233 int tableSize, i, j, k;
235 #if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE 239 (void)params.
GetIntValue(Name::TableSize(), tableSize);
243 #elif CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE 247 (void)params.
GetIntValue(Name::TableSize(), tableSize);
253 if (params.
GetIntValue(Name::TableSize(), tableSize))
254 tableSize = (tableSize >= 64*1024) ? 64*1024 : 2*1024;
258 #if defined(_MSC_VER) && (_MSC_VER < 1400) 270 #if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE 273 const __m128i r = s_clmulConstants[0];
274 __m128i
h0 = _mm_shuffle_epi8(_mm_load_si128((__m128i *)(
void *)hashKey), s_clmulConstants[1]);
277 for (i=0; i<tableSize; i+=32)
279 __m128i
h1 = CLMUL_GF_Mul(h, h0, r);
280 _mm_storel_epi64((__m128i *)(
void *)(table+i), h);
281 _mm_storeu_si128((__m128i *)(
void *)(table+i+16), h1);
282 _mm_storeu_si128((__m128i *)(
void *)(table+i+8), h);
283 _mm_storel_epi64((__m128i *)(
void *)(table+i+8), h1);
284 h = CLMUL_GF_Mul(h1, h0, r);
289 #elif CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE 292 const uint64x2_t r = s_clmulConstants[0];
293 const uint64x2_t t = vld1q_u64((uint64_t *)hashKey);
294 const uint64x2_t
h0 = (uint64x2_t)vrev64q_u8((uint8x16_t)vcombine_u64(vget_high_u64(t), vget_low_u64(t)));
297 for (i=0; i<tableSize-32; i+=32)
299 const uint64x2_t
h1 = PMULL_GF_Mul(h, h0, r);
300 vst1_u64((uint64_t *)(table+i), vget_low_u64(h));
301 vst1q_u64((uint64_t *)(table+i+16), h1);
302 vst1q_u64((uint64_t *)(table+i+8), h);
303 vst1_u64((uint64_t *)(table+i+8), vget_low_u64(h1));
304 h = PMULL_GF_Mul(h1, h0, r);
307 const uint64x2_t
h1 = PMULL_GF_Mul(h, h0, r);
308 vst1_u64((uint64_t *)(table+i), vget_low_u64(h));
309 vst1q_u64((uint64_t *)(table+i+16), h1);
310 vst1q_u64((uint64_t *)(table+i+8), h);
311 vst1_u64((uint64_t *)(table+i+8), vget_low_u64(h1));
321 if (tableSize == 64*1024)
323 for (i=0; i<128; i++)
326 Block::Put(NULL, table+(i/8)*256*16+(
size_t(1)<<(11-k)))(
V0)(V1);
329 V1 = (V1>>1) | (V0<<63);
330 V0 = (V0>>1) ^ (x ?
W64LIT(0xe1) << 56 : 0);
335 memset(table+i*256*16, 0, 16);
336 #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE || CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 338 for (j=2; j<=0x80; j*=2)
340 SSE2_Xor16(table+i*256*16+(j+k)*16, table+i*256*16+j*16, table+i*256*16+k*16);
342 #elif CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE 344 for (j=2; j<=0x80; j*=2)
346 NEON_Xor16(table+i*256*16+(j+k)*16, table+i*256*16+j*16, table+i*256*16+k*16);
349 for (j=2; j<=0x80; j*=2)
351 Xor16(table+i*256*16+(j+k)*16, table+i*256*16+j*16, table+i*256*16+k*16);
361 for (
unsigned int ii=2; ii<=0x80; ii*=2)
365 for (
unsigned int jj=1; jj<ii; jj++)
371 for (i=0; i<128-24; i++)
375 Block::Put(NULL, table+1024+(i/32)*256+(
size_t(1)<<(7-k)))(
V0)(V1);
377 Block::Put(NULL, table+(i/32)*256+(
size_t(1)<<(11-k)))(
V0)(V1);
380 V1 = (V1>>1) | (V0<<63);
381 V0 = (V0>>1) ^ (x ?
W64LIT(0xe1) << 56 : 0);
386 memset(table+i*256, 0, 16);
387 memset(table+1024+i*256, 0, 16);
388 #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE || CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 390 for (j=2; j<=8; j*=2)
393 SSE2_Xor16(table+i*256+(j+k)*16, table+i*256+j*16, table+i*256+k*16);
394 SSE2_Xor16(table+1024+i*256+(j+k)*16, table+1024+i*256+j*16, table+1024+i*256+k*16);
397 #elif CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE 399 for (j=2; j<=8; j*=2)
402 NEON_Xor16(table+i*256+(j+k)*16, table+i*256+j*16, table+i*256+k*16);
403 NEON_Xor16(table+1024+i*256+(j+k)*16, table+1024+i*256+j*16, table+1024+i*256+k*16);
407 for (j=2; j<=8; j*=2)
410 Xor16(table+i*256+(j+k)*16, table+i*256+j*16, table+i*256+k*16);
411 Xor16(table+1024+i*256+(j+k)*16, table+1024+i*256+j*16, table+1024+i*256+k*16);
419 #if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE 422 __m128i &x = *(__m128i *)(
void *)
HashBuffer();
423 x = _mm_shuffle_epi8(x, s_clmulConstants[1]);
425 #elif CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE 430 const uint8x16_t x = vrev64q_u8(vld1q_u8(
HashBuffer()));
431 vst1q_u8(
HashBuffer(), (uint8x16_t)vcombine_u64(vget_high_u64((uint64x2_t)x), vget_low_u64((uint64x2_t)x)));
444 memcpy(hashBuffer, iv, len);
445 memset(hashBuffer+len, 0, 3);
446 hashBuffer[len+3] = 1;
450 size_t origLen = len;
456 iv += (origLen - len);
485 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE) 487 #elif CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE 493 #if CRYPTOPP_MSC_VERSION 494 # pragma warning(disable: 4731) // frame pointer register 'ebp' modified by inline assembly code 497 #endif // #ifndef CRYPTOPP_GENERATE_X64_MASM 499 #ifdef CRYPTOPP_X64_MASM_AVAILABLE 501 void GCM_AuthenticateBlocks_2K(
const byte *
data,
size_t blocks,
word64 *hashBuffer,
const word16 *reductionTable);
502 void GCM_AuthenticateBlocks_64K(
const byte *data,
size_t blocks,
word64 *hashBuffer);
506 #ifndef CRYPTOPP_GENERATE_X64_MASM 510 #if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE 513 const __m128i *table = (
const __m128i *)(
const void *)
MulTable();
514 __m128i x = _mm_load_si128((__m128i *)(
void *)
HashBuffer());
515 const __m128i r = s_clmulConstants[0], mask1 = s_clmulConstants[1], mask2 = s_clmulConstants[2];
519 size_t s =
UnsignedMin(len/16, s_clmulTableSizeInBlocks), i=0;
520 __m128i
d, d2 = _mm_shuffle_epi8(_mm_loadu_si128((
const __m128i *)(
const void *)(data+(s-1)*16)), mask2);;
521 __m128i c0 = _mm_setzero_si128();
522 __m128i c1 = _mm_setzero_si128();
523 __m128i c2 = _mm_setzero_si128();
527 __m128i
h0 = _mm_load_si128(table+i);
528 __m128i
h1 = _mm_load_si128(table+i+1);
529 __m128i
h2 = _mm_xor_si128(h0, h1);
533 d = _mm_shuffle_epi8(_mm_loadu_si128((
const __m128i *)(
const void *)data), mask1);
534 d = _mm_xor_si128(d, x);
535 c0 = _mm_xor_si128(c0, _mm_clmulepi64_si128(d, h0, 0));
536 c2 = _mm_xor_si128(c2, _mm_clmulepi64_si128(d, h1, 1));
537 d = _mm_xor_si128(d, _mm_shuffle_epi32(d, _MM_SHUFFLE(1, 0, 3, 2)));
538 c1 = _mm_xor_si128(c1, _mm_clmulepi64_si128(d, h2, 0));
542 d = _mm_shuffle_epi8(_mm_loadu_si128((
const __m128i *)(
const void *)(data+(s-i)*16-8)), mask2);
543 c0 = _mm_xor_si128(c0, _mm_clmulepi64_si128(d2, h0, 1));
544 c2 = _mm_xor_si128(c2, _mm_clmulepi64_si128(d, h1, 1));
545 d2 = _mm_xor_si128(d2, d);
546 c1 = _mm_xor_si128(c1, _mm_clmulepi64_si128(d2, h2, 1));
550 d = _mm_shuffle_epi8(_mm_loadu_si128((
const __m128i *)(
const void *)data), mask1);
551 d = _mm_xor_si128(d, x);
552 c0 = _mm_xor_si128(c0, _mm_clmulepi64_si128(d, h0, 0x10));
553 c2 = _mm_xor_si128(c2, _mm_clmulepi64_si128(d, h1, 0x11));
554 d = _mm_xor_si128(d, _mm_shuffle_epi32(d, _MM_SHUFFLE(1, 0, 3, 2)));
555 c1 = _mm_xor_si128(c1, _mm_clmulepi64_si128(d, h2, 0x10));
559 d2 = _mm_shuffle_epi8(_mm_loadu_si128((
const __m128i *)(
const void *)(data+(s-i)*16-8)), mask1);
560 c0 = _mm_xor_si128(c0, _mm_clmulepi64_si128(d, h0, 0x10));
561 c2 = _mm_xor_si128(c2, _mm_clmulepi64_si128(d2, h1, 0x10));
562 d = _mm_xor_si128(d, d2);
563 c1 = _mm_xor_si128(c1, _mm_clmulepi64_si128(d, h2, 0x10));
568 c1 = _mm_xor_si128(_mm_xor_si128(c1, c0), c2);
569 x = CLMUL_Reduce(c0, c1, c2, r);
572 _mm_store_si128((__m128i *)(
void *)
HashBuffer(), x);
575 #elif CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE 578 const uint64x2_t *table = (
const uint64x2_t *)
MulTable();
579 uint64x2_t x = vld1q_u64((
const uint64_t*)
HashBuffer());
580 const uint64x2_t r = s_clmulConstants[0];
584 size_t s =
UnsignedMin(len/16, s_clmulTableSizeInBlocks), i=0;
585 uint64x2_t
d, d2 = (uint64x2_t)vrev64q_u8((uint8x16_t)vld1q_u64((
const uint64_t *)(data+(s-1)*16)));
586 uint64x2_t c0 = vdupq_n_u64(0);
587 uint64x2_t c1 = vdupq_n_u64(0);
588 uint64x2_t c2 = vdupq_n_u64(0);
592 const uint64x2_t
h0 = vld1q_u64((
const uint64_t*)(table+i));
593 const uint64x2_t
h1 = vld1q_u64((
const uint64_t*)(table+i+1));
594 const uint64x2_t
h2 = veorq_u64(h0, h1);
598 const uint64x2_t
t1 = vld1q_u64((
const uint64_t *)data);
599 d = veorq_u64((uint64x2_t)vrev64q_u8((uint8x16_t)vcombine_u64(vget_high_u64(t1), vget_low_u64(t1))), x);
600 c0 = veorq_u64(c0, (uint64x2_t)vmull_p64(vgetq_lane_u64(d, 0), vgetq_lane_u64(h0, 0)));
601 c2 = veorq_u64(c2, (uint64x2_t)vmull_p64(vgetq_lane_u64(d, 1), vgetq_lane_u64(h1, 0)));
602 d = veorq_u64(d, (uint64x2_t)vcombine_u32(vget_high_u32((uint32x4_t)d), vget_low_u32((uint32x4_t)d)));
603 c1 = veorq_u64(c1, (uint64x2_t)vmull_p64(vgetq_lane_u64(d, 0), vgetq_lane_u64(h2, 0)));
608 d = (uint64x2_t)vrev64q_u8((uint8x16_t)vld1q_u64((
const uint64_t *)(data+(s-i)*16-8)));
609 c0 = veorq_u64(c0, (uint64x2_t)vmull_p64(vgetq_lane_u64(d2, 1), vgetq_lane_u64(h0, 0)));
610 c2 = veorq_u64(c2, (uint64x2_t)vmull_p64(vgetq_lane_u64(d, 1), vgetq_lane_u64(h1, 0)));
611 d2 = veorq_u64(d2, d);
612 c1 = veorq_u64(c1, (uint64x2_t)vmull_p64(vgetq_lane_u64(d2, 1), vgetq_lane_u64(h2, 0)));
617 const uint64x2_t
t2 = vld1q_u64((
const uint64_t *)data);
618 d = veorq_u64((uint64x2_t)vrev64q_u8((uint8x16_t)vcombine_u64(vget_high_u64(t2), vget_low_u64(t2))), x);
619 c0 = veorq_u64(c0, (uint64x2_t)vmull_p64(vgetq_lane_u64(d, 0), vgetq_lane_u64(h0, 1)));
620 c2 = veorq_u64(c2, (uint64x2_t)vmull_high_p64((poly64x2_t)d, (poly64x2_t)h1));
621 d = veorq_u64(d, (uint64x2_t)vcombine_u32(vget_high_u32((uint32x4_t)d), vget_low_u32((uint32x4_t)d)));
622 c1 = veorq_u64(c1, (uint64x2_t)vmull_p64(vgetq_lane_u64(d, 0), vgetq_lane_u64(h2, 1)));
627 const uint64x2_t
t3 = vld1q_u64((uint64_t *)(data+(s-i)*16-8));
628 d2 = (uint64x2_t)vrev64q_u8((uint8x16_t)vcombine_u64(vget_high_u64(t3), vget_low_u64(t3)));
629 c0 = veorq_u64(c0, (uint64x2_t)vmull_p64(vgetq_lane_u64(d, 0), vgetq_lane_u64(h0, 1)));
630 c2 = veorq_u64(c2, (uint64x2_t)vmull_p64(vgetq_lane_u64(d2, 0), vgetq_lane_u64(h1, 1)));
631 d = veorq_u64(d, d2);
632 c1 = veorq_u64(c1, (uint64x2_t)vmull_p64(vgetq_lane_u64(d, 0), vgetq_lane_u64(h2, 1)));
637 c1 = veorq_u64(veorq_u64(c1, c0), c2);
638 x = PMULL_Reduce(c0, c1, c2, r);
651 #
if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE)
661 word64 x0 = hashBuffer[0], x1 = hashBuffer[1];
665 word64 y0, y1,
a0,
a1, b0, b1, c0, c1, d0, d1;
673 #define READ_TABLE_WORD64_COMMON(a, b, c, d) *(word64 *)(void *)(table+(a*1024)+(b*256)+c+d*8) 675 #ifdef IS_LITTLE_ENDIAN 676 #if CRYPTOPP_BOOL_SLOW_WORD64 681 #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) 683 #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) 685 #define GF_MOST_SIG_8BITS(a) (a##1 >> 7*8) 686 #define GF_SHIFT_8(a) a##1 = (a##1 << 8) ^ (a##0 >> 7*8); a##0 <<= 8; 688 #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) 689 #define GF_MOST_SIG_8BITS(a) (a##1 & 0xff) 690 #define GF_SHIFT_8(a) a##1 = (a##1 >> 8) ^ (a##0 << 7*8); a##0 >>= 8; 693 #define GF_MUL_32BY128(op, a, b, c) \ 694 a0 op READ_TABLE_WORD64(a, b, c, 0, 0) ^ READ_TABLE_WORD64(a, b, c, 1, 0);\ 695 a1 op READ_TABLE_WORD64(a, b, c, 0, 1) ^ READ_TABLE_WORD64(a, b, c, 1, 1);\ 696 b0 op READ_TABLE_WORD64(a, b, c, 2, 0) ^ READ_TABLE_WORD64(a, b, c, 3, 0);\ 697 b1 op READ_TABLE_WORD64(a, b, c, 2, 1) ^ READ_TABLE_WORD64(a, b, c, 3, 1);\ 698 c0 op READ_TABLE_WORD64(a, b, c, 4, 0) ^ READ_TABLE_WORD64(a, b, c, 5, 0);\ 699 c1 op READ_TABLE_WORD64(a, b, c, 4, 1) ^ READ_TABLE_WORD64(a, b, c, 5, 1);\ 700 d0 op READ_TABLE_WORD64(a, b, c, 6, 0) ^ READ_TABLE_WORD64(a, b, c, 7, 0);\ 701 d1 op READ_TABLE_WORD64(a, b, c, 6, 1) ^ READ_TABLE_WORD64(a, b, c, 7, 1);\ 722 hashBuffer[0] = x0; hashBuffer[1] = x1;
729 word64 x0 = hashBuffer[0], x1 = hashBuffer[1];
741 #undef READ_TABLE_WORD64_COMMON 742 #undef READ_TABLE_WORD64 744 #define READ_TABLE_WORD64_COMMON(a, c, d) *(word64 *)(void *)(table+(a)*256*16+(c)+(d)*8) 746 #ifdef IS_LITTLE_ENDIAN 747 #if CRYPTOPP_BOOL_SLOW_WORD64 752 #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) 754 #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) 757 #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) 760 #define GF_MUL_8BY128(op, b, c, d) \ 761 a0 op READ_TABLE_WORD64(b, c, d, 0);\ 762 a1 op READ_TABLE_WORD64(b, c, d, 1);\ 785 hashBuffer[0] = x0; hashBuffer[1] = x1;
788 #endif // #ifndef CRYPTOPP_GENERATE_X64_MASM 790 #ifdef CRYPTOPP_X64_MASM_AVAILABLE 795 GCM_AuthenticateBlocks_64K(data, len/16, hashBuffer);
799 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 806 #elif defined(CRYPTOPP_GENERATE_X64_MASM)
808 GCM_AuthenticateBlocks_2K PROC FRAME
816 AS2( mov WORD_REG(cx), data )
817 AS2( mov WORD_REG(dx), len )
818 AS2( mov WORD_REG(si), hashBuffer )
819 AS2(
shr WORD_REG(dx), 4 )
831 AS2( mov AS_REG_7, WORD_REG(di))
836 AS2( movdqa xmm0, [WORD_REG(si)] )
838 #define MUL_TABLE_0 WORD_REG(si) + 32
839 #define MUL_TABLE_1 WORD_REG(si) + 32 + 1024
840 #define RED_TABLE AS_REG_7
843 AS2( movdqu xmm4, [WORD_REG(cx)] )
844 AS2( pxor xmm0, xmm4 )
846 AS2( movd ebx, xmm0 )
847 AS2( mov eax, AS_HEX(f0f0f0f0) )
850 AS2( and ebx, AS_HEX(f0f0f0f0) )
852 AS2( movdqa xmm5, XMMWORD_PTR [MUL_TABLE_1 + WORD_REG(di)] )
854 AS2( movdqa xmm4, XMMWORD_PTR [MUL_TABLE_1 + WORD_REG(di)] )
857 AS2( movdqa xmm3, XMMWORD_PTR [MUL_TABLE_1 + WORD_REG(di)] )
859 AS2( movdqa xmm2, XMMWORD_PTR [MUL_TABLE_1 + WORD_REG(di)] )
861 #define SSE2_MUL_32BITS(i) \
862 AS2( psrldq xmm0, 4 )\
863 AS2( movd eax, xmm0 )\
864 AS2( and eax, AS_HEX(f0f0f0f0) )\
865 AS2( movzx edi, bh )\
866 AS2( pxor xmm5, XMMWORD_PTR [MUL_TABLE_0 + (i-1)*256 + WORD_REG(di)] )\
867 AS2( movzx edi, bl )\
868 AS2( pxor xmm4, XMMWORD_PTR [MUL_TABLE_0 + (i-1)*256 + WORD_REG(di)] )\
870 AS2( movzx edi, bh )\
871 AS2( pxor xmm3, XMMWORD_PTR [MUL_TABLE_0 + (i-1)*256 + WORD_REG(di)] )\
872 AS2( movzx edi, bl )\
873 AS2( pxor xmm2, XMMWORD_PTR [MUL_TABLE_0 + (i-1)*256 + WORD_REG(di)] )\
874 AS2( movd ebx, xmm0 )\
876 AS2( and ebx, AS_HEX(f0f0f0f0) )\
877 AS2( movzx edi, ah )\
878 AS2( pxor xmm5, XMMWORD_PTR [MUL_TABLE_1 + i*256 + WORD_REG(di)] )\
879 AS2( movzx edi, al )\
880 AS2( pxor xmm4, XMMWORD_PTR [MUL_TABLE_1 + i*256 + WORD_REG(di)] )\
882 AS2( movzx edi, ah )\
883 AS2( pxor xmm3, XMMWORD_PTR [MUL_TABLE_1 + i*256 + WORD_REG(di)] )\
884 AS2( movzx edi, al )\
885 AS2( pxor xmm2, XMMWORD_PTR [MUL_TABLE_1 + i*256 + WORD_REG(di)] )\
892 AS2( pxor xmm5, XMMWORD_PTR [MUL_TABLE_0 + 3*256 + WORD_REG(di)] )
894 AS2( pxor xmm4, XMMWORD_PTR [MUL_TABLE_0 + 3*256 + WORD_REG(di)] )
897 AS2( pxor xmm3, XMMWORD_PTR [MUL_TABLE_0 + 3*256 + WORD_REG(di)] )
899 AS2( pxor xmm2, XMMWORD_PTR [MUL_TABLE_0 + 3*256 + WORD_REG(di)] )
901 AS2( movdqa xmm0, xmm3 )
902 AS2( pslldq xmm3, 1 )
903 AS2( pxor xmm2, xmm3 )
904 AS2( movdqa xmm1, xmm2 )
905 AS2( pslldq xmm2, 1 )
906 AS2( pxor xmm5, xmm2 )
908 AS2( psrldq xmm0, 15 )
910 AS2( movd edi, xmm0 )
912 AS2( mov WORD_REG(di), xmm0 )
914 AS2( movd WORD_REG(di), xmm0 )
916 AS2( movzx eax, WORD PTR [RED_TABLE + WORD_REG(di)*2] )
919 AS2( movdqa xmm0, xmm5 )
920 AS2( pslldq xmm5, 1 )
921 AS2( pxor xmm4, xmm5 )
923 AS2( psrldq xmm1, 15 )
925 AS2( movd edi, xmm1 )
927 AS2( mov WORD_REG(di), xmm1 )
929 AS2( movd WORD_REG(di), xmm1 )
931 AS2( xor ax, WORD PTR [RED_TABLE + WORD_REG(di)*2] )
934 AS2( psrldq xmm0, 15 )
936 AS2( movd edi, xmm0 )
938 AS2( mov WORD_REG(di), xmm0 )
940 AS2( movd WORD_REG(di), xmm0 )
942 AS2( xor ax, WORD PTR [RED_TABLE + WORD_REG(di)*2] )
944 AS2( movd xmm0, eax )
945 AS2( pxor xmm0, xmm4 )
947 AS2( add WORD_REG(cx), 16 )
948 AS2( sub WORD_REG(dx), 1 )
952 AS2( movdqa [WORD_REG(si)], xmm0 )
966 :
"memory",
"cc",
"%eax" 971 #elif defined(CRYPTOPP_GENERATE_X64_MASM) 976 GCM_AuthenticateBlocks_2K ENDP
987 #elif defined(CRYPTOPP_GENERATE_X64_MASM)
989 GCM_AuthenticateBlocks_64K PROC FRAME
995 AS2( mov WORD_REG(cx), data )
996 AS2( mov WORD_REG(dx), len )
997 AS2( mov WORD_REG(si), hashBuffer )
998 AS2(
shr WORD_REG(dx), 4 )
1001 AS2( movdqa xmm0, [WORD_REG(si)] )
1004 #define MUL_TABLE(i,j) WORD_REG(si) + 32 + (i*4+j)*256*16
1007 AS2( movdqu xmm1, [WORD_REG(cx)] )
1008 AS2( pxor xmm1, xmm0 )
1009 AS2( pxor xmm0, xmm0 )
1011 #undef SSE2_MUL_32BITS
1012 #define SSE2_MUL_32BITS(i) \
1013 AS2( movd eax, xmm1 )\
1014 AS2( psrldq xmm1, 4 )\
1015 AS2( movzx edi, al )\
1016 AS2( add WORD_REG(di), WORD_REG(di) )\
1017 AS2( pxor xmm0, [MUL_TABLE(i,0) + WORD_REG(di)*8] )\
1018 AS2( movzx edi, ah )\
1019 AS2( add WORD_REG(di), WORD_REG(di) )\
1020 AS2( pxor xmm0, [MUL_TABLE(i,1) + WORD_REG(di)*8] )\
1022 AS2( movzx edi, al )\
1023 AS2( add WORD_REG(di), WORD_REG(di) )\
1024 AS2( pxor xmm0, [MUL_TABLE(i,2) + WORD_REG(di)*8] )\
1025 AS2( movzx edi, ah )\
1026 AS2( add WORD_REG(di), WORD_REG(di) )\
1027 AS2( pxor xmm0, [MUL_TABLE(i,3) + WORD_REG(di)*8] )\
1034 AS2( add WORD_REG(cx), 16 )
1035 AS2( sub WORD_REG(dx), 1 )
1039 AS2( movdqa [WORD_REG(si)], xmm0 )
1044 :
"c" (data),
"d" (len/16),
"S" (hashBuffer)
1045 :
"memory",
"cc",
"%edi",
"%eax" 1047 #elif defined(CRYPTOPP_GENERATE_X64_MASM) 1051 GCM_AuthenticateBlocks_64K ENDP
1057 #ifndef CRYPTOPP_GENERATE_X64_MASM 1089 #endif // #ifndef CRYPTOPP_GENERATE_X64_MASM
#define CRYPTOPP_BOOL_X64
An invalid argument was detected.
void AuthenticateLastFooterBlock(byte *mac, size_t macSize)
void Resynchronize(const byte *iv, int length=-1)
Resynchronize the cipher.
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.
void SetCipherWithIV(BlockCipher &cipher, const byte *iv, int feedbackSize=0)
const BlockCipher & GetBlockCipher() const
void resize(size_type newSize)
Change size and preserve contents.
#define NAMESPACE_BEGIN(x)
CRYPTOPP_DLL bool GetIntValue(const char *name, int &value) const
Get a named value with type int.
static GetBlock< T, B, GA > Get(const void *block)
size_type size() const
Provides the count of elements in the SecBlock.
#define GF_MOST_SIG_8BITS(a)
Library configuration file.
byte GetByte(size_t n) const
return the n-th byte
Access a block of memory.
byte order is little-endian
Polynomial with Coefficients in GF(2)
Interface for one direction (encryption or decryption) of a block cipher.
void Seek(lword position)
Seeks to a random position in the stream.
static word16 s_reductionTable[256]
Use a table with 64K entries.
bool IsAlignedOn(const void *ptr, unsigned int alignment)
Determines whether ptr is aligned to a minimum value.
void ProcessData(byte *outString, const byte *inString, size_t length)
Apply keystream to data.
void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms)
#define CRYPTOPP_ALIGN_DATA(x)
void Resync(const byte *iv, size_t len)
unsigned int OptimalDataAlignment() const
Provides input and output data alignment for optimal performance.
void ReverseHashBufferIfNeeded()
std::string AlgorithmName() const
Provides the name of this algorithm.
unsigned int m_bufferedDataLength
virtual BlockCipher & AccessBlockCipher()=0
uint32_t shr(uint32_t x, std::size_t n)
BlockGetAndPut< word32, BigEndian > Block
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be neagtive and incorrectly promoted.
unsigned long long word64
#define CRYPTOPP_ASSERT(exp)
Functions for CPU features and intrinsics.
#define USE_MOV_REG32_OR_REG64
void IncrementCounterBy256()
#define GF_MUL_8BY128(op, b, c, d)
#define CRYPTOPP_BOOL_X32
virtual GCM_TablesOption GetTablesOption() const =0
#define CRYPTOPP_BOOL_X86
void * memcpy(void *a, const void *b, size_t c)
lword m_totalHeaderLength
GCM block cipher mode of operation.
ByteOrder GetNativeByteOrder()
Returns NativeByteOrder as an enumerated ByteOrder value.
void AuthenticateLastConfidentialBlock()
lword m_totalMessageLength
Access a block of memory.
#define GF_MUL_32BY128(op, a, b, c)
size_t AuthenticateBlocks(const byte *data, size_t len)
static volatile bool s_reductionTableInitialized
byte ByteReverse(byte value)
Reverses bytes in a 8-bit value.
unsigned int BlockSize() const
AlignedSecByteBlock m_counterArray
Interface for retrieving values given their names.
void AuthenticateLastHeaderBlock()