00001
00002
00003
00004
00005
00006
00007
00008 #include "pch.h"
00009 #include "config.h"
00010
00011 #if CRYPTOPP_MSC_VERSION
00012 # pragma warning(disable: 4100 4731)
00013 #endif
00014
00015 #ifndef CRYPTOPP_IMPORTS
00016 #ifndef CRYPTOPP_GENERATE_X64_MASM
00017
00018 #include "secblock.h"
00019 #include "sha.h"
00020 #include "misc.h"
00021 #include "cpu.h"
00022
00023 NAMESPACE_BEGIN(CryptoPP)
00024
00025
00026
00027 #define blk0(i) (W[i] = data[i])
00028 #define blk1(i) (W[i&15] = rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1))
00029
00030 void SHA1::InitState(HashWordType *state)
00031 {
00032 state[0] = 0x67452301L;
00033 state[1] = 0xEFCDAB89L;
00034 state[2] = 0x98BADCFEL;
00035 state[3] = 0x10325476L;
00036 state[4] = 0xC3D2E1F0L;
00037 }
00038
00039 #define f1(x,y,z) (z^(x&(y^z)))
00040 #define f2(x,y,z) (x^y^z)
00041 #define f3(x,y,z) ((x&y)|(z&(x|y)))
00042 #define f4(x,y,z) (x^y^z)
00043
00044
00045 #define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
00046 #define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
00047 #define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rotlFixed(v,5);w=rotlFixed(w,30);
00048 #define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rotlFixed(v,5);w=rotlFixed(w,30);
00049 #define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rotlFixed(v,5);w=rotlFixed(w,30);
00050
00051 void SHA1::Transform(word32 *state, const word32 *data)
00052 {
00053 word32 W[16];
00054
00055 word32 a = state[0];
00056 word32 b = state[1];
00057 word32 c = state[2];
00058 word32 d = state[3];
00059 word32 e = state[4];
00060
00061 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);
00062 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);
00063 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);
00064 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);
00065 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);
00066 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);
00067 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);
00068 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);
00069 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);
00070 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);
00071 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);
00072 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);
00073 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);
00074 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);
00075 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);
00076 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);
00077 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);
00078 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);
00079 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);
00080 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);
00081
00082 state[0] += a;
00083 state[1] += b;
00084 state[2] += c;
00085 state[3] += d;
00086 state[4] += e;
00087 }
00088
00089
00090
00091
00092
00093 void SHA224::InitState(HashWordType *state)
00094 {
00095 static const word32 s[8] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
00096 memcpy(state, s, sizeof(s));
00097 }
00098
00099 void SHA256::InitState(HashWordType *state)
00100 {
00101 static const word32 s[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
00102 memcpy(state, s, sizeof(s));
00103 }
00104
00105 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
00106 CRYPTOPP_ALIGN_DATA(16) extern const word32 SHA256_K[64] CRYPTOPP_SECTION_ALIGN16 = {
00107 #else
00108 extern const word32 SHA256_K[64] = {
00109 #endif
00110 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
00111 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
00112 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
00113 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
00114 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
00115 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
00116 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
00117 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
00118 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
00119 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
00120 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
00121 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
00122 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
00123 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
00124 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
00125 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
00126 };
00127
00128 #endif // #ifndef CRYPTOPP_GENERATE_X64_MASM
00129
00130 #if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X32_ASM_AVAILABLE) || defined(CRYPTOPP_GENERATE_X64_MASM)
00131
00132 static void CRYPTOPP_FASTCALL X86_SHA256_HashBlocks(word32 *state, const word32 *data, size_t len
00133 #if defined(_MSC_VER) && (_MSC_VER == 1200)
00134 , ...
00135 #endif
00136 )
00137 {
00138 #if defined(_MSC_VER) && (_MSC_VER == 1200)
00139 AS2(mov ecx, [state])
00140 AS2(mov edx, [data])
00141 #endif
00142
00143 #define LOCALS_SIZE 8*4 + 16*4 + 4*WORD_SZ
00144 #define H(i) [BASE+ASM_MOD(1024+7-(i),8)*4]
00145 #define G(i) H(i+1)
00146 #define F(i) H(i+2)
00147 #define E(i) H(i+3)
00148 #define D(i) H(i+4)
00149 #define C(i) H(i+5)
00150 #define B(i) H(i+6)
00151 #define A(i) H(i+7)
00152 #define Wt(i) BASE+8*4+ASM_MOD(1024+15-(i),16)*4
00153 #define Wt_2(i) Wt((i)-2)
00154 #define Wt_15(i) Wt((i)-15)
00155 #define Wt_7(i) Wt((i)-7)
00156 #define K_END [BASE+8*4+16*4+0*WORD_SZ]
00157 #define STATE_SAVE [BASE+8*4+16*4+1*WORD_SZ]
00158 #define DATA_SAVE [BASE+8*4+16*4+2*WORD_SZ]
00159 #define DATA_END [BASE+8*4+16*4+3*WORD_SZ]
00160 #define Kt(i) WORD_REG(si)+(i)*4
00161 #if CRYPTOPP_BOOL_X32
00162 #define BASE esp+8
00163 #elif CRYPTOPP_BOOL_X86
00164 #define BASE esp+4
00165 #elif defined(__GNUC__)
00166 #define BASE r8
00167 #else
00168 #define BASE rsp
00169 #endif
00170
00171 #define RA0(i, edx, edi) \
00172 AS2( add edx, [Kt(i)] )\
00173 AS2( add edx, [Wt(i)] )\
00174 AS2( add edx, H(i) )\
00175
00176 #define RA1(i, edx, edi)
00177
00178 #define RB0(i, edx, edi)
00179
00180 #define RB1(i, edx, edi) \
00181 AS2( mov AS_REG_7d, [Wt_2(i)] )\
00182 AS2( mov edi, [Wt_15(i)])\
00183 AS2( mov ebx, AS_REG_7d )\
00184 AS2( shr AS_REG_7d, 10 )\
00185 AS2( ror ebx, 17 )\
00186 AS2( xor AS_REG_7d, ebx )\
00187 AS2( ror ebx, 2 )\
00188 AS2( xor ebx, AS_REG_7d )\
00189 AS2( add ebx, [Wt_7(i)])\
00190 AS2( mov AS_REG_7d, edi )\
00191 AS2( shr AS_REG_7d, 3 )\
00192 AS2( ror edi, 7 )\
00193 AS2( add ebx, [Wt(i)])\
00194 AS2( xor AS_REG_7d, edi )\
00195 AS2( add edx, [Kt(i)])\
00196 AS2( ror edi, 11 )\
00197 AS2( add edx, H(i) )\
00198 AS2( xor AS_REG_7d, edi )\
00199 AS2( add AS_REG_7d, ebx )\
00200 AS2( mov [Wt(i)], AS_REG_7d)\
00201 AS2( add edx, AS_REG_7d )\
00202
00203 #define ROUND(i, r, eax, ecx, edi, edx)\
00204 \
00205 \
00206 AS2( mov edx, F(i) )\
00207 AS2( xor edx, G(i) )\
00208 AS2( and edx, edi )\
00209 AS2( xor edx, G(i) )\
00210 AS2( mov AS_REG_7d, edi )\
00211 AS2( ror edi, 6 )\
00212 AS2( ror AS_REG_7d, 25 )\
00213 RA##r(i, edx, edi )\
00214 AS2( xor AS_REG_7d, edi )\
00215 AS2( ror edi, 5 )\
00216 AS2( xor AS_REG_7d, edi )\
00217 AS2( add edx, AS_REG_7d )\
00218 RB##r(i, edx, edi )\
00219 \
00220 \
00221 AS2( mov ebx, ecx )\
00222 AS2( xor ecx, B(i) )\
00223 AS2( and eax, ecx )\
00224 AS2( xor eax, B(i) )\
00225 AS2( mov AS_REG_7d, ebx )\
00226 AS2( ror ebx, 2 )\
00227 AS2( add eax, edx )\
00228 AS2( add edx, D(i) )\
00229 AS2( mov D(i), edx )\
00230 AS2( ror AS_REG_7d, 22 )\
00231 AS2( xor AS_REG_7d, ebx )\
00232 AS2( ror ebx, 11 )\
00233 AS2( xor AS_REG_7d, ebx )\
00234 AS2( add eax, AS_REG_7d )\
00235 AS2( mov H(i), eax )\
00236
00237
00238
00239 #if CRYPTOPP_BOOL_X64
00240 #define SWAP_COPY(i) \
00241 AS2( mov WORD_REG(bx), [WORD_REG(dx)+i*WORD_SZ])\
00242 AS1( bswap WORD_REG(bx))\
00243 AS2( mov [Wt(i*2+1)], WORD_REG(bx))
00244 #else // X86 and X32
00245 #define SWAP_COPY(i) \
00246 AS2( mov WORD_REG(bx), [WORD_REG(dx)+i*WORD_SZ])\
00247 AS1( bswap WORD_REG(bx))\
00248 AS2( mov [Wt(i)], WORD_REG(bx))
00249 #endif
00250
00251 #if defined(__GNUC__)
00252 #if CRYPTOPP_BOOL_X64
00253 FixedSizeAlignedSecBlock<byte, LOCALS_SIZE> workspace;
00254 #endif
00255 __asm__ __volatile__
00256 (
00257 #if CRYPTOPP_BOOL_X64
00258 "lea %4, %%r8;"
00259 #endif
00260 INTEL_NOPREFIX
00261 #elif defined(CRYPTOPP_GENERATE_X64_MASM)
00262 ALIGN 8
00263 X86_SHA256_HashBlocks PROC FRAME
00264 rex_push_reg rsi
00265 push_reg rdi
00266 push_reg rbx
00267 push_reg rbp
00268 alloc_stack(LOCALS_SIZE+8)
00269 .endprolog
00270 mov rdi, r8
00271 lea rsi, [?SHA256_K@CryptoPP@@3QBIB + 48*4]
00272 #endif
00273
00274 #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
00275 #ifndef __GNUC__
00276 AS2( mov edi, [len])
00277 AS2( lea WORD_REG(si), [SHA256_K+48*4])
00278 #endif
00279 #if !defined(_MSC_VER) || (_MSC_VER < 1400)
00280 AS_PUSH_IF86(bx)
00281 #endif
00282
00283 AS_PUSH_IF86(bp)
00284 AS2( mov ebx, esp)
00285 AS2( and esp, -16)
00286 AS2( sub WORD_REG(sp), LOCALS_SIZE)
00287 AS_PUSH_IF86(bx)
00288 #endif
00289 AS2( mov STATE_SAVE, WORD_REG(cx))
00290 AS2( mov DATA_SAVE, WORD_REG(dx))
00291 AS2( lea WORD_REG(ax), [WORD_REG(di) + WORD_REG(dx)])
00292 AS2( mov DATA_END, WORD_REG(ax))
00293 AS2( mov K_END, WORD_REG(si))
00294
00295 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
00296 #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
00297 AS2( test edi, 1)
00298 ASJ( jnz, 2, f)
00299 AS1( dec DWORD PTR K_END)
00300 #endif
00301 AS2( movdqa xmm0, XMMWORD_PTR [WORD_REG(cx)+0*16])
00302 AS2( movdqa xmm1, XMMWORD_PTR [WORD_REG(cx)+1*16])
00303 #endif
00304
00305 #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
00306 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
00307 ASJ( jmp, 0, f)
00308 #endif
00309 ASL(2)
00310 AS2( mov esi, ecx)
00311 AS2( lea edi, A(0))
00312 AS2( mov ecx, 8)
00313 AS1( rep movsd)
00314 AS2( mov esi, K_END)
00315 ASJ( jmp, 3, f)
00316 #endif
00317
00318 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
00319 ASL(0)
00320 AS2( movdqa E(0), xmm1)
00321 AS2( movdqa A(0), xmm0)
00322 #endif
00323 #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
00324 ASL(3)
00325 #endif
00326 AS2( sub WORD_REG(si), 48*4)
00327 SWAP_COPY(0) SWAP_COPY(1) SWAP_COPY(2) SWAP_COPY(3)
00328 SWAP_COPY(4) SWAP_COPY(5) SWAP_COPY(6) SWAP_COPY(7)
00329 #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
00330 SWAP_COPY(8) SWAP_COPY(9) SWAP_COPY(10) SWAP_COPY(11)
00331 SWAP_COPY(12) SWAP_COPY(13) SWAP_COPY(14) SWAP_COPY(15)
00332 #endif
00333 AS2( mov edi, E(0))
00334 AS2( mov eax, B(0))
00335 AS2( xor eax, C(0))
00336 AS2( mov ecx, A(0))
00337
00338 ROUND(0, 0, eax, ecx, edi, edx)
00339 ROUND(1, 0, ecx, eax, edx, edi)
00340 ROUND(2, 0, eax, ecx, edi, edx)
00341 ROUND(3, 0, ecx, eax, edx, edi)
00342 ROUND(4, 0, eax, ecx, edi, edx)
00343 ROUND(5, 0, ecx, eax, edx, edi)
00344 ROUND(6, 0, eax, ecx, edi, edx)
00345 ROUND(7, 0, ecx, eax, edx, edi)
00346 ROUND(8, 0, eax, ecx, edi, edx)
00347 ROUND(9, 0, ecx, eax, edx, edi)
00348 ROUND(10, 0, eax, ecx, edi, edx)
00349 ROUND(11, 0, ecx, eax, edx, edi)
00350 ROUND(12, 0, eax, ecx, edi, edx)
00351 ROUND(13, 0, ecx, eax, edx, edi)
00352 ROUND(14, 0, eax, ecx, edi, edx)
00353 ROUND(15, 0, ecx, eax, edx, edi)
00354
00355 ASL(1)
00356 AS2(add WORD_REG(si), 4*16)
00357 ROUND(0, 1, eax, ecx, edi, edx)
00358 ROUND(1, 1, ecx, eax, edx, edi)
00359 ROUND(2, 1, eax, ecx, edi, edx)
00360 ROUND(3, 1, ecx, eax, edx, edi)
00361 ROUND(4, 1, eax, ecx, edi, edx)
00362 ROUND(5, 1, ecx, eax, edx, edi)
00363 ROUND(6, 1, eax, ecx, edi, edx)
00364 ROUND(7, 1, ecx, eax, edx, edi)
00365 ROUND(8, 1, eax, ecx, edi, edx)
00366 ROUND(9, 1, ecx, eax, edx, edi)
00367 ROUND(10, 1, eax, ecx, edi, edx)
00368 ROUND(11, 1, ecx, eax, edx, edi)
00369 ROUND(12, 1, eax, ecx, edi, edx)
00370 ROUND(13, 1, ecx, eax, edx, edi)
00371 ROUND(14, 1, eax, ecx, edi, edx)
00372 ROUND(15, 1, ecx, eax, edx, edi)
00373 AS2( cmp WORD_REG(si), K_END)
00374 ASJ( jb, 1, b)
00375
00376 AS2( mov WORD_REG(dx), DATA_SAVE)
00377 AS2( add WORD_REG(dx), 64)
00378 AS2( mov AS_REG_7, STATE_SAVE)
00379 AS2( mov DATA_SAVE, WORD_REG(dx))
00380
00381 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
00382 #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
00383 AS2( test DWORD PTR K_END, 1)
00384 ASJ( jz, 4, f)
00385 #endif
00386 AS2( movdqa xmm1, XMMWORD_PTR [AS_REG_7+1*16])
00387 AS2( movdqa xmm0, XMMWORD_PTR [AS_REG_7+0*16])
00388 AS2( paddd xmm1, E(0))
00389 AS2( paddd xmm0, A(0))
00390 AS2( movdqa [AS_REG_7+1*16], xmm1)
00391 AS2( movdqa [AS_REG_7+0*16], xmm0)
00392 AS2( cmp WORD_REG(dx), DATA_END)
00393 ASJ( jb, 0, b)
00394 #endif
00395
00396 #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
00397 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
00398 ASJ( jmp, 5, f)
00399 ASL(4)
00400 #endif
00401 AS2( add [AS_REG_7+0*4], ecx)
00402 AS2( add [AS_REG_7+4*4], edi)
00403 AS2( mov eax, B(0))
00404 AS2( mov ebx, C(0))
00405 AS2( mov ecx, D(0))
00406 AS2( add [AS_REG_7+1*4], eax)
00407 AS2( add [AS_REG_7+2*4], ebx)
00408 AS2( add [AS_REG_7+3*4], ecx)
00409 AS2( mov eax, F(0))
00410 AS2( mov ebx, G(0))
00411 AS2( mov ecx, H(0))
00412 AS2( add [AS_REG_7+5*4], eax)
00413 AS2( add [AS_REG_7+6*4], ebx)
00414 AS2( add [AS_REG_7+7*4], ecx)
00415 AS2( mov ecx, AS_REG_7d)
00416 AS2( cmp WORD_REG(dx), DATA_END)
00417 ASJ( jb, 2, b)
00418 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
00419 ASL(5)
00420 #endif
00421 #endif
00422
00423 AS_POP_IF86(sp)
00424 AS_POP_IF86(bp)
00425 #if !defined(_MSC_VER) || (_MSC_VER < 1400)
00426 AS_POP_IF86(bx)
00427 #endif
00428
00429 #ifdef CRYPTOPP_GENERATE_X64_MASM
00430 add rsp, LOCALS_SIZE+8
00431 pop rbp
00432 pop rbx
00433 pop rdi
00434 pop rsi
00435 ret
00436 X86_SHA256_HashBlocks ENDP
00437 #endif
00438
00439 #ifdef __GNUC__
00440 ATT_PREFIX
00441 :
00442 : "c" (state), "d" (data), "S" (SHA256_K+48), "D" (len)
00443 #if CRYPTOPP_BOOL_X64
00444 , "m" (workspace[0])
00445 #endif
00446 : "memory", "cc", "%eax"
00447 #if CRYPTOPP_BOOL_X64
00448 , "%rbx", "%r8", "%r10"
00449 #endif
00450 );
00451 #endif
00452 }
00453
00454 #endif // (defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_GENERATE_X64_MASM))
00455
00456 #ifndef CRYPTOPP_GENERATE_X64_MASM
00457
00458 #ifdef CRYPTOPP_X64_MASM_AVAILABLE
00459 extern "C" {
00460 void CRYPTOPP_FASTCALL X86_SHA256_HashBlocks(word32 *state, const word32 *data, size_t len);
00461 }
00462 #endif
00463
00464 #if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X32_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE)
00465
00466 size_t SHA256::HashMultipleBlocks(const word32 *input, size_t length)
00467 {
00468 X86_SHA256_HashBlocks(m_state, input, (length&(size_t(0)-BLOCKSIZE)) - !HasSSE2());
00469 return length % BLOCKSIZE;
00470 }
00471
00472 size_t SHA224::HashMultipleBlocks(const word32 *input, size_t length)
00473 {
00474 X86_SHA256_HashBlocks(m_state, input, (length&(size_t(0)-BLOCKSIZE)) - !HasSSE2());
00475 return length % BLOCKSIZE;
00476 }
00477
00478 #endif
00479
00480 #define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15]))
00481
00482 #define Ch(x,y,z) (z^(x&(y^z)))
00483 #define Maj(x,y,z) (y^((x^y)&(y^z)))
00484
00485 #define a(i) T[(0-i)&7]
00486 #define b(i) T[(1-i)&7]
00487 #define c(i) T[(2-i)&7]
00488 #define d(i) T[(3-i)&7]
00489 #define e(i) T[(4-i)&7]
00490 #define f(i) T[(5-i)&7]
00491 #define g(i) T[(6-i)&7]
00492 #define h(i) T[(7-i)&7]
00493
00494 #define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA256_K[i+j]+(j?blk2(i):blk0(i));\
00495 d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
00496
00497
00498 #define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22))
00499 #define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25))
00500 #define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3))
00501 #define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10))
00502
00503 void SHA256::Transform(word32 *state, const word32 *data)
00504 {
00505 word32 W[16];
00506 #if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X32_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE)
00507
00508 ByteReverse(W, data, BLOCKSIZE);
00509 X86_SHA256_HashBlocks(state, W, BLOCKSIZE - !HasSSE2());
00510 #else
00511 word32 T[8];
00512
00513 memcpy(T, state, sizeof(T));
00514
00515 for (unsigned int j=0; j<64; j+=16)
00516 {
00517 R( 0); R( 1); R( 2); R( 3);
00518 R( 4); R( 5); R( 6); R( 7);
00519 R( 8); R( 9); R(10); R(11);
00520 R(12); R(13); R(14); R(15);
00521 }
00522
00523 state[0] += a(0);
00524 state[1] += b(0);
00525 state[2] += c(0);
00526 state[3] += d(0);
00527 state[4] += e(0);
00528 state[5] += f(0);
00529 state[6] += g(0);
00530 state[7] += h(0);
00531 #endif
00532 }
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609 #undef S0
00610 #undef S1
00611 #undef s0
00612 #undef s1
00613 #undef R
00614
00615
00616
00617 void SHA384::InitState(HashWordType *state)
00618 {
00619 static const word64 s[8] = {
00620 W64LIT(0xcbbb9d5dc1059ed8), W64LIT(0x629a292a367cd507),
00621 W64LIT(0x9159015a3070dd17), W64LIT(0x152fecd8f70e5939),
00622 W64LIT(0x67332667ffc00b31), W64LIT(0x8eb44a8768581511),
00623 W64LIT(0xdb0c2e0d64f98fa7), W64LIT(0x47b5481dbefa4fa4)};
00624 memcpy(state, s, sizeof(s));
00625 }
00626
00627 void SHA512::InitState(HashWordType *state)
00628 {
00629 static const word64 s[8] = {
00630 W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b),
00631 W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1),
00632 W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f),
00633 W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179)};
00634 memcpy(state, s, sizeof(s));
00635 }
00636
00637 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32)
00638 CRYPTOPP_ALIGN_DATA(16) static const word64 SHA512_K[80] CRYPTOPP_SECTION_ALIGN16 = {
00639 #else
00640 static const word64 SHA512_K[80] = {
00641 #endif
00642 W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd),
00643 W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),
00644 W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019),
00645 W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),
00646 W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe),
00647 W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),
00648 W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1),
00649 W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),
00650 W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3),
00651 W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
00652 W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483),
00653 W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
00654 W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210),
00655 W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
00656 W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725),
00657 W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
00658 W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926),
00659 W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
00660 W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8),
00661 W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
00662 W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001),
00663 W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
00664 W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910),
00665 W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
00666 W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53),
00667 W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
00668 W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb),
00669 W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
00670 W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60),
00671 W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
00672 W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9),
00673 W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
00674 W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207),
00675 W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
00676 W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6),
00677 W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
00678 W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493),
00679 W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
00680 W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a),
00681 W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)
00682 };
00683
00684 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32)
00685
00686 CRYPTOPP_NAKED static void CRYPTOPP_FASTCALL SHA512_SSE2_Transform(word64 *state, const word64 *data)
00687 {
00688 #ifdef __GNUC__
00689 __asm__ __volatile__
00690 (
00691 INTEL_NOPREFIX
00692 AS_PUSH_IF86( bx)
00693 AS2( mov ebx, eax)
00694 #else
00695 AS1( push ebx)
00696 AS1( push esi)
00697 AS1( push edi)
00698 AS2( lea ebx, SHA512_K)
00699 #endif
00700
00701 AS2( mov eax, esp)
00702 AS2( and esp, 0xfffffff0)
00703 AS2( sub esp, 27*16)
00704 AS_PUSH_IF86( ax)
00705 AS2( xor eax, eax)
00706
00707 #if CRYPTOPP_BOOL_X32
00708 AS2( lea edi, [esp+8+8*8])
00709 AS2( lea esi, [esp+8+20*8+8])
00710 #else
00711 AS2( lea edi, [esp+4+8*8])
00712 AS2( lea esi, [esp+4+20*8+8])
00713 #endif
00714
00715 AS2( movdqa xmm0, [ecx+0*16])
00716 AS2( movdq2q mm4, xmm0)
00717 AS2( movdqa [edi+0*16], xmm0)
00718 AS2( movdqa xmm0, [ecx+1*16])
00719 AS2( movdqa [edi+1*16], xmm0)
00720 AS2( movdqa xmm0, [ecx+2*16])
00721 AS2( movdq2q mm5, xmm0)
00722 AS2( movdqa [edi+2*16], xmm0)
00723 AS2( movdqa xmm0, [ecx+3*16])
00724 AS2( movdqa [edi+3*16], xmm0)
00725 ASJ( jmp, 0, f)
00726
00727 #define SSE2_S0_S1(r, a, b, c) \
00728 AS2( movq mm6, r)\
00729 AS2( psrlq r, a)\
00730 AS2( movq mm7, r)\
00731 AS2( psllq mm6, 64-c)\
00732 AS2( pxor mm7, mm6)\
00733 AS2( psrlq r, b-a)\
00734 AS2( pxor mm7, r)\
00735 AS2( psllq mm6, c-b)\
00736 AS2( pxor mm7, mm6)\
00737 AS2( psrlq r, c-b)\
00738 AS2( pxor r, mm7)\
00739 AS2( psllq mm6, b-a)\
00740 AS2( pxor r, mm6)
00741
00742 #define SSE2_s0(r, a, b, c) \
00743 AS2( movdqa xmm6, r)\
00744 AS2( psrlq r, a)\
00745 AS2( movdqa xmm7, r)\
00746 AS2( psllq xmm6, 64-c)\
00747 AS2( pxor xmm7, xmm6)\
00748 AS2( psrlq r, b-a)\
00749 AS2( pxor xmm7, r)\
00750 AS2( psrlq r, c-b)\
00751 AS2( pxor r, xmm7)\
00752 AS2( psllq xmm6, c-a)\
00753 AS2( pxor r, xmm6)
00754
00755 #define SSE2_s1(r, a, b, c) \
00756 AS2( movdqa xmm6, r)\
00757 AS2( psrlq r, a)\
00758 AS2( movdqa xmm7, r)\
00759 AS2( psllq xmm6, 64-c)\
00760 AS2( pxor xmm7, xmm6)\
00761 AS2( psrlq r, b-a)\
00762 AS2( pxor xmm7, r)\
00763 AS2( psllq xmm6, c-b)\
00764 AS2( pxor xmm7, xmm6)\
00765 AS2( psrlq r, c-b)\
00766 AS2( pxor r, xmm7)
00767
00768 ASL(SHA512_Round)
00769
00770 AS2( paddq mm0, [edi+7*8])
00771 AS2( movq mm2, [edi+5*8])
00772 AS2( movq mm3, [edi+6*8])
00773 AS2( pxor mm2, mm3)
00774 AS2( pand mm2, mm5)
00775 SSE2_S0_S1(mm5,14,18,41)
00776 AS2( pxor mm2, mm3)
00777 AS2( paddq mm0, mm2)
00778 AS2( paddq mm5, mm0)
00779 AS2( movq mm2, [edi+1*8])
00780 AS2( movq mm1, mm2)
00781 AS2( por mm2, mm4)
00782 AS2( pand mm2, [edi+2*8])
00783 AS2( pand mm1, mm4)
00784 AS2( por mm1, mm2)
00785 AS2( paddq mm1, mm5)
00786 AS2( paddq mm5, [edi+3*8])
00787 AS2( movq [edi+3*8], mm5)
00788 AS2( movq [edi+11*8], mm5)
00789 SSE2_S0_S1(mm4,28,34,39)
00790 AS2( paddq mm4, mm1)
00791 AS2( movq [edi-8], mm4)
00792 AS2( movq [edi+7*8], mm4)
00793 AS1( ret)
00794
00795
00796 ASL(0)
00797 AS2( movq mm0, [edx+eax*8])
00798 AS2( movq [esi+eax*8], mm0)
00799 AS2( movq [esi+eax*8+16*8], mm0)
00800 AS2( paddq mm0, [ebx+eax*8])
00801 ASC( call, SHA512_Round)
00802 AS1( inc eax)
00803 AS2( sub edi, 8)
00804 AS2( test eax, 7)
00805 ASJ( jnz, 0, b)
00806 AS2( add edi, 8*8)
00807 AS2( cmp eax, 16)
00808 ASJ( jne, 0, b)
00809
00810
00811 AS2( movdqu xmm0, [esi+(16-2)*8])
00812 ASL(1)
00813
00814 AS2( movdqu xmm3, [esi])
00815 AS2( paddq xmm3, [esi+(16-7)*8])
00816 AS2( movdqa xmm2, [esi+(16-15)*8])
00817 SSE2_s1(xmm0, 6, 19, 61)
00818 AS2( paddq xmm0, xmm3)
00819 SSE2_s0(xmm2, 1, 7, 8)
00820 AS2( paddq xmm0, xmm2)
00821 AS2( movdq2q mm0, xmm0)
00822 AS2( movhlps xmm1, xmm0)
00823 AS2( paddq mm0, [ebx+eax*8])
00824 AS2( movlps [esi], xmm0)
00825 AS2( movlps [esi+8], xmm1)
00826 AS2( movlps [esi+8*16], xmm0)
00827 AS2( movlps [esi+8*17], xmm1)
00828
00829 ASC( call, SHA512_Round)
00830 AS2( sub edi, 8)
00831 AS2( movdq2q mm0, xmm1)
00832 AS2( paddq mm0, [ebx+eax*8+8])
00833 ASC( call, SHA512_Round)
00834
00835 AS2( add esi, 16)
00836 AS2( add eax, 2)
00837 AS2( sub edi, 8)
00838 AS2( test eax, 7)
00839 ASJ( jnz, 1, b)
00840
00841 AS2( mov esi, 0xf)
00842 AS2( and esi, eax)
00843 #if CRYPTOPP_BOOL_X32
00844 AS2( lea esi, [esp+8+20*8+8+esi*8])
00845 #else
00846 AS2( lea esi, [esp+4+20*8+8+esi*8])
00847 #endif
00848 AS2( add edi, 8*8)
00849 AS2( cmp eax, 80)
00850 ASJ( jne, 1, b)
00851
00852 #define SSE2_CombineState(i) \
00853 AS2( movdqa xmm0, [edi+i*16])\
00854 AS2( paddq xmm0, [ecx+i*16])\
00855 AS2( movdqa [ecx+i*16], xmm0)
00856
00857 SSE2_CombineState(0)
00858 SSE2_CombineState(1)
00859 SSE2_CombineState(2)
00860 SSE2_CombineState(3)
00861
00862 AS_POP_IF86( sp)
00863 AS1( emms)
00864
00865 #if defined(__GNUC__)
00866 AS_POP_IF86( bx)
00867 ATT_PREFIX
00868 :
00869 : "a" (SHA512_K), "c" (state), "d" (data)
00870 : "%esi", "%edi", "memory", "cc"
00871 );
00872 #else
00873 AS1( pop edi)
00874 AS1( pop esi)
00875 AS1( pop ebx)
00876 AS1( ret)
00877 #endif
00878 }
00879 #endif // #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
00880
00881 void SHA512::Transform(word64 *state, const word64 *data)
00882 {
00883 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32)
00884 if (HasSSE2())
00885 {
00886 SHA512_SSE2_Transform(state, data);
00887 return;
00888 }
00889 #endif
00890
00891 #define S0(x) (rotrFixed(x,28)^rotrFixed(x,34)^rotrFixed(x,39))
00892 #define S1(x) (rotrFixed(x,14)^rotrFixed(x,18)^rotrFixed(x,41))
00893 #define s0(x) (rotrFixed(x,1)^rotrFixed(x,8)^(x>>7))
00894 #define s1(x) (rotrFixed(x,19)^rotrFixed(x,61)^(x>>6))
00895
00896 #define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA512_K[i+j]+(j?blk2(i):blk0(i));\
00897 d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
00898
00899 word64 W[16];
00900 word64 T[8];
00901
00902 memcpy(T, state, sizeof(T));
00903
00904 for (unsigned int j=0; j<80; j+=16)
00905 {
00906 R( 0); R( 1); R( 2); R( 3);
00907 R( 4); R( 5); R( 6); R( 7);
00908 R( 8); R( 9); R(10); R(11);
00909 R(12); R(13); R(14); R(15);
00910 }
00911
00912 state[0] += a(0);
00913 state[1] += b(0);
00914 state[2] += c(0);
00915 state[3] += d(0);
00916 state[4] += e(0);
00917 state[5] += f(0);
00918 state[6] += g(0);
00919 state[7] += h(0);
00920 }
00921
00922 NAMESPACE_END
00923
00924 #endif // #ifndef CRYPTOPP_GENERATE_X64_MASM
00925 #endif // #ifndef CRYPTOPP_IMPORTS