From 354bb40e75d94466e91fe6960523612c9d17ccfb Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 2 Nov 2017 23:11:29 +0300 Subject: Add implementation --- mysql/extra/yassl/taocrypt/src/arc4.cpp | 243 ++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 mysql/extra/yassl/taocrypt/src/arc4.cpp (limited to 'mysql/extra/yassl/taocrypt/src/arc4.cpp') diff --git a/mysql/extra/yassl/taocrypt/src/arc4.cpp b/mysql/extra/yassl/taocrypt/src/arc4.cpp new file mode 100644 index 0000000..10a3a7d --- /dev/null +++ b/mysql/extra/yassl/taocrypt/src/arc4.cpp @@ -0,0 +1,243 @@ +/* + Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. +*/ + +/* based on Wei Dai's arc4.cpp from CryptoPP */ + +#include "runtime.hpp" +#include "arc4.hpp" + + +#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) + #define DO_ARC4_ASM +#endif + + +namespace TaoCrypt { + +void ARC4::SetKey(const byte* key, word32 length) +{ + x_ = 1; + y_ = 0; + + word32 i; + + for (i = 0; i < STATE_SIZE; i++) + state_[i] = i; + + word32 keyIndex = 0, stateIndex = 0; + + for (i = 0; i < STATE_SIZE; i++) { + word32 a = state_[i]; + stateIndex += key[keyIndex] + a; + stateIndex &= 0xFF; + state_[i] = state_[stateIndex]; + state_[stateIndex] = a; + + if (++keyIndex >= length) + keyIndex = 0; + } +} + + +// local +namespace { + +inline unsigned int MakeByte(word32& x, word32& y, byte* s) +{ + word32 a = s[x]; + y = (y+a) & 0xff; + + word32 b = s[y]; + s[x] = b; + s[y] = a; + x = (x+1) & 0xff; + + return s[(a+b) & 0xff]; +} + +} // namespace + + + +void ARC4::Process(byte* out, const byte* in, word32 length) +{ + if (length == 0) return; + +#ifdef DO_ARC4_ASM + if (isMMX) { + AsmProcess(out, in, length); + return; + } +#endif + + byte *const s = state_; + word32 x = x_; + word32 y = y_; + + if (in == out) + while (length--) + *out++ ^= MakeByte(x, y, s); + else + while(length--) + *out++ = *in++ ^ MakeByte(x, y, s); + x_ = x; + y_ = y; +} + + + +#ifdef DO_ARC4_ASM + +#ifdef _MSC_VER + __declspec(naked) +#else + __attribute__ ((noinline)) +#endif +void ARC4::AsmProcess(byte* out, const byte* in, word32 length) +{ +#ifdef __GNUC__ + #define AS1(x) #x ";" + #define AS2(x, y) #x ", " #y ";" + + #define PROLOG() \ + __asm__ __volatile__ \ + ( \ + ".intel_syntax noprefix;" \ + "push ebx;" \ + "push ebp;" \ + "mov ebp, eax;" + #define EPILOG() \ + "pop ebp;" \ + "pop ebx;" \ + "emms;" \ + ".att_syntax;" \ + : \ + : "c" (this), "D" (out), "S" (in), "a" (length) \ + : "%edx", "memory", "cc" \ + ); + +#else + #define AS1(x) __asm x + #define AS2(x, y) __asm x, y + + #define PROLOG() \ + AS1( push ebp ) \ + AS2( mov ebp, esp ) \ + AS2( movd mm3, edi ) \ + AS2( movd mm4, ebx ) \ + AS2( movd mm5, esi ) \ + AS2( movd mm6, ebp ) \ + AS2( mov edi, DWORD PTR [ebp + 8] ) \ + AS2( mov esi, DWORD PTR [ebp + 12] ) \ + AS2( mov ebp, DWORD PTR [ebp + 16] ) + + #define EPILOG() \ + AS2( movd ebp, mm6 ) \ + AS2( movd esi, mm5 ) \ + AS2( movd ebx, mm4 ) \ + AS2( movd edi, mm3 ) \ + AS2( mov esp, ebp ) \ + AS1( pop ebp ) \ + AS1( emms ) \ + AS1( ret 12 ) + +#endif + + PROLOG() + + AS2( sub esp, 4 ) // make room + + AS2( cmp ebp, 0 ) + AS1( jz nothing ) + + AS2( mov [esp], ebp ) // length + + AS2( movzx edx, BYTE PTR [ecx + 1] ) // y + AS2( lea ebp, [ecx + 2] ) // state_ + AS2( movzx ecx, BYTE PTR [ecx] ) // x + + // setup loop + // a = s[x]; + AS2( movzx eax, BYTE PTR [ebp + ecx] ) + + +#ifdef _MSC_VER + AS1( loopStart: ) // loopStart +#else + AS1( 0: ) // loopStart for some gas (need numeric for jump back +#endif + + // y = (y+a) & 0xff; + AS2( add edx, eax ) + AS2( and edx, 255 ) + + // b = s[y]; + AS2( movzx ebx, BYTE PTR [ebp + edx] ) + + // s[x] = b; + AS2( mov [ebp + ecx], bl ) + + // s[y] = a; + AS2( mov [ebp + edx], al ) + + // x = (x+1) & 0xff; + AS1( inc ecx ) + AS2( and ecx, 255 ) + + //return s[(a+b) & 0xff]; + AS2( add eax, ebx ) + AS2( and eax, 255 ) + + AS2( movzx ebx, BYTE PTR [ebp + eax] ) + + // a = s[x]; for next round + AS2( movzx eax, BYTE PTR [ebp + ecx] ) + + // xOr w/ inByte + AS2( xor bl, BYTE PTR [esi] ) + AS1( inc esi ) + + // write to outByte + AS2( mov [edi], bl ) + AS1( inc edi ) + + AS1( dec DWORD PTR [esp] ) +#ifdef _MSC_VER + AS1( jnz loopStart ) // loopStart +#else + AS1( jnz 0b ) // loopStart +#endif + + + // write back to x_ and y_ + AS2( mov [ebp - 2], cl ) + AS2( mov [ebp - 1], dl ) + + +AS1( nothing: ) + + // inline adjust + AS2( add esp, 4 ) // fix room on stack + + EPILOG() +} + +#endif // DO_ARC4_ASM + + +} // namespace -- cgit v1.1