Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

925 lines
26 KiB

  1. // sha.cpp - modified by Wei Dai from Steve Reid's public domain sha1.c
  2. // Steve Reid implemented SHA-1. Wei Dai implemented SHA-2.
  3. // Both are in the public domain.
  4. // use "cl /EP /P /DCRYPTOPP_GENERATE_X64_MASM sha.cpp" to generate MASM code
  5. #include "pch.h"
  6. #include "config.h"
  7. #if CRYPTOPP_MSC_VERSION
  8. # pragma warning(disable: 4100 4731)
  9. #endif
  10. #ifndef CRYPTOPP_IMPORTS
  11. #ifndef CRYPTOPP_GENERATE_X64_MASM
  12. #include "secblock.h"
  13. #include "sha.h"
  14. #include "misc.h"
  15. #include "cpu.h"
  16. NAMESPACE_BEGIN(CryptoPP)
  17. // start of Steve Reid's code
  18. #define blk0(i) (W[i] = data[i])
  19. #define blk1(i) (W[i&15] = rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1))
  20. void SHA1::InitState(HashWordType *state)
  21. {
  22. state[0] = 0x67452301L;
  23. state[1] = 0xEFCDAB89L;
  24. state[2] = 0x98BADCFEL;
  25. state[3] = 0x10325476L;
  26. state[4] = 0xC3D2E1F0L;
  27. }
  28. #define f1(x,y,z) (z^(x&(y^z)))
  29. #define f2(x,y,z) (x^y^z)
  30. #define f3(x,y,z) ((x&y)|(z&(x|y)))
  31. #define f4(x,y,z) (x^y^z)
  32. /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
  33. #define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
  34. #define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
  35. #define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rotlFixed(v,5);w=rotlFixed(w,30);
  36. #define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rotlFixed(v,5);w=rotlFixed(w,30);
  37. #define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rotlFixed(v,5);w=rotlFixed(w,30);
  38. void SHA1::Transform(word32 *state, const word32 *data)
  39. {
  40. word32 W[16];
  41. /* Copy context->state[] to working vars */
  42. word32 a = state[0];
  43. word32 b = state[1];
  44. word32 c = state[2];
  45. word32 d = state[3];
  46. word32 e = state[4];
  47. /* 4 rounds of 20 operations each. Loop unrolled. */
  48. R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
  49. R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
  50. R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
  51. R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
  52. R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
  53. R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
  54. R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
  55. R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
  56. R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
  57. R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
  58. R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
  59. R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
  60. R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
  61. R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
  62. R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
  63. R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
  64. R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
  65. R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
  66. R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
  67. R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
  68. /* Add the working vars back into context.state[] */
  69. state[0] += a;
  70. state[1] += b;
  71. state[2] += c;
  72. state[3] += d;
  73. state[4] += e;
  74. }
  75. // end of Steve Reid's code
  76. // *************************************************************
  77. void SHA224::InitState(HashWordType *state)
  78. {
  79. static const word32 s[8] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
  80. memcpy(state, s, sizeof(s));
  81. }
  82. void SHA256::InitState(HashWordType *state)
  83. {
  84. static const word32 s[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
  85. memcpy(state, s, sizeof(s));
  86. }
  87. #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
  88. CRYPTOPP_ALIGN_DATA(16) extern const word32 SHA256_K[64] CRYPTOPP_SECTION_ALIGN16 = {
  89. #else
  90. extern const word32 SHA256_K[64] = {
  91. #endif
  92. 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
  93. 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
  94. 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
  95. 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
  96. 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
  97. 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
  98. 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
  99. 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
  100. 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
  101. 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
  102. 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
  103. 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
  104. 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
  105. 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
  106. 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
  107. 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
  108. };
  109. #endif // #ifndef CRYPTOPP_GENERATE_X64_MASM
  110. #if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X32_ASM_AVAILABLE) || defined(CRYPTOPP_GENERATE_X64_MASM)
  111. static void CRYPTOPP_FASTCALL X86_SHA256_HashBlocks(word32 *state, const word32 *data, size_t len
  112. #if defined(_MSC_VER) && (_MSC_VER == 1200)
  113. , ... // VC60 workaround: prevent VC 6 from inlining this function
  114. #endif
  115. )
  116. {
  117. #if defined(_MSC_VER) && (_MSC_VER == 1200)
  118. AS2(mov ecx, [state])
  119. AS2(mov edx, [data])
  120. #endif
  121. #define LOCALS_SIZE 8*4 + 16*4 + 4*WORD_SZ
  122. #define H(i) [BASE+ASM_MOD(1024+7-(i),8)*4]
  123. #define G(i) H(i+1)
  124. #define F(i) H(i+2)
  125. #define E(i) H(i+3)
  126. #define D(i) H(i+4)
  127. #define C(i) H(i+5)
  128. #define B(i) H(i+6)
  129. #define A(i) H(i+7)
  130. #define Wt(i) BASE+8*4+ASM_MOD(1024+15-(i),16)*4
  131. #define Wt_2(i) Wt((i)-2)
  132. #define Wt_15(i) Wt((i)-15)
  133. #define Wt_7(i) Wt((i)-7)
  134. #define K_END [BASE+8*4+16*4+0*WORD_SZ]
  135. #define STATE_SAVE [BASE+8*4+16*4+1*WORD_SZ]
  136. #define DATA_SAVE [BASE+8*4+16*4+2*WORD_SZ]
  137. #define DATA_END [BASE+8*4+16*4+3*WORD_SZ]
  138. #define Kt(i) WORD_REG(si)+(i)*4
  139. #if CRYPTOPP_BOOL_X32
  140. #define BASE esp+8
  141. #elif CRYPTOPP_BOOL_X86
  142. #define BASE esp+4
  143. #elif defined(__GNUC__)
  144. #define BASE r8
  145. #else
  146. #define BASE rsp
  147. #endif
  148. #define RA0(i, edx, edi) \
  149. AS2( add edx, [Kt(i)] )\
  150. AS2( add edx, [Wt(i)] )\
  151. AS2( add edx, H(i) )\
  152. #define RA1(i, edx, edi)
  153. #define RB0(i, edx, edi)
  154. #define RB1(i, edx, edi) \
  155. AS2( mov AS_REG_7d, [Wt_2(i)] )\
  156. AS2( mov edi, [Wt_15(i)])\
  157. AS2( mov ebx, AS_REG_7d )\
  158. AS2( shr AS_REG_7d, 10 )\
  159. AS2( ror ebx, 17 )\
  160. AS2( xor AS_REG_7d, ebx )\
  161. AS2( ror ebx, 2 )\
  162. AS2( xor ebx, AS_REG_7d )/* s1(W_t-2) */\
  163. AS2( add ebx, [Wt_7(i)])\
  164. AS2( mov AS_REG_7d, edi )\
  165. AS2( shr AS_REG_7d, 3 )\
  166. AS2( ror edi, 7 )\
  167. AS2( add ebx, [Wt(i)])/* s1(W_t-2) + W_t-7 + W_t-16 */\
  168. AS2( xor AS_REG_7d, edi )\
  169. AS2( add edx, [Kt(i)])\
  170. AS2( ror edi, 11 )\
  171. AS2( add edx, H(i) )\
  172. AS2( xor AS_REG_7d, edi )/* s0(W_t-15) */\
  173. AS2( add AS_REG_7d, ebx )/* W_t = s1(W_t-2) + W_t-7 + s0(W_t-15) W_t-16*/\
  174. AS2( mov [Wt(i)], AS_REG_7d)\
  175. AS2( add edx, AS_REG_7d )\
  176. #define ROUND(i, r, eax, ecx, edi, edx)\
  177. /* in: edi = E */\
  178. /* unused: eax, ecx, temp: ebx, AS_REG_7d, out: edx = T1 */\
  179. AS2( mov edx, F(i) )\
  180. AS2( xor edx, G(i) )\
  181. AS2( and edx, edi )\
  182. AS2( xor edx, G(i) )/* Ch(E,F,G) = (G^(E&(F^G))) */\
  183. AS2( mov AS_REG_7d, edi )\
  184. AS2( ror edi, 6 )\
  185. AS2( ror AS_REG_7d, 25 )\
  186. RA##r(i, edx, edi )/* H + Wt + Kt + Ch(E,F,G) */\
  187. AS2( xor AS_REG_7d, edi )\
  188. AS2( ror edi, 5 )\
  189. AS2( xor AS_REG_7d, edi )/* S1(E) */\
  190. AS2( add edx, AS_REG_7d )/* T1 = S1(E) + Ch(E,F,G) + H + Wt + Kt */\
  191. RB##r(i, edx, edi )/* H + Wt + Kt + Ch(E,F,G) */\
  192. /* in: ecx = A, eax = B^C, edx = T1 */\
  193. /* unused: edx, temp: ebx, AS_REG_7d, out: eax = A, ecx = B^C, edx = E */\
  194. AS2( mov ebx, ecx )\
  195. AS2( xor ecx, B(i) )/* A^B */\
  196. AS2( and eax, ecx )\
  197. AS2( xor eax, B(i) )/* Maj(A,B,C) = B^((A^B)&(B^C) */\
  198. AS2( mov AS_REG_7d, ebx )\
  199. AS2( ror ebx, 2 )\
  200. AS2( add eax, edx )/* T1 + Maj(A,B,C) */\
  201. AS2( add edx, D(i) )\
  202. AS2( mov D(i), edx )\
  203. AS2( ror AS_REG_7d, 22 )\
  204. AS2( xor AS_REG_7d, ebx )\
  205. AS2( ror ebx, 11 )\
  206. AS2( xor AS_REG_7d, ebx )\
  207. AS2( add eax, AS_REG_7d )/* T1 + S0(A) + Maj(A,B,C) */\
  208. AS2( mov H(i), eax )\
  209. // Unroll the use of CRYPTOPP_BOOL_X64 in assembler math. The GAS assembler on X32 (version 2.25)
  210. // complains "Error: invalid operands (*ABS* and *UND* sections) for `*` and `-`"
  211. #if CRYPTOPP_BOOL_X64
  212. #define SWAP_COPY(i) \
  213. AS2( mov WORD_REG(bx), [WORD_REG(dx)+i*WORD_SZ])\
  214. AS1( bswap WORD_REG(bx))\
  215. AS2( mov [Wt(i*2+1)], WORD_REG(bx))
  216. #else // X86 and X32
  217. #define SWAP_COPY(i) \
  218. AS2( mov WORD_REG(bx), [WORD_REG(dx)+i*WORD_SZ])\
  219. AS1( bswap WORD_REG(bx))\
  220. AS2( mov [Wt(i)], WORD_REG(bx))
  221. #endif
  222. #if defined(__GNUC__)
  223. #if CRYPTOPP_BOOL_X64
  224. FixedSizeAlignedSecBlock<byte, LOCALS_SIZE> workspace;
  225. #endif
  226. __asm__ __volatile__
  227. (
  228. #if CRYPTOPP_BOOL_X64
  229. "lea %4, %%r8;"
  230. #endif
  231. INTEL_NOPREFIX
  232. #elif defined(CRYPTOPP_GENERATE_X64_MASM)
  233. ALIGN 8
  234. X86_SHA256_HashBlocks PROC FRAME
  235. rex_push_reg rsi
  236. push_reg rdi
  237. push_reg rbx
  238. push_reg rbp
  239. alloc_stack(LOCALS_SIZE+8)
  240. .endprolog
  241. mov rdi, r8
  242. lea rsi, [?SHA256_K@CryptoPP@@3QBIB + 48*4]
  243. #endif
  244. #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
  245. #ifndef __GNUC__
  246. AS2( mov edi, [len])
  247. AS2( lea WORD_REG(si), [SHA256_K+48*4])
  248. #endif
  249. #if !defined(_MSC_VER) || (_MSC_VER < 1400)
  250. AS_PUSH_IF86(bx)
  251. #endif
  252. AS_PUSH_IF86(bp)
  253. AS2( mov ebx, esp)
  254. AS2( and esp, -16)
  255. AS2( sub WORD_REG(sp), LOCALS_SIZE)
  256. AS_PUSH_IF86(bx)
  257. #endif
  258. AS2( mov STATE_SAVE, WORD_REG(cx))
  259. AS2( mov DATA_SAVE, WORD_REG(dx))
  260. AS2( lea WORD_REG(ax), [WORD_REG(di) + WORD_REG(dx)])
  261. AS2( mov DATA_END, WORD_REG(ax))
  262. AS2( mov K_END, WORD_REG(si))
  263. #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
  264. #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
  265. AS2( test edi, 1)
  266. ASJ( jnz, 2, f)
  267. AS1( dec DWORD PTR K_END)
  268. #endif
  269. AS2( movdqa xmm0, XMMWORD_PTR [WORD_REG(cx)+0*16])
  270. AS2( movdqa xmm1, XMMWORD_PTR [WORD_REG(cx)+1*16])
  271. #endif
  272. #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
  273. #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
  274. ASJ( jmp, 0, f)
  275. #endif
  276. ASL(2) // non-SSE2
  277. AS2( mov esi, ecx)
  278. AS2( lea edi, A(0))
  279. AS2( mov ecx, 8)
  280. AS1( rep movsd)
  281. AS2( mov esi, K_END)
  282. ASJ( jmp, 3, f)
  283. #endif
  284. #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
  285. ASL(0)
  286. AS2( movdqa E(0), xmm1)
  287. AS2( movdqa A(0), xmm0)
  288. #endif
  289. #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
  290. ASL(3)
  291. #endif
  292. AS2( sub WORD_REG(si), 48*4)
  293. SWAP_COPY(0) SWAP_COPY(1) SWAP_COPY(2) SWAP_COPY(3)
  294. SWAP_COPY(4) SWAP_COPY(5) SWAP_COPY(6) SWAP_COPY(7)
  295. #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
  296. SWAP_COPY(8) SWAP_COPY(9) SWAP_COPY(10) SWAP_COPY(11)
  297. SWAP_COPY(12) SWAP_COPY(13) SWAP_COPY(14) SWAP_COPY(15)
  298. #endif
  299. AS2( mov edi, E(0)) // E
  300. AS2( mov eax, B(0)) // B
  301. AS2( xor eax, C(0)) // B^C
  302. AS2( mov ecx, A(0)) // A
  303. ROUND(0, 0, eax, ecx, edi, edx)
  304. ROUND(1, 0, ecx, eax, edx, edi)
  305. ROUND(2, 0, eax, ecx, edi, edx)
  306. ROUND(3, 0, ecx, eax, edx, edi)
  307. ROUND(4, 0, eax, ecx, edi, edx)
  308. ROUND(5, 0, ecx, eax, edx, edi)
  309. ROUND(6, 0, eax, ecx, edi, edx)
  310. ROUND(7, 0, ecx, eax, edx, edi)
  311. ROUND(8, 0, eax, ecx, edi, edx)
  312. ROUND(9, 0, ecx, eax, edx, edi)
  313. ROUND(10, 0, eax, ecx, edi, edx)
  314. ROUND(11, 0, ecx, eax, edx, edi)
  315. ROUND(12, 0, eax, ecx, edi, edx)
  316. ROUND(13, 0, ecx, eax, edx, edi)
  317. ROUND(14, 0, eax, ecx, edi, edx)
  318. ROUND(15, 0, ecx, eax, edx, edi)
  319. ASL(1)
  320. AS2(add WORD_REG(si), 4*16)
  321. ROUND(0, 1, eax, ecx, edi, edx)
  322. ROUND(1, 1, ecx, eax, edx, edi)
  323. ROUND(2, 1, eax, ecx, edi, edx)
  324. ROUND(3, 1, ecx, eax, edx, edi)
  325. ROUND(4, 1, eax, ecx, edi, edx)
  326. ROUND(5, 1, ecx, eax, edx, edi)
  327. ROUND(6, 1, eax, ecx, edi, edx)
  328. ROUND(7, 1, ecx, eax, edx, edi)
  329. ROUND(8, 1, eax, ecx, edi, edx)
  330. ROUND(9, 1, ecx, eax, edx, edi)
  331. ROUND(10, 1, eax, ecx, edi, edx)
  332. ROUND(11, 1, ecx, eax, edx, edi)
  333. ROUND(12, 1, eax, ecx, edi, edx)
  334. ROUND(13, 1, ecx, eax, edx, edi)
  335. ROUND(14, 1, eax, ecx, edi, edx)
  336. ROUND(15, 1, ecx, eax, edx, edi)
  337. AS2( cmp WORD_REG(si), K_END)
  338. ASJ( jb, 1, b)
  339. AS2( mov WORD_REG(dx), DATA_SAVE)
  340. AS2( add WORD_REG(dx), 64)
  341. AS2( mov AS_REG_7, STATE_SAVE)
  342. AS2( mov DATA_SAVE, WORD_REG(dx))
  343. #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
  344. #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
  345. AS2( test DWORD PTR K_END, 1)
  346. ASJ( jz, 4, f)
  347. #endif
  348. AS2( movdqa xmm1, XMMWORD_PTR [AS_REG_7+1*16])
  349. AS2( movdqa xmm0, XMMWORD_PTR [AS_REG_7+0*16])
  350. AS2( paddd xmm1, E(0))
  351. AS2( paddd xmm0, A(0))
  352. AS2( movdqa [AS_REG_7+1*16], xmm1)
  353. AS2( movdqa [AS_REG_7+0*16], xmm0)
  354. AS2( cmp WORD_REG(dx), DATA_END)
  355. ASJ( jb, 0, b)
  356. #endif
  357. #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
  358. #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
  359. ASJ( jmp, 5, f)
  360. ASL(4) // non-SSE2
  361. #endif
  362. AS2( add [AS_REG_7+0*4], ecx) // A
  363. AS2( add [AS_REG_7+4*4], edi) // E
  364. AS2( mov eax, B(0))
  365. AS2( mov ebx, C(0))
  366. AS2( mov ecx, D(0))
  367. AS2( add [AS_REG_7+1*4], eax)
  368. AS2( add [AS_REG_7+2*4], ebx)
  369. AS2( add [AS_REG_7+3*4], ecx)
  370. AS2( mov eax, F(0))
  371. AS2( mov ebx, G(0))
  372. AS2( mov ecx, H(0))
  373. AS2( add [AS_REG_7+5*4], eax)
  374. AS2( add [AS_REG_7+6*4], ebx)
  375. AS2( add [AS_REG_7+7*4], ecx)
  376. AS2( mov ecx, AS_REG_7d)
  377. AS2( cmp WORD_REG(dx), DATA_END)
  378. ASJ( jb, 2, b)
  379. #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
  380. ASL(5)
  381. #endif
  382. #endif
  383. AS_POP_IF86(sp)
  384. AS_POP_IF86(bp)
  385. #if !defined(_MSC_VER) || (_MSC_VER < 1400)
  386. AS_POP_IF86(bx)
  387. #endif
  388. #ifdef CRYPTOPP_GENERATE_X64_MASM
  389. add rsp, LOCALS_SIZE+8
  390. pop rbp
  391. pop rbx
  392. pop rdi
  393. pop rsi
  394. ret
  395. X86_SHA256_HashBlocks ENDP
  396. #endif
  397. #ifdef __GNUC__
  398. ATT_PREFIX
  399. :
  400. : "c" (state), "d" (data), "S" (SHA256_K+48), "D" (len)
  401. #if CRYPTOPP_BOOL_X64
  402. , "m" (workspace[0])
  403. #endif
  404. : "memory", "cc", "%eax"
  405. #if CRYPTOPP_BOOL_X64
  406. , "%rbx", "%r8", "%r10"
  407. #endif
  408. );
  409. #endif
  410. }
  411. #endif // (defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_GENERATE_X64_MASM))
  412. #ifndef CRYPTOPP_GENERATE_X64_MASM
  413. #ifdef CRYPTOPP_X64_MASM_AVAILABLE
  414. extern "C" {
  415. void CRYPTOPP_FASTCALL X86_SHA256_HashBlocks(word32 *state, const word32 *data, size_t len);
  416. }
  417. #endif
  418. #if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X32_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE)
  419. size_t SHA256::HashMultipleBlocks(const word32 *input, size_t length)
  420. {
  421. X86_SHA256_HashBlocks(m_state, input, (length&(size_t(0)-BLOCKSIZE)) - !HasSSE2());
  422. return length % BLOCKSIZE;
  423. }
  424. size_t SHA224::HashMultipleBlocks(const word32 *input, size_t length)
  425. {
  426. X86_SHA256_HashBlocks(m_state, input, (length&(size_t(0)-BLOCKSIZE)) - !HasSSE2());
  427. return length % BLOCKSIZE;
  428. }
  429. #endif
  430. #define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15]))
  431. #define Ch(x,y,z) (z^(x&(y^z)))
  432. #define Maj(x,y,z) (y^((x^y)&(y^z)))
  433. #define a(i) T[(0-i)&7]
  434. #define b(i) T[(1-i)&7]
  435. #define c(i) T[(2-i)&7]
  436. #define d(i) T[(3-i)&7]
  437. #define e(i) T[(4-i)&7]
  438. #define f(i) T[(5-i)&7]
  439. #define g(i) T[(6-i)&7]
  440. #define h(i) T[(7-i)&7]
  441. #define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA256_K[i+j]+(j?blk2(i):blk0(i));\
  442. d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
  443. // for SHA256
  444. #define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22))
  445. #define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25))
  446. #define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3))
  447. #define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10))
  448. void SHA256::Transform(word32 *state, const word32 *data)
  449. {
  450. word32 W[16];
  451. #if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X32_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE)
  452. // this byte reverse is a waste of time, but this function is only called by MDC
  453. ByteReverse(W, data, BLOCKSIZE);
  454. X86_SHA256_HashBlocks(state, W, BLOCKSIZE - !HasSSE2());
  455. #else
  456. word32 T[8];
  457. /* Copy context->state[] to working vars */
  458. memcpy(T, state, sizeof(T));
  459. /* 64 operations, partially loop unrolled */
  460. for (unsigned int j=0; j<64; j+=16)
  461. {
  462. R( 0); R( 1); R( 2); R( 3);
  463. R( 4); R( 5); R( 6); R( 7);
  464. R( 8); R( 9); R(10); R(11);
  465. R(12); R(13); R(14); R(15);
  466. }
  467. /* Add the working vars back into context.state[] */
  468. state[0] += a(0);
  469. state[1] += b(0);
  470. state[2] += c(0);
  471. state[3] += d(0);
  472. state[4] += e(0);
  473. state[5] += f(0);
  474. state[6] += g(0);
  475. state[7] += h(0);
  476. #endif
  477. }
  478. /*
  479. // smaller but slower
  480. void SHA256::Transform(word32 *state, const word32 *data)
  481. {
  482. word32 T[20];
  483. word32 W[32];
  484. unsigned int i = 0, j = 0;
  485. word32 *t = T+8;
  486. memcpy(t, state, 8*4);
  487. word32 e = t[4], a = t[0];
  488. do
  489. {
  490. word32 w = data[j];
  491. W[j] = w;
  492. w += SHA256_K[j];
  493. w += t[7];
  494. w += S1(e);
  495. w += Ch(e, t[5], t[6]);
  496. e = t[3] + w;
  497. t[3] = t[3+8] = e;
  498. w += S0(t[0]);
  499. a = w + Maj(a, t[1], t[2]);
  500. t[-1] = t[7] = a;
  501. --t;
  502. ++j;
  503. if (j%8 == 0)
  504. t += 8;
  505. } while (j<16);
  506. do
  507. {
  508. i = j&0xf;
  509. word32 w = s1(W[i+16-2]) + s0(W[i+16-15]) + W[i] + W[i+16-7];
  510. W[i+16] = W[i] = w;
  511. w += SHA256_K[j];
  512. w += t[7];
  513. w += S1(e);
  514. w += Ch(e, t[5], t[6]);
  515. e = t[3] + w;
  516. t[3] = t[3+8] = e;
  517. w += S0(t[0]);
  518. a = w + Maj(a, t[1], t[2]);
  519. t[-1] = t[7] = a;
  520. w = s1(W[(i+1)+16-2]) + s0(W[(i+1)+16-15]) + W[(i+1)] + W[(i+1)+16-7];
  521. W[(i+1)+16] = W[(i+1)] = w;
  522. w += SHA256_K[j+1];
  523. w += (t-1)[7];
  524. w += S1(e);
  525. w += Ch(e, (t-1)[5], (t-1)[6]);
  526. e = (t-1)[3] + w;
  527. (t-1)[3] = (t-1)[3+8] = e;
  528. w += S0((t-1)[0]);
  529. a = w + Maj(a, (t-1)[1], (t-1)[2]);
  530. (t-1)[-1] = (t-1)[7] = a;
  531. t-=2;
  532. j+=2;
  533. if (j%8 == 0)
  534. t += 8;
  535. } while (j<64);
  536. state[0] += a;
  537. state[1] += t[1];
  538. state[2] += t[2];
  539. state[3] += t[3];
  540. state[4] += e;
  541. state[5] += t[5];
  542. state[6] += t[6];
  543. state[7] += t[7];
  544. }
  545. */
  546. #undef S0
  547. #undef S1
  548. #undef s0
  549. #undef s1
  550. #undef R
  551. // *************************************************************
  552. void SHA384::InitState(HashWordType *state)
  553. {
  554. static const word64 s[8] = {
  555. W64LIT(0xcbbb9d5dc1059ed8), W64LIT(0x629a292a367cd507),
  556. W64LIT(0x9159015a3070dd17), W64LIT(0x152fecd8f70e5939),
  557. W64LIT(0x67332667ffc00b31), W64LIT(0x8eb44a8768581511),
  558. W64LIT(0xdb0c2e0d64f98fa7), W64LIT(0x47b5481dbefa4fa4)};
  559. memcpy(state, s, sizeof(s));
  560. }
  561. void SHA512::InitState(HashWordType *state)
  562. {
  563. static const word64 s[8] = {
  564. W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b),
  565. W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1),
  566. W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f),
  567. W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179)};
  568. memcpy(state, s, sizeof(s));
  569. }
  570. #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32)
  571. CRYPTOPP_ALIGN_DATA(16) static const word64 SHA512_K[80] CRYPTOPP_SECTION_ALIGN16 = {
  572. #else
  573. static const word64 SHA512_K[80] = {
  574. #endif
  575. W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd),
  576. W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),
  577. W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019),
  578. W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),
  579. W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe),
  580. W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),
  581. W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1),
  582. W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),
  583. W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3),
  584. W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
  585. W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483),
  586. W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
  587. W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210),
  588. W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
  589. W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725),
  590. W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
  591. W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926),
  592. W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
  593. W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8),
  594. W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
  595. W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001),
  596. W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
  597. W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910),
  598. W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
  599. W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53),
  600. W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
  601. W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb),
  602. W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
  603. W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60),
  604. W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
  605. W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9),
  606. W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
  607. W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207),
  608. W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
  609. W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6),
  610. W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
  611. W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493),
  612. W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
  613. W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a),
  614. W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)
  615. };
  616. #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32)
  617. // put assembly version in separate function, otherwise MSVC 2005 SP1 doesn't generate correct code for the non-assembly version
  618. CRYPTOPP_NAKED static void CRYPTOPP_FASTCALL SHA512_SSE2_Transform(word64 *state, const word64 *data)
  619. {
  620. #ifdef __GNUC__
  621. __asm__ __volatile__
  622. (
  623. INTEL_NOPREFIX
  624. AS_PUSH_IF86( bx)
  625. AS2( mov ebx, eax)
  626. #else
  627. AS1( push ebx)
  628. AS1( push esi)
  629. AS1( push edi)
  630. AS2( lea ebx, SHA512_K)
  631. #endif
  632. AS2( mov eax, esp)
  633. AS2( and esp, 0xfffffff0)
  634. AS2( sub esp, 27*16) // 17*16 for expanded data, 20*8 for state
  635. AS_PUSH_IF86( ax)
  636. AS2( xor eax, eax)
  637. #if CRYPTOPP_BOOL_X32
  638. AS2( lea edi, [esp+8+8*8]) // start at middle of state buffer. will decrement pointer each round to avoid copying
  639. AS2( lea esi, [esp+8+20*8+8]) // 16-byte alignment, then add 8
  640. #else
  641. AS2( lea edi, [esp+4+8*8]) // start at middle of state buffer. will decrement pointer each round to avoid copying
  642. AS2( lea esi, [esp+4+20*8+8]) // 16-byte alignment, then add 8
  643. #endif
  644. AS2( movdqa xmm0, [ecx+0*16])
  645. AS2( movdq2q mm4, xmm0)
  646. AS2( movdqa [edi+0*16], xmm0)
  647. AS2( movdqa xmm0, [ecx+1*16])
  648. AS2( movdqa [edi+1*16], xmm0)
  649. AS2( movdqa xmm0, [ecx+2*16])
  650. AS2( movdq2q mm5, xmm0)
  651. AS2( movdqa [edi+2*16], xmm0)
  652. AS2( movdqa xmm0, [ecx+3*16])
  653. AS2( movdqa [edi+3*16], xmm0)
  654. ASJ( jmp, 0, f)
  655. #define SSE2_S0_S1(r, a, b, c) \
  656. AS2( movq mm6, r)\
  657. AS2( psrlq r, a)\
  658. AS2( movq mm7, r)\
  659. AS2( psllq mm6, 64-c)\
  660. AS2( pxor mm7, mm6)\
  661. AS2( psrlq r, b-a)\
  662. AS2( pxor mm7, r)\
  663. AS2( psllq mm6, c-b)\
  664. AS2( pxor mm7, mm6)\
  665. AS2( psrlq r, c-b)\
  666. AS2( pxor r, mm7)\
  667. AS2( psllq mm6, b-a)\
  668. AS2( pxor r, mm6)
  669. #define SSE2_s0(r, a, b, c) \
  670. AS2( movdqa xmm6, r)\
  671. AS2( psrlq r, a)\
  672. AS2( movdqa xmm7, r)\
  673. AS2( psllq xmm6, 64-c)\
  674. AS2( pxor xmm7, xmm6)\
  675. AS2( psrlq r, b-a)\
  676. AS2( pxor xmm7, r)\
  677. AS2( psrlq r, c-b)\
  678. AS2( pxor r, xmm7)\
  679. AS2( psllq xmm6, c-a)\
  680. AS2( pxor r, xmm6)
  681. #define SSE2_s1(r, a, b, c) \
  682. AS2( movdqa xmm6, r)\
  683. AS2( psrlq r, a)\
  684. AS2( movdqa xmm7, r)\
  685. AS2( psllq xmm6, 64-c)\
  686. AS2( pxor xmm7, xmm6)\
  687. AS2( psrlq r, b-a)\
  688. AS2( pxor xmm7, r)\
  689. AS2( psllq xmm6, c-b)\
  690. AS2( pxor xmm7, xmm6)\
  691. AS2( psrlq r, c-b)\
  692. AS2( pxor r, xmm7)
  693. ASL(SHA512_Round)
  694. // k + w is in mm0, a is in mm4, e is in mm5
  695. AS2( paddq mm0, [edi+7*8]) // h
  696. AS2( movq mm2, [edi+5*8]) // f
  697. AS2( movq mm3, [edi+6*8]) // g
  698. AS2( pxor mm2, mm3)
  699. AS2( pand mm2, mm5)
  700. SSE2_S0_S1(mm5,14,18,41)
  701. AS2( pxor mm2, mm3)
  702. AS2( paddq mm0, mm2) // h += Ch(e,f,g)
  703. AS2( paddq mm5, mm0) // h += S1(e)
  704. AS2( movq mm2, [edi+1*8]) // b
  705. AS2( movq mm1, mm2)
  706. AS2( por mm2, mm4)
  707. AS2( pand mm2, [edi+2*8]) // c
  708. AS2( pand mm1, mm4)
  709. AS2( por mm1, mm2)
  710. AS2( paddq mm1, mm5) // temp = h + Maj(a,b,c)
  711. AS2( paddq mm5, [edi+3*8]) // e = d + h
  712. AS2( movq [edi+3*8], mm5)
  713. AS2( movq [edi+11*8], mm5)
  714. SSE2_S0_S1(mm4,28,34,39) // S0(a)
  715. AS2( paddq mm4, mm1) // a = temp + S0(a)
  716. AS2( movq [edi-8], mm4)
  717. AS2( movq [edi+7*8], mm4)
  718. AS1( ret)
  719. // first 16 rounds
  720. ASL(0)
  721. AS2( movq mm0, [edx+eax*8])
  722. AS2( movq [esi+eax*8], mm0)
  723. AS2( movq [esi+eax*8+16*8], mm0)
  724. AS2( paddq mm0, [ebx+eax*8])
  725. ASC( call, SHA512_Round)
  726. AS1( inc eax)
  727. AS2( sub edi, 8)
  728. AS2( test eax, 7)
  729. ASJ( jnz, 0, b)
  730. AS2( add edi, 8*8)
  731. AS2( cmp eax, 16)
  732. ASJ( jne, 0, b)
  733. // rest of the rounds
  734. AS2( movdqu xmm0, [esi+(16-2)*8])
  735. ASL(1)
  736. // data expansion, W[i-2] already in xmm0
  737. AS2( movdqu xmm3, [esi])
  738. AS2( paddq xmm3, [esi+(16-7)*8])
  739. AS2( movdqa xmm2, [esi+(16-15)*8])
  740. SSE2_s1(xmm0, 6, 19, 61)
  741. AS2( paddq xmm0, xmm3)
  742. SSE2_s0(xmm2, 1, 7, 8)
  743. AS2( paddq xmm0, xmm2)
  744. AS2( movdq2q mm0, xmm0)
  745. AS2( movhlps xmm1, xmm0)
  746. AS2( paddq mm0, [ebx+eax*8])
  747. AS2( movlps [esi], xmm0)
  748. AS2( movlps [esi+8], xmm1)
  749. AS2( movlps [esi+8*16], xmm0)
  750. AS2( movlps [esi+8*17], xmm1)
  751. // 2 rounds
  752. ASC( call, SHA512_Round)
  753. AS2( sub edi, 8)
  754. AS2( movdq2q mm0, xmm1)
  755. AS2( paddq mm0, [ebx+eax*8+8])
  756. ASC( call, SHA512_Round)
  757. // update indices and loop
  758. AS2( add esi, 16)
  759. AS2( add eax, 2)
  760. AS2( sub edi, 8)
  761. AS2( test eax, 7)
  762. ASJ( jnz, 1, b)
  763. // do housekeeping every 8 rounds
  764. AS2( mov esi, 0xf)
  765. AS2( and esi, eax)
  766. #if CRYPTOPP_BOOL_X32
  767. AS2( lea esi, [esp+8+20*8+8+esi*8])
  768. #else
  769. AS2( lea esi, [esp+4+20*8+8+esi*8])
  770. #endif
  771. AS2( add edi, 8*8)
  772. AS2( cmp eax, 80)
  773. ASJ( jne, 1, b)
  774. #define SSE2_CombineState(i) \
  775. AS2( movdqa xmm0, [edi+i*16])\
  776. AS2( paddq xmm0, [ecx+i*16])\
  777. AS2( movdqa [ecx+i*16], xmm0)
  778. SSE2_CombineState(0)
  779. SSE2_CombineState(1)
  780. SSE2_CombineState(2)
  781. SSE2_CombineState(3)
  782. AS_POP_IF86( sp)
  783. AS1( emms)
  784. #if defined(__GNUC__)
  785. AS_POP_IF86( bx)
  786. ATT_PREFIX
  787. :
  788. : "a" (SHA512_K), "c" (state), "d" (data)
  789. : "%esi", "%edi", "memory", "cc"
  790. );
  791. #else
  792. AS1( pop edi)
  793. AS1( pop esi)
  794. AS1( pop ebx)
  795. AS1( ret)
  796. #endif
  797. }
  798. #endif // #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
  799. void SHA512::Transform(word64 *state, const word64 *data)
  800. {
  801. #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32)
  802. if (HasSSE2())
  803. {
  804. SHA512_SSE2_Transform(state, data);
  805. return;
  806. }
  807. #endif
  808. #define S0(x) (rotrFixed(x,28)^rotrFixed(x,34)^rotrFixed(x,39))
  809. #define S1(x) (rotrFixed(x,14)^rotrFixed(x,18)^rotrFixed(x,41))
  810. #define s0(x) (rotrFixed(x,1)^rotrFixed(x,8)^(x>>7))
  811. #define s1(x) (rotrFixed(x,19)^rotrFixed(x,61)^(x>>6))
  812. #define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA512_K[i+j]+(j?blk2(i):blk0(i));\
  813. d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
  814. word64 W[16];
  815. word64 T[8];
  816. /* Copy context->state[] to working vars */
  817. memcpy(T, state, sizeof(T));
  818. /* 80 operations, partially loop unrolled */
  819. for (unsigned int j=0; j<80; j+=16)
  820. {
  821. R( 0); R( 1); R( 2); R( 3);
  822. R( 4); R( 5); R( 6); R( 7);
  823. R( 8); R( 9); R(10); R(11);
  824. R(12); R(13); R(14); R(15);
  825. }
  826. /* Add the working vars back into context.state[] */
  827. state[0] += a(0);
  828. state[1] += b(0);
  829. state[2] += c(0);
  830. state[3] += d(0);
  831. state[4] += e(0);
  832. state[5] += f(0);
  833. state[6] += g(0);
  834. state[7] += h(0);
  835. }
  836. NAMESPACE_END
  837. #endif // #ifndef CRYPTOPP_GENERATE_X64_MASM
  838. #endif // #ifndef CRYPTOPP_IMPORTS