#include #include "box64stack.h" #include "x64emu.h" #include "x64run_private.h" #include "x64emu_private.h" #include "x64shaext.h" static uint32_t rol(uint32_t a, int n) { n = n&31; if(!n) return a; return (a<>(32-n)); } static uint32_t ror(uint32_t a, int n) { n = n&31; if(!n) return a; return (a>>n) | (a<<(32-n)); } static uint32_t f0(uint32_t B, uint32_t C, uint32_t D) { return (B & C) ^ ((~B) & D); } static uint32_t f1(uint32_t B, uint32_t C, uint32_t D) { return B ^ C ^ D; } static uint32_t f2(uint32_t B, uint32_t C, uint32_t D) { return (B & C) ^ (B & D) ^ (C & D); } static uint32_t f3(uint32_t B, uint32_t C, uint32_t D) { return B ^ C ^ D; } static uint32_t Ch(uint32_t E, uint32_t F, uint32_t G) { return (E & F) ^ ((~E) & G); } static uint32_t Maj(uint32_t A, uint32_t B, uint32_t C) { return (A & B) ^ (A & C) ^ (B & C); } static uint32_t sigma0(uint32_t A) { return ror(A, 2) ^ ror(A, 13) ^ ror(A, 22); } static uint32_t sigma1(uint32_t E) { return ror(E, 6) ^ ror(E, 11) ^ ror(E, 25); } static uint32_t tho0(uint32_t W) { return ror(W, 7) ^ ror(W, 18) ^ (W>>3); } static uint32_t tho1(uint32_t W) { return ror(W, 17) ^ ror(W, 19) ^ (W>>10); } static const uint32_t Ks[] = { 0x5A827999, 0x6ED9EBA1, 0X8F1BBCDC, 0xCA62C1D6 }; void sha1nexte(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2) { uint32_t tmp = rol(xmm1->ud[3], 30); xmm1->ud[3] = xmm2->ud[3] + tmp; xmm1->ud[2] = xmm2->ud[2]; xmm1->ud[1] = xmm2->ud[1]; xmm1->ud[0] = xmm2->ud[0]; } void sha1msg1(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2) { uint32_t w0 = xmm1->ud[3]; uint32_t w1 = xmm1->ud[2]; uint32_t w2 = xmm1->ud[1]; uint32_t w3 = xmm1->ud[0]; uint32_t w4 = xmm2->ud[3]; uint32_t w5 = xmm2->ud[2]; xmm1->ud[3] = w2 ^ w0; xmm1->ud[2] = w3 ^ w1; xmm1->ud[1] = w4 ^ w2; xmm1->ud[0] = w5 ^ w3; } void sha1msg2(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2) { uint32_t w13 = xmm2->ud[2]; uint32_t w14 = xmm2->ud[1]; uint32_t w15 = xmm2->ud[0]; uint32_t w16 = rol(xmm1->ud[3] ^ w13, 1); uint32_t w17 = rol(xmm1->ud[2] ^ w14, 1); uint32_t w18 = rol(xmm1->ud[1] ^ w15, 1); uint32_t w19 = rol(xmm1->ud[0] ^ w16, 1); xmm1->ud[3] = w16; xmm1->ud[2] = w17; xmm1->ud[1] = w18; xmm1->ud[0] = w19; } void sha256msg1(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2) { uint32_t w4 = xmm2->ud[0]; uint32_t w3 = xmm1->ud[3]; uint32_t w2 = xmm1->ud[2]; uint32_t w1 = xmm1->ud[1]; uint32_t w0 = xmm1->ud[0]; xmm1->ud[3] = w3 + tho0(w4); xmm1->ud[2] = w2 + tho0(w3); xmm1->ud[1] = w1 + tho0(w2); xmm1->ud[0] = w0 + tho0(w1); } void sha256msg2(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2) { uint32_t w14 = xmm2->ud[2]; uint32_t w15 = xmm2->ud[3]; uint32_t w16 = xmm1->ud[0] + tho1(w14); uint32_t w17 = xmm1->ud[1] + tho1(w15); uint32_t w18 = xmm1->ud[2] + tho1(w16); uint32_t w19 = xmm1->ud[3] + tho1(w17); xmm1->ud[3] = w19; xmm1->ud[2] = w18; xmm1->ud[1] = w17; xmm1->ud[0] = w16; } void sha1rnds4(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2, uint8_t ib) { uint32_t K = Ks[ib&3]; uint32_t(*f)(uint32_t , uint32_t , uint32_t) = NULL; switch (ib&3) { case 0: f = f0; break; case 1: f = f1; break; case 2: f = f2; break; case 3: f = f3; break; } uint32_t A = xmm1->ud[3]; uint32_t B = xmm1->ud[2]; uint32_t C = xmm1->ud[1]; uint32_t D = xmm1->ud[0]; uint32_t E = 0; for(int i=0; i<4; ++i) { uint32_t new_A = f(B, C, D) + rol(A, 5) + xmm2->ud[3-i] + E + K; E = D; D = C; C = rol(B, 30); B = A; A = new_A; } xmm1->ud[3] = A; xmm1->ud[2] = B; xmm1->ud[1] = C; xmm1->ud[0] = D; } void sha256rnds2(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2) { uint32_t A = xmm2->ud[3]; uint32_t B = xmm2->ud[2]; uint32_t C = xmm1->ud[3]; uint32_t D = xmm1->ud[2]; uint32_t E = xmm2->ud[1]; uint32_t F = xmm2->ud[0]; uint32_t G = xmm1->ud[1]; uint32_t H = xmm1->ud[0]; for(int i=0; i<2; ++i) { uint32_t new_A = Ch(E, F, G) + sigma1(E) + emu->xmm[0].ud[i] + H + Maj(A, B, C) + sigma0(A); uint32_t new_E = Ch(E, F, G) + sigma1(E) + emu->xmm[0].ud[i] + H + D; H = G; G = F; F = E; E = new_E; D = C; C = B; B = A; A = new_A; } xmm1->ud[3] = A; xmm1->ud[2] = B; xmm1->ud[1] = E; xmm1->ud[0] = F; }