📄 md5.cpp
字号:
/* md5.cpp * * Copyright (C) 2003 Sawtooth Consulting Ltd. * * This file is part of yaSSL. * * yaSSL 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; either version 2 of the License, or * (at your option) any later version. * * There are special exceptions to the terms and conditions of the GPL as it * is applied to yaSSL. View the full text of the exception in the file * FLOSS-EXCEPTIONS in the directory of this software distribution. * * yaSSL 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; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *//* based on Wei Dai's md5.cpp from CryptoPP */#include "runtime.hpp"#include "md5.hpp"#ifdef USE_SYS_STL #include <algorithm>#else #include "algorithm.hpp"#endifnamespace STL = STL_NAMESPACE; namespace TaoCrypt {void MD5::Init(){ digest_[0] = 0x67452301L; digest_[1] = 0xefcdab89L; digest_[2] = 0x98badcfeL; digest_[3] = 0x10325476L; buffLen_ = 0; loLen_ = 0; hiLen_ = 0;}MD5::MD5(const MD5& that) : HASHwithTransform(DIGEST_SIZE / sizeof(word32), BLOCK_SIZE) { buffLen_ = that.buffLen_; loLen_ = that.loLen_; hiLen_ = that.hiLen_; memcpy(digest_, that.digest_, DIGEST_SIZE); memcpy(buffer_, that.buffer_, BLOCK_SIZE);}MD5& MD5::operator= (const MD5& that){ MD5 tmp(that); Swap(tmp); return *this;}void MD5::Swap(MD5& other){ STL::swap(loLen_, other.loLen_); STL::swap(hiLen_, other.hiLen_); STL::swap(buffLen_, other.buffLen_); memcpy(digest_, other.digest_, DIGEST_SIZE); memcpy(buffer_, other.buffer_, BLOCK_SIZE);}#ifdef DO_MD5_ASM// Update digest with data of size lenvoid MD5::Update(const byte* data, word32 len){ if (!isMMX) { HASHwithTransform::Update(data, len); return; } byte* local = reinterpret_cast<byte*>(buffer_); // remove buffered data if possible if (buffLen_) { word32 add = min(len, BLOCK_SIZE - buffLen_); memcpy(&local[buffLen_], data, add); buffLen_ += add; data += add; len -= add; if (buffLen_ == BLOCK_SIZE) { Transform(); AddLength(BLOCK_SIZE); buffLen_ = 0; } } // at once for asm if (buffLen_ == 0) { word32 times = len / BLOCK_SIZE; if (times) { AsmTransform(data, times); const word32 add = BLOCK_SIZE * times; AddLength(add); len -= add; data += add; } } // cache any data left if (len) { memcpy(&local[buffLen_], data, len); buffLen_ += len; }}/* // w = rotlFixed(w + f(x, y, z) + index[edi] + data, s) + x#define ASMMD5STEP(f, w, x, y, z, index, data, s) \ f(x, y, z) \ AS2( mov ebp, [edi + index * 4] ) \ AS2( lea w, [esi + w + data] ) \ AS2( add w, ebp ) \ AS2( rol w, s ) \ AS2( add w, x ) // F1(x, y, z) (z ^ (x & (y ^ z))) // place in esi#define ASMF1(x, y, z) \ AS2( mov esi, y ) \ AS2( xor esi, z ) \ AS2( and esi, x ) \ AS2( xor esi, z )#define ASMF2(x, y, z) ASMF1(z, x, y) // F3(x ^ y ^ z) // place in esi#define ASMF3(x, y, z) \ AS2( mov esi, x ) \ AS2( xor esi, y ) \ AS2( xor esi, z ) // F4(x, y, z) (y ^ (x | ~z)) // place in esi#define ASMF4(x, y, z) \ AS2( mov esi, z ) \ AS1( not esi ) \ AS2( or esi, x ) \ AS2( xor esi, y )*/ // combine above ASMMD5STEP(f w/ each f ASMF1 - F4 // esi already set up, after using set for next round // ebp already set up, set up using next round index #define MD5STEP1(w, x, y, z, index, data, s) \ AS2( xor esi, z ) \ AS2( and esi, x ) \ AS2( lea w, [ebp + w + data] ) \ AS2( xor esi, z ) \ AS2( add w, esi ) \ AS2( mov esi, x ) \ AS2( rol w, s ) \ AS2( mov ebp, [edi + index * 4] ) \ AS2( add w, x )#define MD5STEP2(w, x, y, z, index, data, s) \ AS2( xor esi, x ) \ AS2( and esi, z ) \ AS2( lea w, [ebp + w + data] ) \ AS2( xor esi, y ) \ AS2( add w, esi ) \ AS2( mov esi, x ) \ AS2( rol w, s ) \ AS2( mov ebp, [edi + index * 4] ) \ AS2( add w, x )#define MD5STEP3(w, x, y, z, index, data, s) \ AS2( xor esi, z ) \ AS2( lea w, [ebp + w + data] ) \ AS2( xor esi, x ) \ AS2( add w, esi ) \ AS2( mov esi, x ) \ AS2( rol w, s ) \ AS2( mov ebp, [edi + index * 4] ) \ AS2( add w, x )#define MD5STEP4(w, x, y, z, index, data, s) \ AS2( or esi, x ) \ AS2( lea w, [ebp + w + data] ) \ AS2( xor esi, y ) \ AS2( add w, esi ) \ AS2( mov esi, y ) \ AS2( rol w, s ) \ AS1( not esi ) \ AS2( mov ebp, [edi + index * 4] ) \ AS2( add w, x )#ifdef _MSC_VER __declspec(naked) #endifvoid MD5::AsmTransform(const byte* data, word32 times){#ifdef __GNUC__ #define AS1(x) asm(#x); #define AS2(x, y) asm(#x ", " #y); #define PROLOG() \ asm(".intel_syntax noprefix"); \ AS2( movd mm3, edi ) \ AS2( movd mm4, ebx ) \ AS2( movd mm5, esi ) \ AS2( movd mm6, ebp ) \ AS2( mov ecx, DWORD PTR [ebp + 8] ) \ AS2( mov edi, DWORD PTR [ebp + 12] ) \ AS2( mov eax, DWORD PTR [ebp + 16] ) #define EPILOG() \ AS2( movd ebp, mm6 ) \ AS2( movd esi, mm5 ) \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -